Подтвердить что ты не робот

Android: howto parse URL String с пробелами для объекта URI?

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

String myString = "http://myhost.com/media/mp3s/9/Agenda of swine - 13. Persecution Ascension_ leave nothing standing.mp3";
URI myUri = new URI(myString);

это дает мне

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

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

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

4b9b3361

Ответ 1

На самом деле вы должны кодировать URI "недопустимые" символы. Поскольку строка фактически содержит полный URL-адрес, трудно правильно кодировать URI. Вы не знаете, какие косые черты / должны быть приняты во внимание, а какие нет. Вы не можете заранее предсказать это на raw 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-формах). См. Также Кодировка URL-адресов URL-адресов строки запроса.

Ответ 2

java.net.URLEncoder.encode(finalPartOfString, "utf-8");

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

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

Ответ 3

Чтобы обрабатывать пробелы, @и другие небезопасные символы в произвольных местах в 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();
}

Ответ 4

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();
}

Ответ 5

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

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;
}