Spring boot 2.0 版本報錯 ResourceHttpRequestHandler cannot be cast to HandlerMethod
在寫自定義的starter的時候,做了一個攔截器,但是在強轉的時候,拋出了異常,具體如圖。

代碼如下:
@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("\n描述:{}\n路徑: {}\n方法: {}\n參數:{}\n耗時:{}", methodDesc, uri, methodName, parameters, expendTime);
}
}
原因:簡單的說,ResourceHttpRequestHandler是用來處理靜態資源的;而HandlerMethod則是springMVC中用@Controller聲明的一個bean及對應的處理方法。好像用到的是SimpleUrlHandlerMapping,導致來處理請求,並返回了一個ResourceHttpRequestHandler實例!而正是這ResourceHttpRequestHandler,在代碼中強轉HandlerMthod時拋出了異常。

解決:在攔截器中加入判斷
/**
* @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("\n描述:{}\n路徑: {}\n方法: {}\n參數:{}\n耗時:{}", methodDesc, uri, methodName, parameters, expendTime);
}
}
}
}
如果你的項目中,還有靜態資源,需要也在攔截器中,進行排除。

