%IIS_USER_HOME% - The IIS Express home directory for the user
%IIS_SITES_HOME% - The default home directory for sites
%IIS_BIN% - The location of the IIS Express binaries
%SYSTEMDRIVE% - The drive letter of %IIS_BIN%
Существует фундаментальная разница между '% 2F' и '/' как для браузера, так и для сервера.
В спецификации HttpServletRequest говорится (без какой-либо логики, AFAICT):
Результат getPathInfo9 () [114380] должен быть декодирован, но результат getRequestURI () не должен декодироваться. Если это так, ваш контейнер сервлета нарушает спецификацию (как правильно указали Воутер Коэкартс и Франсуа Гравель). Какую версию Tomcat вы используете?
Что еще больше сбивает с толку, текущие версии Tomcat отклоняют пути, содержащие кодировки определенных специальных символов,
If there's a %2F
in the decoded url, it means the encoded url contained %252F
.
Since %2F
is /
Why not just split on "\/"
and not worry about URL encoding?
Согласно Javadoc , getRequestURI не должен декодировать строку. С другой стороны, getServletPath возвращает декодированную строку. Я протестировал это локально с помощью Jetty, и он ведет себя, как описано в документе.
Так что в вашей ситуации может быть что-то еще, поскольку поведение, которое вы описываете, не соответствует документации Sun.
Похоже, вы пытаетесь что-то сделать RESTy (используйте Jersey). Можете ли вы просто проанализировать начальную и конечную части URL-адреса, чтобы получить данные, которые вы ищете?
url.substring (startLength, url.length - endLength);
Обновление: изначально в этом ответе было ошибочно указано, что '/' и '% 2F' в пути всегда должны обрабатываться одинаково. На самом деле они отличаются, потому что путь - это список сегментов, разделенных /.
Вам не нужно делать различие между закодированным и незакодированным символом в части пути URL. Внутри пути нет символа, который может иметь особое значение в URL-адресе. Например, "% 2F" следует интерпретировать так же, как "/", и браузер, обращающийся к такому URL-адресу, может свободно заменять один другим по своему усмотрению. Различие между ними нарушает стандарт кодирования URL-адресов.
В полном URL-адресе вы должны различать экранированные и неэкранированные символы по разным причинам, в том числе:
Java отлично справляется с первыми двумя случаями:
getPathInfo ()
, который возвращает только часть пути, декодированный getParameter (String)
для доступа к частям части запроса Это не касается так хорошо с третьим случаем. Если вы хотите сделать различие между '/' как разделением двух сегментов пути и '/' внутри сегмента пути (% 2F), вы не можете последовательно представить путь как одну декодированную строку. Вы можете представить его как одну закодированную строку (например, "foo / bar% 2Fbaz"), Но поскольку API getPathInfo () обещает сделать именно это (одна декодированная строка), у него нет другого выбора, кроме как рассматривать '/' и '% 2F' как одно и то же.
Для обычных веб-приложений это нормально. Если вы находитесь в редком случае, когда вам действительно нужно что-то изменить, вы можете провести собственный анализ URL-адреса, получив необработанную версию с помощью getRequestURI ()
. Если он дает URL, декодированный, как вы утверждаете, то это означает, что в используемой вами реализации сервлета есть ошибка.