之前没注意springboot 404 会经过两次拦截器
我在拦截器做了token判断
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//返回数据格式
response.setContentType("application/json;charset=UTF-8");
//获取请求头的token
// System.out.println(request.getRequestURI());
// System.out.println((Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE));
String token = request.getHeader("token");
if (!StringUtils.hasText(token) || Objects.isNull(stringRedisTemplate.opsForValue().get("connect_" + token))) {
throw new CustomException(TOKEN_ERROR);
} else {
return true;
}
}
在拦截器上我也做了处理,对异常重定向的/error也做了拦截放行
//添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getLoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/account/login","/outside/**","/error");
}
当时我以为会返回404的页面但是返回的却是500
明明放行了/error,但是他还是经过了拦截器
打开控制板输出requesturi
打印出来的是当前地址
是不是/error不走呢,然后我不放行/error
发现第一次走的是原地址,第二次走的是/error
这就头痛了,如果只放行/error,会走原路径那我返回500的页面,明明404却返回500,这有点不妥,但是我也不可能在过滤器上判断uri是否符合程序所写的uri,毕竟接口会不断累加的。
最终我发现一个解决方法
配置文件yml加上这一段话(后来发现这个方式不妥,最底下补上正确的解决方式)
spring:
web:
resources:
add-mappings: false
这回正常了,因为只走一次/error,而我放行了error就没打印
为啥加上这段配置就不会走原地址,其实我没太明白,这跟静态资源有啥关系,有待研究
后续:
自己打了断点之后发现是在DispatchServlet里面的getHandler有所不同
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
/**
* Return the HandlerExecutionChain for this request.
* <p>Tries all handler mappings in order.
* @param request current HTTP request
* @return the HandlerExecutionChain, or {@code null} if no handler could be found
*/
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
如果没有配置add-mappings: false
多对一个静态资源的handlermapping
然后给你匹配上
而配置了add-mappings: false
就直接给你走404了,不会过两次拦截起了
过了几天回顾了,这个问题
发现这种处理方式不妥,如果关闭映射会导致访问不了静态资源
其实resourcesHandlerMapping默认匹配是/**,只要修改默认匹配规则就能避免走拦截器
正确解决方式为
spring:
mvc:
static-path-pattern: /static/**