1. Preface
The importance of unified exception handling for application is self-evident. Today, let's talk about how Spring can handle unified Rest exception handling. At the same time, we will simply compare their advantages and disadvantages.
2. @Controller Combine @ ExceptionHandler
Declare a method in the controller and mark it with the @ ExceptionHandler annotation:
@Controller @RequestMapping("/test") public class TestController { @RequestMapping("/err") @ResponseBody public Object demo1(){ int i = 1 / 0; return new Date(); } @ExceptionHandler({RuntimeException.class}) public ModelAndView fix(Exception ex){ System.out.println(ex.getMessage()); return new ModelAndView("error",new ModelMap("ex",ex.getMessage())); } }
Advantage:
- Highest priority.
- @The method return value type of ExceptionHandler tag supports multiple types. It can be views, json, etc.
Disadvantages:
- The exception type on the @ ExceptionHandler annotation in a Controller cannot be the same, otherwise the runtime throws an exception.
- An exception type that requires explicit declaration handling.
- Scope is just that Controller is not a real global exception. If you want to work globally, you need to put it in the parent class of all controllers.
3. @ControllerAdvice combined with @ ExceptionHandler
This is an improved version of 2. By defining the @ ControllerAdvice class and marking @ ExceptionHandler on the method, the purpose of global exception handling is achieved:
@ControllerAdvice public class TestController { @ExceptionHandler({RuntimeException.class}) public ModelAndView fix(Exception ex){ System.out.println(ex.getMessage()); return new ModelAndView("error",new ModelMap("ex",ex.getMessage())); } }
Advantage:
- Global exception handling.
- Subject and status code of complete control response
- Multiple exceptions are mapped to the same method for handling together, and it makes full use of the updated response entity response
Disadvantages:
- The exception type on the @ ExceptionHandler annotation in a Controller cannot be the same, otherwise the runtime throws an exception.
- An exception type that requires explicit declaration handling.
In general, this method is also recommended for exception handling. Compatible in most cases.
4. HandlerExceptionResolver interface
Implement the HandlerExceptionResolver interface. Here we inherit its abstract implementation AbstractHandlerExceptionResolver:
@Component public class RestResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver { @Override protected ModelAndView doResolveException( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try { if (ex instanceof IllegalArgumentException) { return handleIllegalArgument((IllegalArgumentException) ex, response, handler); } //todo more exception } catch (Exception handlerException) { //todo } return null; } private ModelAndView handleIllegalArgument(IllegalArgumentException ex, HttpServletResponse response) throws IOException { response.sendError(HttpServletResponse.SC_CONFLICT); String accept = request.getHeader(HttpHeaders.ACCEPT); //todo more response return new ModelAndView(); } }
Advantage:
- This is a global exception handler.
- In this way, it is convenient to return JSP, velocity and other template views.
- Multiple formats of response are supported. Although the overridden method returns ModelAndView, we can use it to customize the response results because there is HttpServletResponse in the parameter. For example, if the client asks for application / json, then in case of an error situation, we need to make sure that we return a response encoded in application / json.
Disadvantages:
- We need to interact with low-level HttpServletResponse to implement various forms of response bodies.
- Low priority
5. Exception handling in spring boot
If you use Spring Boot as the framework We can also use it in a unique way. The advantage is that the low-level API is shielded, and the disadvantages are obvious, so specific exceptions cannot be caught.
5.1 implementation of ErrorController
By default, Spring Boot provides / error mapping to handle all errors, registers the global error page in the Servlet container and returns it to the client. By implementing the ErrorController interface and registering as a Bean. No more examples here. Refer to BasicErrorController.
5.2 add ErrorAttributes
We can also add a Bean of type ErrorAttributes to replace the default exception handling.
@Component public class MyCustomErrorAttributes extends DefaultErrorAttributes { @Override public Map<String, Object> getErrorAttributes( WebRequest webRequest, boolean includeStackTrace) { Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace); errorAttributes.put("locale", webRequest.getLocale() .toString()); errorAttributes.remove("error"); //todo your business return errorAttributes; } }
5.3 inherit the base class BasicErrorController
Spring Boot auto configuration also provides a base class BasicErrorController to implement the exception handling of ErrorController interface. By default, it processes the error of text/html type request. It can inherit the base class to customize and handle more request types, add public methods and specify the processing type by using the product attribute of @ RequestMapping annotation.
@Component public class MyErrorController extends BasicErrorController { public MyErrorController(ErrorAttributes errorAttributes) { super(errorAttributes, new ErrorProperties()); } @RequestMapping(produces = MediaType.APPLICATION_XML_VALUE) public ResponseEntity<Map<String, Object>> xmlError(HttpServletRequest request) { //todo your business } }
6. ResponseStatusException of spring 5
In addition, in the latest Spring 5, you can handle it by throwing a ResponseStatusException exception.
Benefits:
- Easy to use
- One type, many status codes: an exception type can lead to many different responses. This reduces tight coupling compared to @ ExceptionHandler
- We will not have to create so many custom exception classes
- Because exceptions can be created programmatically, exception handling can be better controlled
Disadvantages:
- Without a unified exception handling method, it is more difficult to enforce some application wide conventions
- There may be a lot of duplicate code.
7. summary
We summarize and analyze the common and uncommon ways of Spring handling exceptions I believe you can find the right way to deal with it. If it's useful to you, please give me a compliment, your encouragement and my motivation!
Pay attention to the public address: Felordcn for more information