/** * Try to resolve the given exception that got thrown during handler execution, * returning a {@link ModelAndView} that represents a specific error page if appropriate. * <p>The returned {@code ModelAndView} may be {@linkplain ModelAndView#isEmpty() empty} * to indicate that the exception has been resolved successfully but that no view * should be rendered, for instance by setting a status code. * @param request current HTTP request * @param response current HTTP response * @param handler the executed handler, or {@code null} if none chosen at the * time of the exception (for example, if multipart resolution failed) * @param ex the exception that got thrown during handler execution * @return a corresponding {@code ModelAndView} to forward to, or {@code null} * for default processing */ ModelAndView resolveException( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
The @ControllerAdvice annotation is a component annotation allowing implementation classes to be auto-detected through classpath scanning. It is automatically enabled when using the MVC namespace or the MVC Java config.
@ControllerAdvice默认在Spring MVC的命名空间中启用。
Classes annotated with @ControllerAdvice can contain @ExceptionHandler, @InitBinder, and @ModelAttribute annotated methods, and these methods will apply to @RequestMapping methods across all controller hierarchies as opposed to the controller hierarchy within which they are declared.
@ControllerAdvice声明的异常处理方法默认对全局都是有效的。
1 2 3 4 5 6 7 8 9 10 11
// Target all Controllers annotated with @RestController @ControllerAdvice(annotations = RestController.class) publicclassAnnotationAdvice{}
// Target all Controllers within specific packages @ControllerAdvice("org.example.controllers") publicclassBasePackageAdvice{}
// Target all Controllers assignable to specific classes @ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class}) publicclassAssignableTypesAdvice{}
/** * Provides handling for standard Spring MVC exceptions. * @param ex the target exception * @param request the current request */ @ExceptionHandler({ NoSuchRequestHandlingMethodException.class, HttpRequestMethodNotSupportedException.class, HttpMediaTypeNotSupportedException.class, HttpMediaTypeNotAcceptableException.class, MissingPathVariableException.class, MissingServletRequestParameterException.class, ServletRequestBindingException.class, ConversionNotSupportedException.class, TypeMismatchException.class, HttpMessageNotReadableException.class, HttpMessageNotWritableException.class, MethodArgumentNotValidException.class, MissingServletRequestPartException.class, BindException.class, NoHandlerFoundException.class }) publicfinalResponseEntity<Object> handleException(Exceptionex, WebRequestrequest) {
HttpHeaders headers = new HttpHeaders();
if (ex instanceof NoSuchRequestHandlingMethodException) { HttpStatus status = HttpStatus.NOT_FOUND; return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, headers, status, request); } ... ... }
@ResponseStatus
用于在自定义异常,设置http的状态码
1 2 3 4
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="No such Order") // 404 publicclassOrderNotFoundExceptionextendsRuntimeException{ // ... }
Spring MVC 中默认开启了ResponseStatusExceptionResolver,这个Resolver会处理上面
设置的Http status code。
A business exception can be annotated with @ResponseStatus. When the exception is raised, the ResponseStatusExceptionResolver handles it by setting the status of the response accordingly. By default the DispatcherServlet registers the ResponseStatusExceptionResolver and it is available for use.
/** * Handle the result of handler selection and handler invocation, which is * either a ModelAndView or an Exception to be resolved to a ModelAndView. */ privatevoidprocessDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception)throws Exception {
// Did the handler return a view to render? if (mv != null && !mv.wasCleared()) { render(mv, request, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isDebugEnabled()) { logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + "': assuming HandlerAdapter completed request handling"); } }
if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) { // Concurrent handling started during a forward return; }
if (mappedHandler != null) { mappedHandler.triggerAfterCompletion(request, response, null); } }
/** * Implementation of the {@link org.springframework.web.portlet.HandlerExceptionResolver} interface that handles * exceptions through the {@link ExceptionHandler} annotation. * * <p>This exception resolver is enabled by default in the {@link org.springframework.web.portlet.DispatcherPortlet}. * * @author Arjen Poutsma * @author Juergen Hoeller * @since 3.0 */ publicclassAnnotationMethodHandlerExceptionResolverextendsAbstractHandlerExceptionResolver{ ...