SpringBoot -- error handling mechanism

Posted by AndyMoore on Sat, 01 Jan 2022 05:01:09 +0100

SpringBoot's default error handling mechanism

Browser access, return an error page by default


PostManHttp requests the simulation tool. The software download link is as follows

PostMan download link

If it is another client, it will respond to a JSON data by default


Principle ---- automatic configuration of SpirngMVC error handling

You can refer to ErrorMvcAutoConfiguration; Automatic configuration of error handling;

The following components were added to the container:

1,DefaultErrorAttributes:

2. BasicErrorController: handles default / error requests


3. ErrorPageCustomizer: error page customization

4,DefaultErrorViewResolver:

Steps:

1. 4xx or 5xx errors occur in the system; ErrorPageCustomizer will take effect (customize the error response rules); Will come to / error

Request: it will be processed by BasicErrorController;

Response page: which page to go to is parsed by DefaultErrorViewResolver;

How to customize error response

1. Customize the error response page

1. How to customize wrong json data

Custom exception:

public class UserNotFoundException extends RuntimeException
{
    public UserNotFoundException()
    {
        super("user does not exist");//Error display
    }
}


How to customize wrong JSON data

@ControllerAdvice//Class that handles global exceptions
public class exception
{
//The browser client returns JSON data
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public Map<String,Object> handleException(Exception e){
        Map<String,Object> map = new HashMap<>();
        map.put("code","user.notexist");
        map.put("message",e.getMessage());
        return map;
    }
}

The above writing method has no adaptive effect, that is, the browser returns an error page, and other clients return a JSON data

Adaptive effect: forward to the error request and let the BasicErrorController handle the request

There is no error status code set here. After successful forwarding, the status code is 200, so you can't go to the custom error page analysis process

@ControllerAdvice//Class that handles global exceptions
public class exception
{
    @ExceptionHandler(UserNotFoundException.class)
    public String handleException(Exception e){
        Map<String,Object> map = new HashMap<>();
        map.put("code","user.notexist");
        map.put("message",e.getMessage());
        //Forward to error request
        //BasicErrorController: handles default / error requests
        return "forward:/error";
    }
}

Pass in our own error status code 4xx 5xx, otherwise we will not enter the parsing process of customized error page

@ControllerAdvice//Class that handles global exceptions
public class exception
{
    @ExceptionHandler(UserNotFoundException.class)
    public String handleException(Exception e, HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        //Pass in our own error status code 4xx 5xx, otherwise we will not enter the parsing process of customized error page
        /**
         * Integer statusCode = (Integer) request
         .getAttribute("javax.servlet.error.status_code");
         */
        request.setAttribute("javax.servlet.error.status_code",400);
        map.put("code","user.notexist");
        map.put("message",e.getMessage());
        //Forward to error request
        //BasicErrorController: handles default / error requests
        return "forward:/error";
    }
}

Bring out our customized data

After an error occurs, a / error request will be sent and processed by BasicErrorController. The data that can be obtained from the response is obtained by getErrorAttributes (the method specified by AbstractErrorController (ErrorController))

1. Completely write an implementation class of ErrorController [or write a subclass of AbstractErrorController] and put it in the container;

2. The usable data on the page or the usable data returned by json are all through errorattributes Get geterrorattributes;

Defaulterrorattributes. In container getErrorAttributes(); Data processing is performed by default;

Custom errorattributes

Here, springboot is to check whether the above error related classes exist in the container. If not, the default configuration class will be used. Therefore, we can rewrite the above error class and put it into the container to customize the error data and carry it out

//Add our own defined ErrorAttributes to the container
@Component
 class MyErrorAttributes extends DefaultErrorAttributes
{
//The map of the return value is the data that the page and json can get
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
        map.put("company","Dahuyou Group Co., Ltd");
        return map;
    }
}

Final effect: the response is adaptive, and the contents to be returned can be changed by customizing ErrorAttributes

If we put an error message in the request field, it is as follows:


Inherit the DefaultErrorAttributes class and override its method to get the error attribute to get the data in the request field

//Add our own defined ErrorAttributes to the container
@Component
 class MyErrorAttributes extends DefaultErrorAttributes
{
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
        map.put("company","Dahuyou Group Co., Ltd");
        //The data we get from the request field
        Object msg = webRequest.getAttribute("error", 0);
        Object msg1 = webRequest.getAttribute("msg", 0);
        map.put("mistakes",msg);
        map.put("msg",msg1);
        return map;
    }
}