This is the 14th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

The default error handling mechanism for SpringBoot

Default effect:

1), browser, return a default error page

The browser sends the request header:

2) If it is another client, the default response is a JSON data

Principle:

Can consult ErrorMvcAutoConfiguration; Automatic configuration of error handling;

Terrorattributes: Help us share information on the page;

BasicErrorController: Handles default /error requests

3, ErrorPageCustomizer: after the system error comes to the error request for processing; (Error page rules for web.xml registration)

4, DefaultErrorViewResolver:

@Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { ModelAndView modelAndView = resolve(String.valueOf(status), model); if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) { modelAndView = resolve(SERIES_VIEWS.get(status.series()), model); } return modelAndView; } private ModelAndView resolve(String viewName, Map<String, Object> model) { error/404 String errorViewName = "error/" + viewName; / / template engine can parse the page address can use template engine parsing TemplateAvailabilityProvider provider = this. TemplateAvailabilityProviders .getProvider(errorViewName, this.applicationContext); if (provider ! Return new ModelAndView(errorViewName, model); Error /404. HTML return resolveResource(errorViewName, model); }Copy the code

If a 4XX or 5XX error occurs in the system; ErrorPageCustomizer takes effect (custom error response rules); It will come to the /error request; It will be handled by BasicErrorController;

Response page; Which page to go to is resolved by TerrorViewResolver;

Custom error

Why are we going to make a custom error? Didn’t he already give me a false tip?

First of all, as developers, we can understand the error prompt, but as users, they don’t know ah, there may be some problems caused by users inadvertently, users can follow our prompt, correctly continue to use, and it is beautiful, so that users have a better user experience

Secondly, we customize the error, which can help us find the cause of our error more easily

1) With a template engine; Error/status code; [Name the error page as error status code. HTML and put it under the error folder in the template engine folder], the error of this status code will come to the corresponding page;

We can use 4xx and 5xx as error page filenames to match all errors of this type, precision first (looking for precise status code.html is preferred);

Information available to the page;

  • 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) There is no template engine (template engine can not find this error page), static resources folder to find;

Error page: gitee.com/ghllhg/Spri…

3) There is no error page above, which is the default error page of SpringBoot;

The first is an exception class that needs us

Public class UserNotExistException extends RuntimeException{public UserNotExistException() {super(" User does not exist "); }}Copy the code

We create a man-made error

 	@ResponseBody
    @RequestMapping("/hello")
    public String hello(@RequestParam("user") String user){
        if(user.equals("aaa")){
            throw new UserNotExistException();
        }
        return "hello World";
    }
Copy the code

Let’s create a new class and customize our exception return information

Public class MyExceptionHandler {@responseBody @ExceptionHandler(UserNotExistException.class) public Map<String,Object> handleException(Exception e){ Map<String,Object> map = new HashMap<>(10); map.put("code","user.notexist"); map.put("message",e.getMessage()); return map; }}Copy the code

Forward to /error for adaptive response effect processing

	@ExceptionHandler(UserNotExistException.class)
    public String handleException(Exception e){
        Map<String,Object> map = new HashMap<>(10);
        map.put("code","user.notexist");
        map.put("message",e.getMessage());

        return "forward:error";
Copy the code

But this way he’s back to where he was before, and the status code says 200, which is not right

@ControllerAdvice public class MyExceptionHandler { @ExceptionHandler(UserNotExistException.class) public String handleException(Exception e,HttpServletRequest request){ Map<String,Object> map = new HashMap<>(10); request.setAttribute("javax.servlet.error.status_code",400); map.put("code","user.notexist"); map.put("message",e.getMessage()); request.setAttribute("ext",map); return "forward:error"; }}Copy the code

We jump to our error page by setting our own status code

But then our custom messages don’t go back and forth

After an error occurs, you get a /error request, which is handled by the BasicErrorController, The data that can be retrieved in response is obtained by getErrorAttributes (a method defined by AbstractErrorController);

Write an entirely ErrorController implementation class (or subclass AbstractErrorController) and put it in a container.

2, can use the data on a page, or is the json returned with data by errorAttributes. GetErrorAttributes get;

The container DefaultErrorAttributes. GetErrorAttributes (); Performing data processing by default;

Custom ErrorAttributes

@Component public class MyErrorAttributes extends DefaultErrorAttributes { /** * * @param webRequest * @param options * @override public map <String, Object> getErrorAttributes(WebRequest WebRequest, ErrorAttributeOptions options) { Map<String, Object> map = super.getErrorAttributes(webRequest, options); map.put("company","ll"); Map<String, Object> ext = (Map<String, Object>) webrequest.getAttribute ("ext", 0); map.put("ext",ext); return map; }}Copy the code