Какая разница между методами getRequestURI и getPathInfo в HttpServletRequest?
Я делаю простой, очень легкий передний контроллер. Мне нужно сопоставить пути запросов к различным обработчикам (действиям), чтобы выбрать правильный.
На моей локальной машине HttpServletRequest.getPathInfo()
и HttpServletRequest.getRequestURI()
вернуть те же результаты. Но я не уверен, что они вернут в производственной среде.
Итак, какая разница между этими методами и что выбрать?
Ответы
Ответ 1
getPathInfo()
предоставляет дополнительную информацию о пути после URI, используемую для доступа к вашему сервлета, где getRequestURI()
предоставляет полный URI.
Я бы подумал, что они будут разными, поскольку Servlet должен быть настроен с собственным шаблоном URI в первую очередь; Я не думаю, что когда-либо служил сервлетом из root (/).
Например, если Servlet 'Foo' сопоставляется с URI '/foo', тогда я бы подумал, что URI:
/foo/path/to/resource
Результат:
RequestURI = /foo/path/to/resource
и
PathInfo = /path/to/resource
Ответ 2
Я помещу здесь небольшую таблицу сравнения (просто чтобы ее где-то найти):
Сервлет отображается как /test%3F/*
, и приложение развертывается под /app
.
http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S%3F+ID?p+1=c+d&p+2=e+f#a
Method URL-Decoded Result
----------------------------------------------------
getContextPath() no /app
getLocalAddr() 127.0.0.1
getLocalName() 30thh.loc
getLocalPort() 8480
getMethod() GET
getPathInfo() yes /a?+b
getProtocol() HTTP/1.1
getQueryString() no p+1=c+d&p+2=e+f
getRequestedSessionId() no S%3F+ID
getRequestURI() no /app/test%3F/a%3F+b;jsessionid=S+ID
getRequestURL() no http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S+ID
getScheme() http
getServerName() 30thh.loc
getServerPort() 8480
getServletPath() yes /test?
getParameterNames() yes [p 2, p 1]
getParameter("p 1") yes c d
В приведенном выше примере сервер работает на localhost:8480
, а имя 30thh.loc
было помещено в файл OS hosts
.
Комментарии
-
"+" обрабатывается как пробел только в строке запроса
-
Якорь "#a" не передается на сервер. Только браузер может работать с ним.
-
Если url-pattern
в отображении сервлета не заканчивается на *
(например, /test
или *.jsp
), getPathInfo()
возвращает null
.
Если используется Spring MVC
-
Метод getPathInfo()
возвращает null
.
-
Метод getServletPath()
возвращает часть между контуром и идентификатором сеанса. В приведенном выше примере значение будет /test?/a?+b
-
Будьте осторожны с URL-закодированными частями @RequestMapping
и @RequestParam
в Spring. Это ошибка (текущая версия 3.2.4) и обычно не работает должным образом.
Ответ 3
Рассмотрим следующий сервлет conf:
<servlet>
<servlet-name>NewServlet</servlet-name>
<servlet-class>NewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>NewServlet</servlet-name>
<url-pattern>/NewServlet/*</url-pattern>
</servlet-mapping>
Теперь, когда я нажимаю URL http://localhost:8084/JSPTemp1/NewServlet/jhi
, он будет вызывать NewServlet
, поскольку он отображается с шаблоном, описанным выше.
Здесь:
getRequestURI() = /JSPTemp1/NewServlet/jhi
getPathInfo() = /jhi
У нас есть те:
-
getPathInfo()
возвращает
строка, декодированная веб-контейнером, указывающая дополнительную информацию о пути, которая поступает после пути сервлета, но до строки запроса в URL-адресе запроса; или null, если URL-адрес не содержит дополнительной информации о пути
-
getRequestURI()
возвращает
Строка, содержащая часть URL-адреса от имени протокола до строки запроса
Ответ 4
Позвольте сложить полный URL-адрес, который клиент будет вводить в свою адресную строку, чтобы достичь вашего сервлета:
http://www.example.com:80/awesome-application/path/to/servlet/path/info?a=1&b=2#boo
Детали:
- схема:
http
- имя хоста:
www.example.com
- порт:
80
- контекстный путь:
awesome-application
- путь сервлета:
path/to/servlet
- информация о пути:
path/info
- query:
a=1&b=2
- фрагмент:
boo
URI запроса (возвращаемый getRequestURI) соответствует частям 4, 5 и 6.
(кстати, хотя вы не просите об этом, метод getRequestURL даст вам части 1, 2, 3, 4, 5 и 6).
Сейчас:
- часть 4 (путь контекста) используется для выбора вашего конкретного приложения из многих других приложений, которые могут выполняться на сервере.
- часть 5 (путь сервлета) используется для выбора определенного сервлета из многих других сервлетов, которые могут быть добавлены в ваше приложение WAR
- часть 6 (информация о пути) интерпретируется вашей логикой сервлета (например, она может указывать на некоторый ресурс, управляемый вашим сервлетом).
- часть 7 (запрос) также доступна для вашего сервлета, используя getQueryString
- часть 8 (фрагмент) даже не отправляется на сервер и имеет значение и известна только клиенту
Следующее всегда выполняется (кроме различий в кодировке URL):
requestURI = contextPath + servletPath + pathInfo
Ниже приведен пример из спецификации Servlet 3.0:
Примечание: изображение следует, у меня нет времени для воссоздания в HTML:
![введите описание изображения здесь]()