Проблема HttpClient с URL-адресами, которые включают фигурные скобки

Я использую 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, который является строкой в основном. Трассировка стека показывает мне индекс фигурных скобок, говорящих недопустимый символ. Поэтому я попытался создать URI из закодированного URL.

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

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

  • " {"С" %7B"
  • "} " С "%7D"

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

2 ответов


строгий ответ заключается в том, что вы никогда не должны иметь фигурные скобки в своем URL

полное описание допустимых URL-адресов можно найти в RFC1738

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

небезопасными:

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

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

чтобы обойти проблему, которую вы испытываете, вы должны кодировать свой url.

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

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

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

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

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

однако, как ни странно, IRIs определяется в:

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

имейте примечание, что:

системы принятия ирис может также заниматься печатных символов в US-ASCII, которые не разрешены в URIs, а именно "", '"', космос, "{", "}", "|", "\", "^", и "`", в шаге 2 выше. Если эти символы найдены, но не преобразованы, затем преобразование
Должен провалиться. Обратите внимание, что знак числа ( " # " ), процент
знак ( " % " ) и квадратные скобки ("[ " ,"]") не являются частью из вышеприведенного списка и не должны быть преобразованы.

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