[英]@ControllerAdvice exception handling together with @ResponseStatus
我有@ControllerAdvice
類,它處理一組異常。 除了我們有其他一些例外,這些例外還帶有@ResponseStatus
批注。 為了結合這兩種方法,我們使用博客文章中描述的技術: http : //spring.io/blog/2013/11/01/exception-handling-in-spring-mvc ,即在ControllerAdvice
我們在下面處理通用Exception
道路:
@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
// If the exception is annotated with @ResponseStatus rethrow it and let
// the framework handle it - like the OrderNotFoundException example
// at the start of this post.
// AnnotationUtils is a Spring Framework utility class.
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)
throw e;
// Otherwise setup and send the user to a default error-view.
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", req.getRequestURL());
mav.setViewName(DEFAULT_ERROR_VIEW);
return mav;
}
它的工作原理像一個超級按鈕,但是,使用此技術會導致錯誤,並在應用程序日志中顯示以下文本:
2014-06-11 15:51:32.907 ERROR o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: ...
這是由ExceptionHandlerExceptionResolver
的這段代碼引起的:
try {
if (logger.isDebugEnabled()) {
logger.debug("Invoking @ExceptionHandler method: " + exceptionHandlerMethod);
}
exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception);
}
catch (Exception invocationEx) {
logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx);
return null;
}
是否有人知道如何將這兩種方法正確地結合在一起以進行異常處理,以避免日志中的錯誤?
謝謝,揚
這是一個老問題,但是我今天剛遇到這個問題,並且找到了比禁用ExceptionHandlerExceptionResolver
日志記錄更好的解決方案。 事實證明,可以通過升級到最新版本的spring框架(對我來說是4.3.8)解決了該問題。 ExceptionHandlerExceptionResolver
已修復,可以檢測是否從@ExceptionHandler
拋出了原始異常。 在這種情況下,不再記錄異常。
當我錯過這個import
時,我遇到了同樣的問題:
import org.springframework.http.HttpStatus;
Eclipse沒有提供我將其添加到Quick Fix中的功能 ,而是手動添加了該行,它有所幫助。
我以稍微不同的方式處理它,我認為可以解決您的問題。
因為我知道基本上我想處理404而不是500的任何色調,所以我會尋找一個NOT_FOUND狀態並進行相應的發送,這似乎可行,並且您不會重新拋出異常。
這意味着
@ControllerAdvice
public class MVCExceptionHandler {
private static final Logger log = LogManager.getLogger();
@ExceptionHandler(Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest req, HttpServletResponse res, Exception ex) throws Exception {
// If the exception is annotated with @ResponseStatus check if it's a 404 in which case deal with it, otherwise 500 it.
if (AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class) != null) {
ResponseStatus rs = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);
if (HttpStatus.NOT_FOUND.equals(rs.value())) {
res.setStatus(HttpStatus.NOT_FOUND.value());
return new ModelAndView("error/404");
}
}
log.error("Error while loading", ex);
return new ModelAndView("error/500");
}
}
問題是您在引發異常,而不是返回ModelAndView
。 本質上,您試圖在ControllerAdvice
類中重新實現ResponseStatusExceptionResolver
。 您可以做到這一點(例如,通過ResponseStatusExceptionResolver
的復制/粘貼代碼),但是除了重復之外,該方法也不完整。 對於某些內置的異常,Spring還附帶有DefaultHandlerExceptionResolver
,這種方法可能無法正確處理這些異常。
相反,我所做的是在ControllerAdvice
類中沒有Exception.class
處理程序。 我不知道這是否是最好的解決方案,但這是我所知道的最好的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.