springmvc异常处理
1 DispatcherServlet的handlerExceptionResolvers
在DispatcherServlet初始化过程中,执行如下初始化方法
protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); }
其中有一步是初始化异常处理器 initHandlerExceptionResolvers(context);
private void initHandlerExceptionResolvers(ApplicationContext context) { this.handlerExceptionResolvers = null; if (this.detectAllHandlerExceptionResolvers) { // 在上下文中查找所有HandlerExceptionResolvers类型的bean. Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false); this.handlerExceptionResolvers = new ArrayList<>(matchingBeans.values()); } else { HandlerExceptionResolver her = context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class); this.handlerExceptionResolvers = Collections.singletonList(her); } // 如果上一步中没有获取到异常处理器,则使用默认的异常处理器 if (this.handlerExceptionResolvers == null) { this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class); } }
默认情况下,detectAllHandlerExceptionResolvers为true,此时会初始化三个HandlerExceptionResolver:
ExceptionHandlerExceptionResolver:使用用户加了@ExceptionHandler注解的方法来处理异常。
ResponseStatusExceptionHandler:如果异常类型是ResponseStatusException,则根据异常中的status和reason,利用HttpServletResponse.sendError来返回异常信息。
DefaultHandlerExceptionResolver:当前两个解析器没有成功处理,则该处理器会处理一些指定的异常类型,例如HttpRequestMethodNotSupportedException、HttpMediaTypeNotSupportedException、HttpMediaTypeNotAcceptableException等等;通过HttpServletResponse.sendError来返回异常信息。
我们可以通过实现 HandlerExceptionResolver 接口自定义异常处理器
2 @Controller类中使用@ExceptionHandler
该方法就会处理其所在controller类抛出的异常
3 @ControllerAdvice类中使用@ExceptionHandler注解
这样,Controller中抛出的所有异常都会被处理到。
4 官网给出的 @ExceptionHandler 参数
| 参数 | 描述 | 
|---|---|
| Exception type | 设置需要处理的异常类型.例子: @ExceptionHandler({FileSystemException.class, RemoteException.class}) | 
| 
 | For access to the controller method that raised the exception. | 
| 
 | Generic access to request parameters and request and session attributes without direct use of the Servlet API. | 
| 
 | Choose any specific request or response type (for example,  | 
| 
 | Enforces the presence of a session. As a consequence, such an argument is never  | 
| 
 | Currently authenticated user — possibly a specific  | 
| 
 | The HTTP method of the request. | 
| 
 | The current request locale, determined by the most specific  | 
| 
 | The time zone associated with the current request, as determined by a  | 
| 
 | For access to the raw response body, as exposed by the Servlet API. | 
| 
 | For access to the model for an error response. Always empty. | 
| 
 | Specify attributes to use in case of a redirect — (that is to be appended to the query string) and flash attributes to be stored temporarily until the request after the redirect. See Redirect Attributes and Flash Attributes. | 
| 
 | For access to any session attribute, in contrast to model attributes stored in the session as a result of a class-level  | 
| 
 | For access to request attributes. See  | 
5 @ExceptionHandler 的响应
| Return value | Description | 
|---|---|
| 
 | The return value is converted through  | 
| 
 | The return value specifies that the full response (including the HTTP headers and the body) be converted through  | 
| 
 | To render an RFC 7807 error response with details in the body, see Error Responses | 
| 
 | To render an RFC 7807 error response with details in the body, see Error Responses | 
| 
 | A view name to be resolved with  | 
| 
 | A  | 
| 
 | Attributes to be added to the implicit model with the view name implicitly determined through a  | 
| 
 | An attribute to be added to the model with the view name implicitly determined through a  Note that  | 
| 
 | The view and model attributes to use and, optionally, a response status. | 
| 
 | A method with a  If none of the above is true, a  | 
| Any other return value | If a return value is not matched to any of the above and is not a simple type (as determined by BeanUtils#isSimpleProperty), by default, it is treated as a model attribute to be added to the model. If it is a simple type, it remains unresolved. | 
因此,我们可以根据不同的异常,返回不通的响应,比如http状态码、自定义业务错误码等等。
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号