URL кодирования, содержащие символы Юникода

Существует ли класс Android, который (правильно) кодирует URL-адреса, содержащие символы Юникода? Например:

Blue Öyster Cult

Преобразуется в следующее с помощью java.net.URI:

uri.toString()
 (java.lang.String) Blue%20Öyster%20Cult

Символ Ö не закодирован. С помощью URLEncoder:

URLEncoder.encode("Blue Öyster Cult", "UTF-8").toString()
 (java.lang.String) Blue+%C3%96yster+Cult

Он слишком много кодирует (т. Е. Пробелы становятся "+", а разделители пути "/" становятся%2F). Если я щелкаю по ссылке, содержащей символы Юникода, в веб-браузере Dolphin, она работает правильно, поэтому, очевидно, это можно сделать. Но если я пытаюсь открыть HttpURLConnection с помощью любой из приведенных выше строк, я получаю HTTP 404 Not Found исключение.

2 ответа

Решение

В итоге я взломал решение, которое, кажется, работает для этого, но, вероятно, не самое надежное:

url = new URL(userSuppliedPath);
String context = url.getProtocol();
String hostname = url.getHost();
String thePath = url.getPath();
int port = url.getPort();
thePath = thePath.replaceAll("(^/|/$)", ""); // removes beginning/end slash
String encodedPath = URLEncoder.encode(thePath, "UTF-8"); // encodes unicode characters
encodedPath = encodedPath.replace("+", "%20"); // change + to %20 (space)
encodedPath = encodedPath.replace("%2F", "/"); // change %2F back to slash
urlString = context + "://" + hostname + ":" + port + "/" + encodedPath;

URLEncoder предназначен для кодирования содержимого формы, а не целых URI. Кодировка / как%2F предназначена для предотвращения интерпретации пользовательского ввода как каталога, и + является допустимым кодированием для данных формы. (форма данных == часть URI после?)

В идеале вы должны кодировать "Blue Öyster Cult" перед добавлением его в базовый URI вместо кодирования всей строки. И если "Blue Öyster Cult" является частью пути, а не частью строки запроса, вы должны заменить + на%20 самостоятельно. С этими ограничениями URLEncoder работает нормально.

Другие вопросы по тегам