Hello, today for you to share SpringBoot exception processing, quickly take out a small notebook to write it down

1. Default exception handling mechanism

By default, SpringBoot provides /error requests to handle all exceptions.

On the browser client, the attribute in the request header is Accept:text/ HTML. Indicates that it wants text data of type HTML. Therefore, the returned error view is rendered in HTML format in response to a “whitelabel” error view.

For other clients, the attribute in the request header is Accept:/, and the default response is json data.

2. Abnormal handling process

HandlerExceptionResolver before introducing the exception handling process, it is important to understand HandlerExceptionResolver: the HandlerExceptionResolver interface, which maps exceptions to the corresponding unified error interface to display a user-friendly interface (instead of presenting specific error messages to users).

public interface HandlerExceptionResolver {

ModelAndView resolveException(HttpServletRequest Request, HttpServletResponse Response, Object Handler, Exception ex);Copy the code

}

At the time of DispatcherServlet initialization, all implementation classes for the HandlerExceptionResolver HandlerExceptionResolver interface are placed in the following collection

public class DispatcherServlet extends FrameworkServlet {

/ / exception parser private collection List < HandlerExceptionResolver > handlerExceptionResolvers;Copy the code

}

As you can see from the figure above, there are TerrorAttributes in this collection; And HandlerExceptionResolverComposite processor exception parser is combined, it includes three can really handle exceptions parser, ExceptionHandlerExceptionResolver, ResponseStatusExceptionResolver, DefaultHandlerExceptionResolver. Here’s what they are used to handle.

Reading the source code for the doDispatch() method, Spring MVC uses nested try-catch statements for the entire doDispatch() method

  • The inner try-catch is used to catch exceptions when HandlerMapping searches for HandlerExecutionChain and HandlerAdapter executes a specific Handler. The exception is passed to the processDispatchResult(processedRequest, Response, mappedHandler, MV, dispatchException) method. The outer try-catch is used to catch exceptions while rendering the view.
  • With two layers of nested try-catches, SpringMVC can catch exceptions from all three components when processing a user request, making it easy to achieve uniform exception handling.

As can be seen from the above code, when an exception occurs, the processHandlerException() method is entered to obtain the exception view, and the ModelAndView object is returned after processing. Next, regardless of whether the view is a normal view or an abnormal view, as long as ModelAndView is not empty, it enters the view rendering process. Here’s how to get the exception view.

Iterate through all of the processor exception parser handlerExceptionResolvers, see who can handle the exception

  • Terrorattributes starts with exceptions. The exception message is saved to the Request field and returns NULL, which is not really resolved.
  • HandlerExceptionResolverComposite traverses it contains three exception handling abnormal parser
  • ExceptionHandlerExceptionResolver processor exception parser support @ ControllerAdvice + @ ExceptionHandler process exception
  • ResponseStatusExceptionResolver processor exception parser support @ ResponseStatus + custom exception
  • DefaultHandlerExceptionResolver processor exception parser supports Spring at the bottom of the exception

When no exception resolver is available to handle the exception, the exception is thrown, and eventually Tomcat sends /error requests that map to the underlying BasicErrorController into the default exception handling mechanism.

Conclusion:

When an exception occurs, it is caught. Walk through all the processor exception parsers to see who can resolve. If you configure global exception handling with @ControllerAdvice+@ExceptionHandler and specify an error view, the exception will be handled and the view rendering process will proceed. If the exception cannot be handled by any of the handler exception resolvers, an exception will be thrown, and Tomcat will send /error requests to the default exception handling mechanism.

Access is a non-existent path, no exception will occur at this time, after the processor mapping, the processor adaptation call still returns an empty ModelAndView, so the view rendering cannot be done. Tomcat still sends /error requests to the default exception handling mechanism.

Default exception handling mechanism

If you want to understand error handling principle, must first see ErrorMvcAutoConfiguration: this is the automatic configuration error handling class, to add the container below several important components.

  • ErrorPageCustomizer
  • BasicErrorController
  • DefaultErrorViewResolver
  • DefaultErrorAttributes

