В чем разница между методами getRequestURI и getPathInfo в HttpServletRequest?

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

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

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

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

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

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

 /foo/path/to/resource 

Это приведет к:

 RequestURI = /foo/path/to/resource 

а также

 PathInfo = /path/to/resource 

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

Сервлет отображается как /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 cd 

В приведенном выше примере сервер работает на localhost:8480 а имя 30thh.loc было помещено в файл hosts ОС.

Комментарии

  • «+» обрабатывается как пробел только в строке запроса

  • Якорь «#a» не передается на сервер. С ним может работать только браузер.

  • Если url-pattern в отображении сервлета не заканчивается на * (например, /test или *.jsp ), getPathInfo() возвращает значение null .

Если используется Spring MVC

  • Метод getPathInfo() возвращает значение null .

  • Метод getServletPath() возвращает часть между getServletPath() и идентификатором сеанса. В приведенном выше примере значение будет /test?/a?+b

  • Будьте осторожны с URL-закодированными частями @RequestMapping и @RequestParam весной. Это багги (текущая версия 3.2.4) и обычно не работает должным образом .

Рассмотрим следующий сервлет conf:

   NewServlet NewServlet   NewServlet /NewServlet/*  

Теперь, когда я нажимаю URL http://localhost:8084/JSPTemp1/NewServlet/jhi , он будет вызывать NewServlet поскольку он сопоставляется с шаблоном, описанным выше.

Вот:

 getRequestURI() = /JSPTemp1/NewServlet/jhi getPathInfo() = /jhi 

У нас есть такие:

  • getPathInfo()

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

  • getRequestURI()

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

Давайте разложим полный 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. query: a=1&b=2
  8. fragment: boo

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

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

Теперь:

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

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

 requestURI = contextPath + servletPath + pathInfo 

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


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

введите описание изображения здесь

  • Как использовать относительные пути без включения имени корневого контекста?
  • Сервлет и фильтр
  • Доступ к пост-переменным с использованием сервлетов Java
  • Как получить и установить глобальный объект в контексте сервлета Java
  • Как вы возвращаете объект JSON из Java-сервлета
  • Как включить JSP-файл из другого проекта в мой проект
  • Кодирование / декодирование заголовков HTTP в Java
  • Как использовать атрибуты сеанса в Spring-mvc
  • Профилактика XSS в веб-приложении JSP / Servlet
  • Загрузка файла с помощью parseRequest от ServletFileUpload?
  • Можно ли использовать статический экземпляр java.sql.Connection в многопоточной системе?
  • Interesting Posts

    Видео, созданное с помощью изображений, воспроизводится только в VLC, но нет других игроков

    SQLite блокирует базу данных даже после закрытия соединения

    Неслучайная соль для hashей паролей

    application / x-www-form-urlencoded или multipart / form-data?

    В чем разница между angular.copy () и присваиванием (=)?

    Расширение диапазона WiFi – что мне нужно и в какой конфигурации?

    Может ли это быть хорошим подходом к обеспечению более безопасной защиты ОС от вредоносного ПО?

    Преобразование серийного номера excel DateTime в R DateTime

    Могу ли я установить кодовую страницу KiTTY по умолчанию для UTF-8 вместо ISO-8859-1?

    Зачем отмечать локальные переменные и параметры метода как «final» в Java?

    Angular 2 2.0.0-rc.1 Свойство ‘map’ не существует в типе ‘Observable ‘ не совпадает с сообщением о выпуске

    Меню «Пуск» Windows 10, центр уведомлений, не загружают приложения приложений

    Получение суффикса дня при использовании DateTime.ToString ()

    Как закрыть приложение OS X из командной строки с помощью псевдонима, определенного в моем .bash_profile?

    “Общая ошибка Не удается открыть раздел реестра Временный (изменчивый) …” из Access ODBC

    Давайте будем гением компьютера.