getPathInfo или getRequestURI: выбираем правильно в Java
Быстрый ответ
Метод getRequestURI() возвращает полный URI, из которого исключены параметры запроса, но в то же время в него включены контекст приложения и путь, соответствующий сервлету. В отличие от него, метод getPathInfo() извлекает часть URI, находящуюся после того фрагмента пути, который соответствует сервлету, и до параметров запроса. Данный метод удобен для получения RESTful параметров.
Пример: для URL http://www.example.com/app/servlet/extra?query=123 результат будет следующим:
- для getRequestURI():/app/servlet/extra
- для getPathInfo():/extra
String uri = request.getRequestURI(); // /app/servlet/extra
String pathInfo = request.getPathInfo(); // /extra

Анализ объекта HttpServletRequest
Рассмотрев HttpServletRequest, стоит обратить внимание на его основные компоненты, влияющие на корректное восприятие URL:
- Контекстный путь (Context Path): определяет корневой путь приложения, доступ к которому осуществляется через getContextPath().
- Путь сервлета (Servlet Path): это фрагмент URI, относящийся к сервлету, отвечающему за обработку запроса.
- Информация о пути (Path Info): сегмент URI, передаваемый сервлету после пути сервлета, который часто используется в RESTful приложениях.
Примечание: при работе с Spring MVC крайне важно внимательно относиться к обработке фрагментов URL, чтобы не столкнуться с проблемами безопасности.
Подводные камни при настройке карты сервлетов
При конфигурировании карты сервлетов стоит помнить, что пропуск символа '*' в маппинге может привести к тому, что getPathInfo() вернет null.
Например, при использовании маппинга /app/* и обращении к /app/servlet/extra, метод getPathInfo() вернет /extra.
Избежание сложностей при обработке URI
Метод getPathInfo() может обрабатываться по-разному в разных средах разработки и продакшена, что требует тщательного тестирования и осознанной настройки конфигурации.
Дополнительные методы объекта HttpServletRequest
Помимо getRequestURI() и getPathInfo(), в HttpServletRequest включены и другие методы, такие как доступ к строке запроса через getQueryString() и обработка фрагментов URL, которую выполняет клиентская сторона после символа "#".
Для обеспечения правильного управления данными следует помнить, что getRequestURI() предоставляет декодированную строку, а getPathInfo() может также вернуть информацию о пути в декодированном виде.
Руководство по спецификации сервлетов
Спецификация сервлетов подробно описывает функции getRequestURI() и getPathInfo(). Ее изучение поможет глубже понять их использование.
Визуализация
Можно представить себе прогулку, чтобы лучше осознать различия между getRequestURI() и getPathInfo():
Город = "Путь запроса Сервлет"
Главная улица (getRequestURI): /Shop/Electronics/TV
Боковая улочка (getPathInfo) при маппинге на /Shop: /Electronics/TV
getRequestURI(): Полный путь, проходимый от начала до конечного пункта назначения.
Дом 🏡 -----------------> 🏬 Магазин электроники 📺 (Полный путь)
getPathInfo(): Только часть пути после последней существенной остановки на маршруте.
Значимая остановка 🛣️ -- [Магазин] --> 🏬 Магазин электроники 📺 (Часть пути)
Ключевое примечание: Если getRequestURI() отражает всю историю пройденного пути, то getPathInfo() описывает отдельные главы этой истории.
Дополнительные рекомендации для разработчиков
Особенности Spring MVC
При разработке на платформе Spring MVC, столкновение с null в getPathInfo() является распространенным. В таких случаях может потребоваться использовать getRequestURI(), чтобы обеспечить единообразие данных.
Паттерн Front Controller
Для Front Controller'ов, например DispatcherServlet, изъяснение пути запроса имеет решающую важность для правильной работы MVC подхода, в связи с чем getRequestURI() и getPathInfo() играют ключевую роль.
Обработка URL-декодирования
Учтите, что getPathInfo() может предоставить сегменты пути в декодированном виде. Обработка таких данных должна быть корректной, чтобы избежать возникновения проблем, связанных с уязвимостями двойного URL-декодирования.
Полезные материалы
- HttpServletRequest (Java(TM) EE 8 Specification APIs) — официальная документация JavaDoc для HttpServletRequest.
- Java Reading Undecoded URL from Servlet – Stack Overflow — обсуждение на Stack Overflow, посвященное теме getRequestURIиgetPathInfo.
- Understanding Java Servlets – getRequestURI vs getPathInfo — подробное руководство, объясняющее отличия между getRequestURIиgetPathInfo.
- Tutorial | DigitalOcean — исследование параметров пути в сервлетах с примерами кода.
- Apache Tomcat 8 Configuration Reference (8.5.98) – The Valve Component — обзор обработки запросов в Apache Tomcat.
- A Guide to the Servlet API Path Information – DZone — обширное руководство по работе с getPathInfoиgetRequestURI.


