Spring Boot2 series of tutorials (xiii) Global Spring Boot Exception Handling

In Spring Boot project, abnormal centrally, you can use Spring in @ControllerAdvice to unify process, you can also define your own exception handling scheme. Spring Boot, there are some default strategy for exception handling, we were run.

By default, Spring Boot anomalies in the page like this:

Prompt us from this exception, you can see it, the reason users see this page because the developer does not provide a clear / error path, if the developer offers / error path, this page will not be displayed, but in Spring Boot provided / error path is actually a last resort, Spring Boot itself in dealing exception is when all the conditions are not met, will go / error path. Then we take a look at Spring Boot, how to customize the error page, on the whole, it can be divided into two types, one is static pages, and a dynamic page.

Static exception page

Custom anomaly static pages, is divided into two, the first is to use the HTTP response code to name the page, such as 404.html, 405.html, 500.html ...., another is to directly define a 4xx. html, 400-499 represents the state of exception pages are displayed, 5xx.html display indicates the state of exception pages 500-599.

The default is the classpath:/static/error/definition of the relevant page of the path:

In this case, start the project, if the project requests throws 500 error, this page will automatically show 500.html, 404.html will show the occurrence of 404 pages. If an abnormal display page exists both 5xx.html, there 500.html, this time, 500 exception occurs, the priority show 500.html page.

Dynamic exception page

Dynamic and static way of exception page definitions are basically the same, page templates can be used are jsp, freemarker, thymeleaf. Dynamic exception page, also supports 404.html or 4xx.html, but in general, due to the abnormal dynamic page exception details can be displayed directly, so there is no need to enumerate one by one mistake, defined directly 4xx.html (used here thymeleaf template ) or 5xx.html can be.

Note that the dynamic page template does not require developers to define their own controller, direct-defined exception pages can, Spring Boot comes with an exception handler will automatically find the exception page.

Page is defined as follows:

Page reads as follows:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>5xx</h1>
<table border="1">
    <tr>
        <td>path</td>
        <td th:text="${path}"></td>
    </tr>
    <tr>
        <td>error</td>
        <td th:text="${error}"></td>
    </tr>
    <tr>
        <td>message</td>
        <td th:text="${message}"></td>
    </tr>
    <tr>
        <td>timestamp</td>
        <td th:text="${timestamp}"></td>
    </tr>
    <tr>
        <td>status</td>
        <td th:text="${status}"></td>
    </tr>
</table>
</body>
</html>

By default, the complete exception message is this 5, showing the effect is as follows:

If the dynamic pages and static pages also defines exception handling page, for example classpath:/static/error/404.html, and classpath:/templates/error/404.htmlthere at the same time, the default use dynamic pages. That is the way to find a complete error page should look like this:

500 error occurred -> Find dynamic 500.html page -> Find static 500.html -> Find dynamic 5xx.html -> Find static 5xx.html.

Custom anomaly data

By default, the Spring Boot, all the above is actually abnormal data out of the display data 5, in which five data definition org.springframework.boot.web.reactive.error.DefaultErrorAttributesclass defined in particular getErrorAttributesways:

@Override
public Map<String, Object> getErrorAttributes(ServerRequest request,
                boolean includeStackTrace) {
        Map<String, Object> errorAttributes = new LinkedHashMap<>();
        errorAttributes.put("timestamp", new Date());
        errorAttributes.put("path", request.path());
        Throwable error = getError(request);
        HttpStatus errorStatus = determineHttpStatus(error);
        errorAttributes.put("status", errorStatus.value());
        errorAttributes.put("error", errorStatus.getReasonPhrase());
        errorAttributes.put("message", determineMessage(error));
        handleException(errorAttributes, determineException(error), includeStackTrace);
        return errorAttributes;
}

DefaultErrorAttributes class itself is defined in org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration abnormal auto-configuration class, if the developer does not provide its own instance of a ErrorAttributes, then Spring Boot will automatically provide a ErrorAttributes of example, is DefaultErrorAttributes.

Based on this, the developers customize ErrorAttributes in two ways:

  1. Direct interface to achieve ErrorAttributes
  2. Inheritance DefaultErrorAttributes (recommended), because DefaultErrorAttributes the treatment of the abnormal data has been completed, developers can directly use.

Defined as follows:

@Component
public class MyErrorAttributes  extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
        if ((Integer)map.get("status") == 500) {
            map.put("message", "服务器内部错误!");
        }
        return map;
    }
}

Defined ErrorAttributes must be registered as a Bean, so, Spring Boot will not use the default DefaultErrorAttributes, and operating results as shown below:

Custom exception view

The default view is the previously mentioned abnormal static or dynamic page, this also may be customized, first, the default view abnormal loading logic errorHtml method org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController class, this method is used to return data + exception page, there is another error method, which returns an exception to the data (if ajax request, the method is triggered).

@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView errorHtml(HttpServletRequest request,
                HttpServletResponse response) {
        HttpStatus status = getStatus(request);
        Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
                        request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = resolveErrorView(request, response, status, model);
        return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
}

In this method, the first will go to get by getErrorAttributes outliers (actually calls the method to getErrorAttributes instance ErrorAttributes's), and then call resolveErrorView to create a ModelAndView, if this creation fails, the user will see the default error tips page.

Under normal circumstances, resolveErrorView method will come resolveErrorView method DefaultErrorViewResolver class:

@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status,
                Map<String, Object> model) {
        ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
        if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
                modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
        }
        return modelAndView;
}

Here, the first abnormal response code name as the view were to find dynamic pages and static pages, if not found, then again with 4xx or 5xx name as the view were to go look for dynamic or static pages.

After To custom exception view resolution, it is also very easy, because the DefaultErrorViewResolver are examples provided in ErrorMvcAutoConfiguration class that developers do not provide instance, will use the default DefaultErrorViewResolver, developers provide their own ErrorViewResolver example, the default configuration it will fail, therefore, custom exception view, just to provide an example of a ErrorViewResolver:

@Component
public class MyErrorViewResolver extends DefaultErrorViewResolver {
    public MyErrorViewResolver(ApplicationContext applicationContext, ResourceProperties resourceProperties) {
        super(applicationContext, resourceProperties);
    }
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        return new ModelAndView("/aaa/123", model);
    }
}

In fact, the developer can define where abnormal data (model directly in a redefined resolveErrorView method, the model data copy and modify the parameters in the past, attention to the type of model parameters UnmodifiableMap, i.e. not directly modified), and no custom MyErrorAttributes. Once defined, view 123 provides a named, as shown below:

After so, even if an error trying to define success.

to sum up

In fact, it can also be custom exception controller BasicErrorController, but Song Ge think this is too go to war, and no need, in front of several ways have been developed to meet most of our needs. If the front and rear ends of the splitter architecture, exception handling, there are other treatment options, the Song Ge and after we talk.

Public concern number [south] a little rain, focused on Spring Boot + Micro service and front and rear ends of separation full stack technology, video tutorials on a regular basis to share concerns reply after Java, Java dry Song Ge receive carefully prepared for you!

Guess you like

Origin www.cnblogs.com/lenve/p/11702806.html