Android: как разобрать строку URL с пробелами в объекте URI? - PullRequest
61 голосов
/ 07 апреля 2010

У меня есть строка, представляющая URL с пробелами, и я хочу преобразовать ее в объект URI. Если я просто попытаюсь создать его через

String myString = "http://myhost.com/media/File Name that has spaces inside.mp3";
URI myUri = new URI(myString);

это дает мне

java.net.URISyntaxException: Illegal character in path at index X

, где index X - это позиция первого пробела в строке URL.

Как мне разобрать myString в URI объект?

Ответы [ 5 ]

120 голосов
/ 07 апреля 2010

Вы должны URI-кодировать"недопустимые" символы. Поскольку строка на самом деле содержит полный URL-адрес, трудно правильно его кодировать по URI. Вы не знаете, какие косые черты / следует учитывать, а какие нет. Вы не можете предсказать это на необработанном String заранее. Проблема действительно должна быть решена на более высоком уровне. Откуда это String? Это жестко закодировано? Тогда просто измените это самостоятельно соответственно. Это входит как пользовательский ввод? Подтвердите его и покажите ошибку, пусть пользователь решит сам.

В любом случае, если вы можете убедиться, что это только пробелов в URL-адресах, что делает его недействительным, то вы также можете просто заменить строку на строку %20:

URI uri = new URI(string.replace(" ", "%20"));

Или, если вы можете гарантировать, что это только часть после последней косой черты, которая должна быть закодирована в URI, то вы также можете просто сделать это с помощью android.net.Uri служебный класс:

int pos = string.lastIndexOf('/') + 1;
URI uri = new URI(string.substring(0, pos) + Uri.encode(string.substring(pos)));

Обратите внимание, что URLEncoder не подходит для задачи, так как она предназначена для кодирования имен / значений параметров строки запроса согласно application/x-www-form-urlencoded правилам (как используется в формах HTML). См. Также Java-кодирование параметров строки запроса .

19 голосов
/ 07 апреля 2010
java.net.URLEncoder.encode(finalPartOfString, "utf-8");

Это будет URL-кодировать строку.

finalPartOfString - это часть после последней косой черты - в вашем случае название песни, как кажется.

2 голосов
/ 30 июня 2014
URL url = Test.class.getResource(args[0]);  // reading demo file path from                                                   
                                            // same location where class                                    
File input=null;
try {
    input = new File(url.toURI());
} catch (URISyntaxException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}
1 голос
/ 27 февраля 2014

Для обработки пробелов, @ и других небезопасных символов в произвольных местах в пути URL, используйте Uri.Builder в сочетании с локальным экземпляром URL, как я описал здесь :

private Uri.Builder builder;
public Uri getUriFromUrl(String thisUrl) {
    URL url = new URL(thisUrl);
    builder =  new Uri.Builder()
                            .scheme(url.getProtocol())
                            .authority(url.getAuthority())
                            .appendPath(url.getPath());
    return builder.build();
}
0 голосов
/ 18 июля 2016

Я написал эту функцию:

public static String encode(@NonNull String uriString) {
    if (TextUtils.isEmpty(uriString)) {
        Assert.fail("Uri string cannot be empty!");
        return uriString;
    }
    // getQueryParameterNames is not exist then cannot iterate on queries
    if (Build.VERSION.SDK_INT < 11) {
        return uriString;
    }

    // Check if uri has valid characters
    // See https://tools.ietf.org/html/rfc3986
    Pattern allowedUrlCharacters = Pattern.compile("([A-Za-z0-9_.~:/?\\#\\[\\]@!$&'()*+,;" +
            "=-]|%[0-9a-fA-F]{2})+");
    Matcher matcher = allowedUrlCharacters.matcher(uriString);
    String validUri = null;
    if (matcher.find()) {
        validUri = matcher.group();
    }
    if (TextUtils.isEmpty(validUri) || uriString.length() == validUri.length()) {
        return uriString;
    }

    // The uriString is not encoded. Then recreate the uri and encode it this time
    Uri uri = Uri.parse(uriString);
    Uri.Builder uriBuilder = new Uri.Builder()
            .scheme(uri.getScheme())
            .authority(uri.getAuthority());
    for (String path : uri.getPathSegments()) {
        uriBuilder.appendPath(path);
    }
    for (String key : uri.getQueryParameterNames()) {
        uriBuilder.appendQueryParameter(key, uri.getQueryParameter(key));
    }
    String correctUrl = uriBuilder.build().toString();
    return correctUrl;
}
...