Сначала вы помещаете (уже экранированную) строку в класс URL
. Это ничего не избежит. Затем вы вытаскиваете секции URL
, которые возвращают их без какой-либо дальнейшей обработки (то есть - они по-прежнему экранированы, поскольку они были экранированы, когда вы их вставляли). Наконец, вы помещаете разделы в класс URI
, используя конструктор с несколькими аргументами . Этот конструктор указан как кодирующий компоненты URI с использованием процентов.
Следовательно, именно на этом последнем этапе, например, ":
" становится "%3A
" (хорошо), а "%3A
" становится "%253A
" (плохо). Поскольку вы вводите URL-адреса, которые уже закодированы *, вы не хотите их кодировать снова.
Следовательно, конструктор с одним аргументом из URI
является вашим другом. Он ничего не избегает и требует, чтобы вы пропустили предварительно экранированную строку. Следовательно, вам не нужно URL
вообще:
mUrl = "A string url is already percent-encoded for use in a new HttpGet()";
URI uri = new URI(mUrl);
* Единственная проблема в том, что ваши URL-адреса иногда не кодируются в процентах, а иногда и так. Тогда у вас есть большая проблема. Вам нужно решить, начинается ли ваша программа с URL-адреса, который всегда закодирован, или с тем, который необходимо кодировать.
Обратите внимание, что нет такой вещи как полный URL, который не кодируется в процентах. Например, вы не можете взять полный URL-адрес «http://example.com/bob&co
» и каким-то образом превратить его в правильно закодированный URL-адрес «http://example.com/bob%26co
» - как вы можете определить разницу между синтаксисом (который не должен быть экранирован) а персонажи (которые должны)? Вот почему форма единственного аргумента URI
требует, чтобы строки уже экранировались. Если у вас есть неэкранированные строки, вам нужно кодировать их в процентах до , вставляя их в полный синтаксис URL, и это то, что помогает вам сделать конструктор с несколькими аргументами URI
.
Редактировать: Я пропустил тот факт, что оригинальный код отбрасывает фрагмент. Если вы хотите удалить фрагмент (или любую другую часть) URL-адреса, вы можете создать URI
, как указано выше, а затем вытянуть все части по мере необходимости (они будут декодированы в обычные строки). , а затем передайте их обратно в URI
конструктор с несколькими аргументами (где они будут перекодированы в качестве компонентов URI):
uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
uri.getPath(), uri.getQuery(), null) // Remove fragment