La

API de servlet expone la ruta de solicitud completa como requestURI y la divide en contextPath, servletPath y pathInfo, cuyos significados dependen de cómo se representa el servlet. A partir de esta entrada, Spring MVC debe determinar la ruta de búsqueda que se utilizará para asignar el controlador, que es la ruta en la asignación del propio DispatcherServlet, excluyendo contextPath y cualquier prefijo servletMapping, si está presente.

ServletPath y pathInfo están decodificados, lo que hace imposible compararlos directamente con el requestURI completo para obtener el lookupPath, por lo que la decodificación se vuelve necesaria requestURI. Sin embargo, esto plantea sus propios problemas porque la ruta puede contener caracteres reservados codificados como "/" o ";", que pueden cambiar la estructura de la ruta después de que se decodificados, lo que también puede provocar problemas de seguridad. Además, los contenedores de servlets pueden normalizar servletPath en diversos grados, lo que hace aún más imposible comparar startsWith con requestURI.

Por eso es mejor evitar depender del servletPath que acompaña al tipo de mapeo servletPath basado en prefijos. Si DispatcherServlet se representa como un servlet predeterminado con un signo "/", o se representa sin un prefijo con un signo "/*", y el contenedor de servlet tiene la versión 4.0+, entonces Spring MVC podrá determinar el tipo de mapeo del servlet y evitar por completo el uso de servletPath y pathInfo. En un contenedor de servlets 3.1, suponiendo que se utilicen los mismos tipos de asignación de servlets, se puede lograr un resultado similar proporcionando UrlPathHelper con alwaysUseFullPath=true a través de Path Matching en la configuración de MVC.

Afortunadamente, la asignación de servlet predeterminada "/" es una elección inteligente. Sin embargo, todavía existe el problema de que es necesario decodificar requestURI para poder compararlo con las asignaciones de controladores. Esto tampoco es deseable debido a la posibilidad de decodificar caracteres reservados que cambiarán la estructura de la ruta. Si no se esperan dichos caracteres, puede bloquearlos (como en el firewall HTTP de Spring Security), o puede configurar UrlPathHelper con urlDecode=false, pero las asignaciones del controlador debe coincidir con la ruta codificada, lo que no siempre funciona de manera aceptable. Además, a veces DispatcherServlet tiene que compartir espacio URL con otro servlet, y esto puede requerir una asignación por prefijo.

Los problemas anteriores se pueden resolver más a fondo pasando de PathMatcher al PathPattern analizado, disponible en la versión 5.3 y superior. A diferencia de AntPathMatcher, que requiere una ruta de búsqueda decodificada o una asignación de controlador codificada, un PathPattern analizado coincide con una representación de ruta analizada llamada RequestPath, por un segmento de camino a la vez. Esto permite decodificar y borrar los valores del segmento de ruta individualmente sin el riesgo de cambiar la estructura de la ruta. Un PathPattern analizado también admite el uso de una asignación de prefijo servletPath, siempre que el prefijo se mantenga simple y no contenga caracteres que deban codificarse.