结论
如果你的工程配置了 Context-Path:
server:
port: 8080
servlet:
context-path: /admin
那么在拦截器路径配置处,就不需要写 Context-Path 的路径:
registry.addInterceptor(jwtAuthenticationInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login");
这样代表着需要拦截器拦截这样的路径:/admin/**
错误示例:
registry.addInterceptor(jwtAuthenticationInterceptor())
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin/login");
这样代表着需要拦截器拦截这样的路径:/admin/admin/**
原因
SpringMVC 会将请求路径剔除 Context-Path 后在匹配 Controller 与拦截器。
栗子:
- Context-Path:
/admin
- 拦截器的拦截路径:
/admin/**
- 请求路径:
/admin/user/page
请求路径剔除 Context-Path:/user/page
,匹配拦截器路径:/admin/**
匹配失败,故拦截器不会执行。
具体源代码如何处理的,可以查看 org.springframework.web.servlet.handler.MappedInterceptor
的 matches 方法:
public boolean matches(HttpServletRequest request) {
Object path = ServletRequestPathUtils.getCachedPath(request);
if (this.pathMatcher != defaultPathMatcher) {
path = path.toString();
}
boolean isPathContainer = (path instanceof PathContainer);
if (!ObjectUtils.isEmpty(this.excludePatterns)) {
for (PatternAdapter adapter : this.excludePatterns) {
if (adapter.match(path, isPathContainer, this.pathMatcher)) {
return false;
}
}
}
if (ObjectUtils.isEmpty(this.includePatterns)) {
return true;
}
// 注意此时的 Path 已经被剔除了,剔除过程可以追踪一下前面的方法调用栈。
// includePatterns 就是拦截器中配置的拦截路径
for (PatternAdapter adapter : this.includePatterns) {
if (adapter.match(path, isPathContainer, this.pathMatcher)) {
return true;
}
}
return false;
}
版权声明:本文为qq_38074398原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。