First we see ErrorPageCustomizer components, this component is a static inner class, located in ErrorMvcAutoConfiguration inside. It implements the ErrorPageRegistrar interface, which provides methods you can use to register an ErrorPage. ErrorPage is officially described as a simple server-independent ErrorPage abstraction, roughly equivalent to a traditional element in web.xml. ErrorPage contains status codes, exceptions, and error controller mapping paths (server.error.path=/error). That is, when an exception occurs and none of the processor exception resolvers can handle it, Tomcat sends /error requests mapped to the BasicErrorController.

This is BasicErrorController. There are two important methods in it, which happen to be the default processing mechanism at the beginning of the object. Method 1: Text/HTML is returned for a browser request. Method 2: JSON is returned for a request from another client.

To summarize, BasicErrorController is used to:

  • Handle requests for default /error paths
  • Calls to DefaulViewResolver for error view resolution fall into three categories
  1. The templates engine supports parsing, so go to /templates/error/ and look for a status code error page that we configured, such as 404.html or 4xx.html.
  2. /resources/, /static/, /public/, / meta-INF /resources/.
  3. New ModelAndView(“error”, model) creates a default error Page. The default error view in ErrorMvcAutoConfiguration has been registered with the container, and it id is error in the container. Then the BeanNameViewResolver view parser will be used to find the default error view in the container according to the view logic error as the component ID.

Terrorviewresolver, which is basically error view resolution. If an error occurs, the actual error page is found using the HTTP status code as the view address. Note, however, that you first look for the exact error status code page, and then follow 4xx,5xx.

Finally, TerrorAttributes, which stores data that error pages can display. Such as status codes, error messages, exception messages, and so on.

public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered {

@override public Map<String, Object> getErrorAttributes(RequestAttributes RequestAttributes, boolean includeStackTrace) { Map<String, Object> errorAttributes = new LinkedHashMap<String, Object>(); errorAttributes.put("timestamp", new Date()); addStatus(errorAttributes, requestAttributes); addErrorDetails(errorAttributes, requestAttributes, includeStackTrace); addPath(errorAttributes, requestAttributes); return errorAttributes; }Copy the code

}

Conclusion:

  • When an exception occurs and none of the processor exception parsers can handle it, ErrorPageCustomizer takes effect (custom error response rules). Tomcat sends /error requests, which are then mapped to the BasicErrorController for processing by HandlerMapping.
  • Error view: If 4xx. HTML or 5xx. HTML error status code pages are configured, which error code page is resolved by DefaulViewResolver. If no configuration error status code page, is the default view StaticView errors, it is a static inner class in ErrorMvcAutoConfiguration, is automatically registered into the container. It is the Render () method in StaticView that creates the default Whitelabel Error Page that we often see during view rendering.
  • Extracting Data: What data a page can retrieve is set by terrorViewResolver.

4. Custom exception handling

1. Customize the exception handling page

In the case of a template engine

  • Error/status code.html, that is, the error page named status code.html in the template engine folder error folder; We can use 4xx and 5xx as error page filenames to match all errors of this type, but the exact status code.html is preferred.
  • No template engine (template engine cannot find this error page), look in the static resources folder. Still place the error page in the Error folder.
  • The error page is not found above, which is the default error page of SpringBoot.

Information retrieved by error pages

  • Timestamp: indicates the timestamp
  • Status: indicates the status code
  • Error: indicates an error message
  • Exception: exception object
  • “Message” : abnormal message
  • Errors: JSR303 data check errors are listed here

2. @ControllerAdvice+@ExceptionHandler Handles global exceptions

The bottom is supported by the abnormal ExceptionHandlerExceptionResolver processor parser

@responseStatus + custom exception

Bottom is supported by the abnormal ResponseStatusExceptionResolver processor parser, but after it parsing is complete, call the * * response in sendError (statusCode, resolvedReason); ** The /error request sent by Tomcat enters the default exception handling mechanism.

Spring’s underlying exception

For example, parameter type conversion is abnormal; Supported by the abnormal DefaultHandlerExceptionResolver processor parser, frame at the bottom of the exception handling. But after parsing, it calls Response.senderror (httpServletresponse.sc_bad_request, ex.getMessage()); The /error request sent by Tomcat goes to the default processing mechanism.

Extension: 【 can not look 】

Custom handler exception parser, error view parser:

  • Implement HandlerExceptionResolver interface custom processor exception parser; Can be used as the default global exception handling rule

  • Implement ErrorViewResolver custom ErrorViewResolver

Well, that’s all for today’s article, hoping to help those of you who are confused in front of the screen