Servlet API는 전체 요청 경로를 requestURI
로 노출하고 이를 Servlet이 매핑되는 방식에 따라 값이 달라지는 contextPath
, servletPath
및 pathInfo
로 세분화합니다. 이러한 입력에서 Spring MVC는 매핑 핸들러에 사용할 조회 경로를 결정해야 하며, 해당되는 경우 contextPath
및 servletMapping
접두사를 제외해야 합니다.
servletPath
및 pathInfo
는 디코딩되어 lookupPath를 파생시키기 위해 전체 requestURI
와 직접 비교할 수 없게 만들고 이로 인해 requestURI
를 디코딩해야 합니다. 그러나 경로에 "/
" 또는 ";
"와 같은 인코딩된 예약 문자가 포함될 수 있기 때문에 자체적인 문제가 발생합니다. 이는 디코딩된 후 경로 구조를 변경하여 보안 문제를 일으킬 수도 있습니다. 또한 서블릿 컨테이너는 servletPath
를 다양한 수준으로 정규화하여 requestURI
에 대한 startWith
비교를 수행하는 것을 더 이상 불가능하게 만들 수 있습니다.
이것이 접두사 기반 servletPath
매핑 유형과 함께 제공되는 servletPath
에 의존하지 않는 것이 가장 좋은 이유입니다. DispatcherServlet
이 "/
"가 있거나 "/*
" 접두사가 없는 기본 서블릿으로 매핑되고 서블릿 컨테이너가 4.0+인 경우 Spring MVC는 서블릿 매핑 유형을 감지하고 servletPath
및 pathInfo
의 사용을 완전히 피할 수 있습니다. 3.1 서블릿 컨테이너에서 동일한 서블릿 매핑 유형을 가정하면 MVC 구성의 Path Matching를 통해 alwaysUseFullPath=true
로 UrlPathHelper
를 제공하여 동등한 결과를 얻을 수 있습니다.
다행히도 기본 서블릿 매핑 "/
"가 좋은 선택입니다. 그러나 컨트롤러 매핑과 비교할 수 있도록 하려면 requestURI
를 디코딩해야 한다는 문제가 여전히 남아 있습니다. 이는 경로 구조를 변경하는 예약된 문자를 디코딩할 가능성이 있기 때문에 다시 한 번 바람직하지 않습니다. 이러한 문자가 예상되지 않으면 이를 거부하거나(예: Spring Security HTTP 방화벽) UrlPathHelper
를 urlDecode=false
로 구성할 수 있지만 컨트롤러 매핑은 항상 제대로 작동하지 않을 수 있는 인코딩된 경로와 일치해야 합니다. 게다가 때로는 DispatcherServlet
이 다른 서블릿과 URL 공간을 공유해야 하고 접두어로 매핑되어야 할 수도 있습니다.
위의 문제는 AntPathMatcher
를 사용하는 문자열 경로 매칭 대신 PathPatternParser
및 구문 분석된 패턴을 사용할 때 해결됩니다. PathPatternParser
는 버전 5.3부터 Spring MVC에서 사용할 수 있으며 버전 6.0부터 기본적으로 활성화됩니다. 조회 경로 디코딩이나 인코딩된 컨트롤러 매핑이 필요한 AntPathMatcher
와 달리 구문 분석된 PathPattern
은 한 번에 하나의 경로 세그먼트씩 RequestPath
라는 경로의 구문 분석된 표현과 일치합니다. 이를 통해 경로 구조를 변경할 위험 없이 경로 세그먼트 값을 개별적으로 디코딩하고 정리(sanitize)할 수 있습니다. 구문 분석된 PathPattern
은 Servlet 경로 매핑이 사용되고 접두사가 단순하게 유지되는 한(즉, 인코딩된 문자가 없는 한) servletPath
접두사 매핑의 사용을 지원합니다. 패턴 구문 세부 정보 및 비교는 패턴 비교를 참조하세요.