spring boot2.0 ResourceHttpRequestHandler cannot be cast to HandlerMethod

在 spring boot 2.0 项目中写拦截器时,遇到一个小问题,记录一下。错误日志如下:

java.lang.ClassCastException: org.springframework.web.servlet.resource.ResourceHttpRequestHandler cannot be cast to org.springframework.web.method.HandlerMethod

在以下两处都会报错

//在打开页面时报错
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    HandlerMethod handlerMethod = (HandlerMethod) handler;
    Method method = handlerMethod.getMethod();
    System.out.println("用户:"+ip+",访问目标:"+method.getDeclaringClass().getName() + "." + method.getName());

    User user=(User)request.getSession().getAttribute("user");
    if(null==user){
        response.sendRedirect("toLogin");
        flag = false;
    }else{
        flag = true;
    }
    return flag;
}

//在提交post请求时报错,即点击提交按钮
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    HandlerMethod handlerMethod = (HandlerMethod) handler;
    Method method = handlerMethod.getMethod();
    long startTime = (Long) request.getAttribute("requestStartTime");
    long endTime = System.currentTimeMillis();
    long executeTime = endTime - startTime;
    // 打印方法执行时间
    if (executeTime > 1000) {
        System.out.println("[" + method.getDeclaringClass().getName() + "." + method.getName() + "] 执行耗时 : "
                + executeTime + "ms");
    } else {
        System.out.println("[" + method.getDeclaringClass().getSimpleName() + "." + method.getName() + "] 执行耗时 : "
                + executeTime + "ms");
    }
}

原因就在于,spring boot 2.0 对静态资源也进行了拦截,当拦截器拦截到请求之后,但 controller 里并没有对应的请求时,该请求会被当成是对静态资源的请求。此时的 handler 就是 ResourceHttpRequestHandler,就会抛出上述错误。

解决方法:

1.拦截器那里排除静态资源的请求路径

public void addInterceptors(InterceptorRegistry registry) {
        // addPathPatterns 用于添加拦截规则
        // excludePathPatterns 用户排除拦截
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/images/**","/js/**","/css/**","/toLogin","/login","/bootstrap-3.3.7-dist/**","/fonts/**","/bizhi.jpg");
    }

附一张项目结构图:

在这里插入图片描述

在实际操作中,采用该方法后依然报错。经多次测试,发现本人遇到的问题在于 jq22.css 文件中可能访问了 images 目录下不存在的图片。

.ph-exclusive #browsers-parent #ph-owl #ph-owl-body {
  width: 264px;
  height: 327px;
  background-image: url("../images/ph-owl.png");//比如说该图片在images目录下不存在,虽说不影响使用,但是会导致这样的问题出现
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10;
}
  1. instanceof 关键字进行判断。
if (handler instanceof ResourceHttpRequestHandler) {
    System.out.println("preHandle这是一个静态资源方法!");
} else if (handler instanceof HandlerMethod) {
    HandlerMethod handlerMethod = (HandlerMethod) handler;
    Method method = handlerMethod.getMethod();
    System.out.println("用户:" + ip + ",访问目标:" + method.getDeclaringClass().getName() + "." + method.getName());
}

最好在 preHandle 和 postHandle 方法中都加上此判断。

发布了103 篇原创文章 · 获赞 77 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Herishwater/article/details/102972894