Кодировка URL-адреса URI изменяет "%3D " на " %253D"
у меня возникли проблемы с кодированием URL-адреса URI:
mUrl = "A string url that needs to be encoded for use in a new HttpGet()";
URL url = new URL(mUrl);
URI uri = new URI(url.getProtocol(), url.getAuthority(), url.getPath(),
url.getQuery(), null);
Это не делает то, что я ожидаю для следующего URL:
проходящий в Строка:
http://m.bloomingdales.com/img?url=http%3A%2F%2Fimages.bloomingdales.com%2Fis%2Fimage%2FBLM%2Fproducts%2F3%2Foptimized%2F1140443_fpx.tif%3Fwid%3D52%26qlt%3D90%2C0%26layer%3Dcomp%26op_sharpen%3D0%26resMode%3Dsharp2%26op_usm%3D0.7%2C1.0%2C0.5%2C0%26fmt%3Djpeg&ttl=30d
выходит as:
http://m.bloomingdales.com/img?url=http%253A%252F%252Fimages.bloomingdales.com%252Fis%252Fimage%252FBLM%252Fproducts%252F3%252Foptimized%252F1140443_fpx.tif%253Fwid%253D52%2526qlt%253D90%252C0%2526layer%253Dcomp%2526op_sharpen%253D0%2526resMode%253Dsharp2%2526op_usm%253D0.7%252C1.0%252C0.5%252C0%2526fmt%253Djpeg&ttl=30d
который нарушен. Например,%3D
превращается в %253D
Кажется, что это делает что-то загадочное для %уже в строке.
что происходит и что я делаю неправильно здесь?
4 ответов
вы сначала ставите (уже сбежал) строку URL
класса. От этого ничего не ускользает. Тогда вы вытаскиваете разделы URL
, который возвращает их без какой-либо дальнейшей обработки (так что -- они все еще экранированы, так как они были экранированы, когда вы их вставили). Наконец, вы помещаете разделы в URI
класс, с помощью конструктор с несколькими аргументами. Этот конструктор задается как кодирование компонентов URI с помощью проценты.
поэтому именно на этом последнем этапе, например,":
" в "%3A
" (хорошо) и "%3A
" в "%253A
" (плохо). Поскольку вы вводите URL-адреса, которые уже закодированы*, вы не хотите кодировать их снова.
таким образом,конструктор с одним аргументом of URI
- твой друг. Он ничего не избегает и требует, чтобы вы передали предварительно экранированную строку. Следовательно, вам не нужно URL
at все:
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
поможет вам сделать.
Edit: я пропустил тот факт, что исходный код отбрасывает фрагмент. Если вы хотите удалить фрагмент (или любую другую часть) URL-адреса, вы можете создать URI
как указано выше, затем вытащите все детали по мере необходимости (они будут декодируются в регулярные строки), затем передайте их обратно в URI
конструктор с несколькими аргументами (где они будут перекодируется как компоненты URI):
uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
uri.getPath(), uri.getQuery(), null) // Remove fragment
на URL
класс не декодировал % - последовательности при анализе URL-адреса, но URI
класс кодирует их (снова). Использовать URI
для анализа строки URL.
Javadocs:
http://download.oracle.com/javase/6/docs/api/java/net/URL.html
класс URL сам не кодирует и не декодирует компоненты URL согласно экранируя механизму определенному в RFC2396. Это ответственность вызывающего кодировать любые поля, которые должны быть экранированы до вызова URL, а также декодировать любые экранированные поля, которые возвращаются из URL. Кроме того, поскольку URL-адрес не знает об экранировании URL-адреса, он не распознает эквивалентность между закодированной или декодированной формой того же URL-адреса. Например, два URL:
http://foo.com/hello world/ and http://foo.com/hello%20world
будут считаться не равными друг другу. Обратите внимание, что класс URI выполняет экранирование его поля компонентов при определенных обстоятельствах.
рекомендуемый способ управления кодированием и декодированием URL-адресов-использовать URI, и конвертировать между этими двумя классами с помощью toURI () и URI.toURL().
%в 3D значит--> = (равно)
и
%253D -->= (равно) decimal 6hex (байт) 3D
%253D Хекс индикатор для CGI: %в 3D
то, что здесь происходит, это то, что %
знаки из первого URL-адреса экранируются, что означает, что они превращаются в %25
в выходной. Вам нужно принять меры предосторожности, чтобы ваш скрипт избегал только буквенно-цифровых символов, а также некоторых символов - но не уже убежал персонажей.
это некоторые символы, которые нужно избежать:
<
>
"
!
#
$
'
(
)
*
,
-
.
/
:
;
@
[
\
]
^
_
`
{
|
}
~
остальное, как =
, %
и &
, и буквенно-цифровые символы, do не.