Android: Как разобрать строку URL с пробелами для объекта 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


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



как я могу распарсить myStringна

818   5  

5 ответов:

вы должны на самом деле URI-encode "неправильные" символы. Поскольку строка фактически содержит полный 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 URL параметров строки запроса.

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

Это URL-encode строку.

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

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

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

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

Comments

    Ничего не найдено.