• Spring boot 2.0 版本报错 ResourceHttpRequestHandler cannot be cast to HandlerMethod


    Spring boot 2.0 版本报错 ResourceHttpRequestHandler cannot be cast to HandlerMethod

    在写自定义的starter的时候,做了一个拦截器,但是在强转的时候,抛出了异常,具体如图。

    image-20210309144020573

    代码如下:

    @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //其实在请求的时候,requestMapping会把所有的方法封装成HandlerMethod,最后放到拦截器中,一起返回。
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
    
            if(method.isAnnotationPresent(Log.class)){
                //  设置开始时间
                long startTime = System.currentTimeMillis();
                threadLocal.set(startTime);
            }
    
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            Log log = method.getAnnotation(Log.class);
            if(method.isAnnotationPresent(Log.class)){
                //  设置开始时间
                Long startTime = threadLocal.get();
                Long endTime = System.currentTimeMillis();
                Long expendTime = endTime - startTime;
    
                // 方法参数
                String uri = request.getRequestURI();
                String methodName = method.getDeclaringClass().getName() + "#" + method.getName();
                String methodDesc = log.value();
                String parameters = JSON.toJSONString(request.getParameterMap());
                MyLogInterceptor.log.info("
    描述:{}
    路径: {}
    方法: {}
    参数:{}
    耗时:{}", methodDesc, uri, methodName, parameters, expendTime);
            }
    
        }
    

    原因:简单的说,ResourceHttpRequestHandler是用来处理静态资源的;而HandlerMethod则是springMVC中用@Controller声明的一个bean及对应的处理方法。好像用到的是SimpleUrlHandlerMapping,导致来处理请求,并返回了一个ResourceHttpRequestHandler实例!而正是这ResourceHttpRequestHandler,在代码中强转HandlerMthod时抛出了异常。

    image-20210309152654781

    解决:在拦截器中加入判断

    /**
     * @author WGR
     * @create 2021/3/9 -- 13:48
     */
    @Slf4j
    public class MyLogInterceptor implements HandlerInterceptor {
    
        //线程隔离,每个线程都有自己的其实时间,但是它有内存泄漏的风险。
        private static final ThreadLocal<Long> threadLocal = new ThreadLocal<>();
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //其实在请求的时候,requestMapping会把所有的方法封装成HandlerMethod,最后放到拦截器中,一起返回。
            if(handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                Method method = handlerMethod.getMethod();
    
                if (method.isAnnotationPresent(Log.class)) {
                    //  设置开始时间
                    long startTime = System.currentTimeMillis();
                    threadLocal.set(startTime);
                }
            }
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            if(handler instanceof HandlerMethod){
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                Method method = handlerMethod.getMethod();
                Log log = method.getAnnotation(Log.class);
                if(method.isAnnotationPresent(Log.class)){
                    //  设置开始时间
                    Long startTime = threadLocal.get();
                    Long endTime = System.currentTimeMillis();
                    Long expendTime = endTime - startTime;
    
                    // 方法参数
                    String uri = request.getRequestURI();
                    String methodName = method.getDeclaringClass().getName() + "#" + method.getName();
                    String methodDesc = log.value();
                    String parameters = JSON.toJSONString(request.getParameterMap());
                    MyLogInterceptor.log.info("
    描述:{}
    路径: {}
    方法: {}
    参数:{}
    耗时:{}", methodDesc, uri, methodName, parameters, expendTime);
                }
            }
    
        }
    }
    

    如果你的项目中,还有静态资源,需要也在拦截器中,进行排除。

    image-20210309154655590

  • 相关阅读:
    web网页测试用例(非常实用)
    怎么做web接口测试
    我的周记13——”离开,是为了更好的回来"
    Lambda 表达式常用函数
    IEnumberable<T>接口
    Linq的学习
    未能加载文件或程序集“Newtonsoft.Json”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。
    拉姆达表达式的笔记
    注册今日头条
    爬取百思不得姐的段子
  • 原文地址:https://www.cnblogs.com/dalianpai/p/14505988.html
Copyright © 2020-2023  润新知