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

原文地址:https://www.cnblogs.com/dalianpai/p/14505988.html