HttpClient проблема с URL, которые содержат фигурные скобки - PullRequest
6 голосов
/ 19 июля 2011

Я использую HttpClient для своего приложения для Android.В какой-то момент я должен получить данные из удаленных мест.Ниже приведен фрагмент, как я использовал HttpClient для получения ответа.

String url_s = "https://mydomain.com/abc/{5D/{B0blhahblah-blah}I1.jpg"; //my url string
DefaultHttpClient httpClient = new DefaultHttpClient();
response = httpClient.execute(new HttpGet(url_s));

Это работает абсолютно нормально в большинстве случаев, но не тогда, когда в моем URL есть несколько фигурных скобок, которые в основном являются String.Трассировка стека показывает мне индекс фигурных скобок с неверным символом.Поэтому я попытался создать URI из закодированного URL.

URL url = new URL(url_s);
URI uri = url.toURI();
response = httpClient.execute(new HttpGet(uri));

После этого я вообще не получил результат из удаленного местоположения.Я обошел проблему и исправил ее, заменив фигурную скобку

  • "{" на "% 7B"
  • "}" на "% 7D"

Но я не полностью удовлетворен своим решением.Есть ли лучшие решения?Что-нибудь аккуратное и не жестко, как у меня?

Ответы [ 2 ]

10 голосов
/ 19 июля 2011

Строгий ответ: у вас никогда не должно быть фигурных скобок в вашем URL

Полное описание действительных URL можно найти в RFC1738

Соответствующая часть дляЭтот ответ выглядит следующим образом:

Небезопасно:

Символы могут быть небезопасны по ряду причин.Символ пробела
небезопасен, поскольку значительные пробелы могут исчезнуть, а незначительные пробелы
могут быть введены, когда URL-адреса транскрибируются или
набираются или подвергаются обработке программ обработки текста.
Символы "<"и ">" небезопасны, поскольку они используются в качестве разделителей
вокруг URL в свободном тексте;знак кавычки ("" ") используется для
разграничения URL-адресов в некоторых системах. Символ" # "небезопасен и всегда должен быть закодирован, поскольку он используется в World Wide Web и в других системах
для разграниченияURL из идентификатора фрагмента / якоря, который может следовать за ним. Символ "%" небезопасен, поскольку он используется для кодирования
других символов. Другие символы небезопасны, поскольку, как известно, иногда изменяются шлюзы
и другие транспортные агенты
таких символов. Это символы "{", "}", "|", "\", "^", "~",
"[", "]" и "` ".

Все небезопасные символы всегда должны быть закодированы в URL. Например,
, символ "#" должен быть закодирован в URL даже в
системах, которые обычно не имеют дело с фрагментом или якорем
идентификаторы, поэтому, если URL-адрес копируется в другую систему, которая
использует их, нет необходимости изменять кодировку URL-адреса.

Чтобы обойти проблему, с которой вы столкнулисьты должензакодируйте ваш URL.

Проблема, с которой вы столкнулись с ошибкой "host not not null", произойдет, когда весь URL кодируется, включая часть https://mydomain.com/, что может привести к путанице.Вы хотите кодировать только последнюю часть URL-адреса, называемую путем.

Решение состоит в том, чтобы использовать класс Uri.Builder для создания URI из отдельных частей, которые должны кодировать путь в процессе

Подробное описание вы найдете в справочной документации Android SDK Uri.Builder

Вот несколько простых примеров использования ваших значений:

Uri.Builder b = Uri.parse("https://mydomain.com").buildUpon();
b.path("/abc/{5D/{B0blhahblah-blah}I1.jpg");
Uri u = b.build();

Или вы можетеиспользовать цепочку:

    Uri u = Uri.parse("https://mydomain.com").buildUpon().path("/abc/{5D/{B0blhahblah-blah}I1.jpg").build();
1 голос
/ 08 сентября 2017

За исключением того, что RFC1738 устарел более десяти лет, был заменен rfc3986, и нет никаких признаков в:

https://tools.ietf.org/html/rfc3986

, что фигурные скобки небезопасны (на самом деле,RFC нигде не содержит ни одной фигурной скобки).Кроме того, я пробовал URI в браузерах, которые содержат фигурные скобки, и они прекрасно работают.

Также обратите внимание, что OP использует класс с именем URI - который определенно должен следовать за 3986, по крайней мере, если нет3987.

Однако, как ни странно, IRI, определенные в:

https://tools.ietf.org/html/rfc3987

Имейте в виду, что:

Системы, принимающие IRI, МОГУТ такжеиметь дело с печатными символами в US-ASCII, которые не разрешены в URI, а именно: "<", ">", '"', пробел," {","} "," | "," \ "," ^ "и "` "на шаге 2 выше. Если эти символы найдены, но не преобразованы, преобразование
ДОЛЖНО завершиться неудачей. Обратите внимание, что знак числа (" # "), знак процента
("% ") и квадратные скобки (" [","] ") не являются частью вышеприведенного списка и НЕ ДОЛЖНЫ преобразовываться.

Другими словами, похоже, что сами RFCесть некоторые проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...