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 работает нормально.