/user/info
,访问路由可以是/user/info
,也可以是/user/info/
可多一个斜杠/user/info/
,访问路由只可以是/user/info/
默认情况是完全匹配,所以带不带斜杠是不一样的。
Spring 有一个useTrailingSlashMatch
配置,如果打开,当默认完全匹配失败的情况下,会再次尝试将注册pattern加上/之后,再和请求的pattern对比,所以注册的/user/info
可以匹配访问的/user/info/
if (this.pathMatcher.match(pattern, lookupPath)) {
return pattern;
}
if (this.useTrailingSlashMatch) {
if (!pattern.endsWith("/") && this.pathMatcher.match(pattern + "/", lookupPath)) {
return pattern +"/";
}
}
return null;
doMatch:205, AntPathMatcher {org.springframework.util}
match:177, AntPathMatcher {org.springframework.util}
lookupHandler:177, AbstractUrlHandlerMapping {org.springframework.web.servlet.handler}
getHandlerInternal:123, AbstractUrlHandlerMapping {org.springframework.web.servlet.handler}
getHandler:401, AbstractHandlerMapping {org.springframework.web.servlet.handler}
getHandler:1231, DispatcherServlet {org.springframework.web.servlet}
doDispatch:1014, DispatcherServlet {org.springframework.web.servlet}
doService:942, DispatcherServlet {org.springframework.web.servlet}
processRequest:998, FrameworkServlet {org.springframework.web.servlet}
doGet:890, FrameworkServlet {org.springframework.web.servlet}
service:634, HttpServlet {javax.servlet.http}
service:875, FrameworkServlet {org.springframework.web.servlet}
service:741, HttpServlet {javax.servlet.http}
internalDoFilter:231, ApplicationFilterChain {org.apache.catalina.core}
doFilter:166, ApplicationFilterChain {org.apache.catalina.core}
doFilter:53, WsFilter {org.apache.tomcat.websocket.server}
internalDoFilter:193, ApplicationFilterChain {org.apache.catalina.core}
doFilter:166, ApplicationFilterChain {org.apache.catalina.core}
doFilterInternal:99, RequestContextFilter {org.springframework.web.filter}
doFilter:107, OncePerRequestFilter {org.springframework.web.filter}
internalDoFilter:193, ApplicationFilterChain {org.apache.catalina.core}
doFilter:166, ApplicationFilterChain {org.apache.catalina.core}
doFilterInternal:92, FormContentFilter {org.springframework.web.filter}
doFilter:107, OncePerRequestFilter {org.springframework.web.filter}
internalDoFilter:193, ApplicationFilterChain {org.apache.catalina.core}
doFilter:166, ApplicationFilterChain {org.apache.catalina.core}
doFilterInternal:93, HiddenHttpMethodFilter {org.springframework.web.filter}
doFilter:107, OncePerRequestFilter {org.springframework.web.filter}
internalDoFilter:193, ApplicationFilterChain {org.apache.catalina.core}
doFilter:166, ApplicationFilterChain {org.apache.catalina.core}
doFilterInternal:200, CharacterEncodingFilter {org.springframework.web.filter}
doFilter:107, OncePerRequestFilter {org.springframework.web.filter}
internalDoFilter:193, ApplicationFilterChain {org.apache.catalina.core}
doFilter:166, ApplicationFilterChain {org.apache.catalina.core}
invoke:199, StandardWrapperValve {org.apache.catalina.core}
invoke:96, StandardContextValve {org.apache.catalina.core}
invoke:490, AuthenticatorBase {org.apache.catalina.authenticator}
invoke:139, StandardHostValve {org.apache.catalina.core}
invoke:92, ErrorReportValve {org.apache.catalina.valves}
invoke:74, StandardEngineValve {org.apache.catalina.core}
service:343, CoyoteAdapter {org.apache.catalina.connector}
service:408, Http11Processor {org.apache.coyote.http11}
process:66, AbstractProcessorLight {org.apache.coyote}
process:770, AbstractProtocol$ConnectionHandler {org.apache.coyote}
doRun:1415, NioEndpoint$SocketProcessor {org.apache.tomcat.util.net}
run:49, SocketProcessorBase {org.apache.tomcat.util.net}
runWorker:1149, ThreadPoolExecutor {java.util.concurrent}
run:624, ThreadPoolExecutor$Worker {java.util.concurrent}
run:61, TaskThread$WrappingRunnable {org.apache.tomcat.util.threads}
run:748, Thread {java.lang}
如果Spring 3 想打开该配置:
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch(true);
}
}