В чем разница между методами getRequestURI и getPathInfo в HttpServletRequest? - PullRequest
125 голосов
/ 08 февраля 2011

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

На моем локальном компьютере HttpServletRequest.getPathInfo() и HttpServletRequest.getRequestURI() возвращают одинаковые результаты. Но я не уверен, что они вернут в производственной среде.

Итак, в чем разница между этим методом и что мне выбрать?

Ответы [ 4 ]

405 голосов
/ 10 января 2014

Я положу небольшую таблицу сравнения здесь (просто чтобы где-то иметь):

Сервлет сопоставлен как /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) и обычно не работает должным образом .

70 голосов
/ 08 февраля 2011

getPathInfo() дает дополнительную информацию о пути после URI, используемую для доступа к сервлету, где getRequestURI() дает полный URI.

Я бы подумал, что они будут другими, учитывая, что сервлет долженбыть настроенным с его собственным шаблоном URI во-первых;Я не думаю, что когда-либо обслуживал сервлет из корня (/).

Например, если сервлет 'Foo' сопоставлен с URI '/ foo', то я бы подумал, что URI:

/foo/path/to/resource

В результате:

RequestURI = /foo/path/to/resource

и

PathInfo = /path/to/resource
21 голосов
/ 10 марта 2017

Давайте разберем полный URL-адрес, который клиент будет вводить в адресную строку, чтобы добраться до вашего сервлета:

http://www.example.com:80/awesome-application/path/to/servlet/path/info?a=1&b=2#boo

Части:

  1. схема: http
  2. имя хоста: www.example.com
  3. порт: 80
  4. путь к контексту: awesome-application
  5. путь к сервлету: path/to/servlet
  6. информация о пути: path/info
  7. запрос: a=1&b=2
  8. фрагмент: boo

URI запроса (возвращенопо getRequestURI ) соответствует частям 4, 5 и 6.

(кстати, даже если вы не просите об этом, метод getRequestURL даст вам части1, 2, 3, 4, 5 и 6).

Сейчас:

  • часть 4 (контекстный путь) используется для выбора конкретного приложения из множества других приложений, которыеможет быть запущен на сервере
  • часть 5 (путь к сервлету) используется для выбора конкретного сервлета из множества других сервлетов, которые могут быть включены в WAR
  • части 6 вашего приложения (путьяnfo) интерпретируется логикой вашего сервлета (например, он может указывать на некоторый ресурс, управляемый вашим сервлетом).
  • part 7 (запрос) также предоставляется вашему сервлету с помощью getQueryString
  • часть 8 (фрагмент) даже не отправляется на сервер и является релевантной и известной только клиенту

Всегда выполняется следующее (кроме различий в кодировке URL):

requestURI = contextPath + servletPath + pathInfo

Следующий пример из спецификации Servlet 3.0 очень полезен:


Примечание: изображение следует, у меня нетвремя для воссоздания в HTML:

enter image description here

16 голосов
/ 08 февраля 2011

Рассмотрим следующий 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()

    1020 * возвращается *
    строка, декодируемая веб-контейнером, задающая дополнительную информацию о пути, которая идет после пути сервлета, но перед строкой запроса в URL запроса; или ноль, если URL не содержит никакой дополнительной информации о пути

  • getRequestURI()

    возвращается
    строка, содержащая часть URL от имени протокола до строки запроса

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...