Servlet API открывает полный путь запроса как requestURI и далее разделяет его на contextPath, servletPath и pathInfo, значения которых зависят от того, каким образом отображен сервлет. Исходя из этих вводных данных Spring MVC должен определить путь поиска, который будет использоваться для отображения обработчика, являющийся путем в отображении самого DispatcherServlet, исключая contextPath и любой префикс servletMapping, если он присутствует.

ServletPath и pathInfo декодируются, что делает невозможным их прямое сравнение с полным requestURI для получения lookupPath, поэтому возникает необходимость в декодировании requestURI. Однако это порождает свои проблемы, поскольку путь может содержать закодированные зарезервированные символы, такие как "/" или ";", которые могут изменить структуру пути после их декодирования, что также может привести к возникновению проблем безопасности. Кроме того, контейнеры сервлетов могут в разной степени нормализовать servletPath, что делает еще более невозможным выполнение сравнения startsWith с requestURI.

Именно поэтому лучше всего избегать зависимости от servletPath, который сопровождает тип отображения servletPath на основе префикса. Если DispatcherServlet отображен как сервлет по умолчанию со знаком "/" или отображен иначе без префикса со знаком "/*", а контейнер сервлетов имеет версию 4.0+, то Spring MVC сможет определить тип отображения сервлета и полностью избежать использования servletPath и pathInfo. В контейнере сервлетов 3.1, при условии использования тех же типов отображения сервлетов, аналогичного результата можно достигнуть путем предоставления UrlPathHelper с alwaysUseFullPath=true через Path Matching в конфигурации MVC.

К счастью, стандартное отображение сервлетов "/" является продуманным выбором. Однако все еще существует проблема, связанная с тем, что requestURI нужно декодировать, чтобы можно было сравнивать с отображениями контроллеров. Это опять же нежелательно из-за вероятности декодирования зарезервированных символов, которые изменят структуру пути. Если наличие таких символов не ожидается, то можно заблокировать их (как в HTTP-брандмауэре Spring Security), или же можно сконфигурировать UrlPathHelper с urlDecode=false, но отображения контроллера должны будут соответствовать закодированному пути, что не всегда работает приемлемо. Более того, иногда DispatcherServlet приходится делить пространство URL с другим сервлетом, и это может потребовать отображения по префиксу.

Вышеперечисленные проблемы можно решить более основательно, если перейти от PathMatcher к парсированному PathPattern, доступному в версии 5.3 и выше. В отличие от AntPathMatcher, которому требуется либо декодированный путь поиска, либо закодированное отображение контроллера, парсированный PathPattern сопоставляется с парсированным представлением пути, называемым RequestPath, по одному сегменту пути за раз. Это позволяет декодировать и очистить значения сегментов пути по отдельности без риска изменить структуру пути. Парсированный PathPattern также поддерживает использование отображения префикса servletPath при условии, что префикс остается простым и не содержит символов, которые необходимо кодировать.