6 SpringBoot Web development - exception handling

Posted by dape2009 on Thu, 13 Jan 2022 14:05:37 +0100

6.1 default rules

1. By default, Spring Boot provides / error mapping to handle all errors.

2. For the machine client, it will generate a JSON response, which contains the details of error, HTTP status and exception messages;

For the browser client, respond to a "whitelabel" error view and render the same data in HTML format.

3. To customize it, add a View and resolve it to error.

4. To completely replace the default behavior, you can implement ErrorController and register the Bean definition of this type, or add a component of ErrorAttributes type to replace its content with the existing mechanism.

5. 4xx and 5xx pages under error / will be automatically parsed.

6.2 custom error handling logic

1) , custom error page

error/404.html error/5xx.html

If there is an accurate error status code, the page will match accurately. If not, find 4xx html; If none, it triggers a white page;

Trigger point:

@Controller
public class TableController {

    //Trigger 400 Bad Request
    @GetMapping("/basic_table")
    public String basic_table(Model model, @RequestParam("a")int a){
        //Analog data
        List<User> users
                = Arrays.asList(new User("zhangsan", "123456"),
                new User("lisi", "123444"),
                new User("haha", "aaaaa"),
                new User("hehe ", "aaddd"));

        model.addAttribute("users",users);
        return "table/basic_table";
    }
}

2) , @ ControllerAdvice+@ExceptionHandler global exception handler

The underlying layer is supported by ExceptionHandlerExceptionResolver

@Slf4j
@ControllerAdvice  //Enhanced controller
public class GlobalExceptionhandler {
	
    //Define a processor dedicated to handling "mathematical exceptions"
    @ExceptionHandler({ArithmeticException.class})
    public String handlerArithException(Exception e){
        log.error("Exception:{}",e.getMessage());
        return "login";
    }

}

Trigger point:

@Controller
public class TableController {

    @GetMapping("/basic_table")
    public String basic_table(Model model){
        //Analog data
        List<User> users
                = Arrays.asList(new User("zhangsan", "123456"),
                new User("lisi", "123444"),
                new User("haha", "aaaaa"),
                new User("hehe ", "aaddd"));
		
        //Trigger mathematical exception
        int i = 10/0;
        model.addAttribute("users",users);
        return "table/basic_table";
    }
}

3) , @ ResponseStatus + custom exception

The underlying layer is supported by * * ResponseStatusExceptionResolver**

Call response at the bottom of the information annotated by responsestatus sendError(statusCode, resolvedReason);

/ error sent by tomcat

//Custom exception binding response error status code
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public class CustomException extends RuntimeException {
    public CustomException() {
        super();
    }

    public CustomException(String message) {
        super(message);
    }
}

Trigger point:

@Controller
public class TableController {

    @GetMapping("/basic_table")
    public String basic_table(Model model){
        //Analog data
        List<User> users
                = Arrays.asList(new User("zhangsan", "123456"),
                new User("lisi", "123444"),
                new User("haha", "aaaaa"),
                new User("hehe ", "aaddd"));
		
        //Trigger custom exception
        if(users.size()>3){
            throw new CustomException("Too many values");
        }
        model.addAttribute("users",users);
        return "table/basic_table";
    }
}

4) . Spring underlying exceptions, such as parameter type conversion exceptions

The bottom layer is supported by DefaultHandlerExceptionResolver to handle the exceptions at the bottom of the framework (for example, 400 missing request parameters)

response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());

The request ends immediately. The / error sent by tomcat is processed by the BasicErrorController.

tomcat native error page:

5) . customize the implementation of HandlerExceptionResolver to handle exceptions

It can be used as the default global exception handling rule

//Set the priority. The smaller the number, the higher the priority
@Order(value = Ordered.HIGHEST_PRECEDENCE)
@Component
public class CustomHandlerExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         Object handler,
                                         Exception ex) {
        try {
            response.sendError(422,"Custom error");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ModelAndView();
    }
}

6) . ErrorViewResolver implements custom exception handling

1. Just execute response Senderror(), the error request will be transferred to the controller;

2. No one can handle the exception. The bottom layer of tomcat is also a response Senderror(), the error request will be transferred to the controller;

3. The page address to be jumped by the basicerrorcontroller is parsed by the ErrorViewResolver view parser;

6.3 [source code analysis] automatic configuration principle of exception handling

  • ErrorMvcAutoConfiguration automatically configures exception handling rules

    • Components in container: Type: defaulterrorattributes - > ID: errorAttributes
      • public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver
      • DefaultErrorAttributes: defines what data can be included in the error page.

    • **Component in container: Type: * * basicErrorController -- > ID: basicErrorController (json + white page adaptation response)
      • Handle the request for the default / error path; The page responds to new ModelAndView("error", model);
      • There is a component in the container. View - > ID is error; (response to default error page)
      • Put the component BeanNameViewResolver (View resolver) in the container; Use the returned View name as the id of the component to find the View object in the container.
    • **Component in container: * * type: * * defaulterrorviewresolver - > ID: * * conventionErrorViewResolver
      • If an error occurs, the HTTP status code will be used as the view page address (viewName) to find the real page
      • error/404,5xx.html

If you want to return to the page; You will find the error view [StaticView]. (the default is a white page)

6.4 [source code analysis] exception handling steps and processes

1. Execute the target method. Any exception during the operation of the target method will be caught and mark the end of the current request; And use dispatchException

2. Enter the view parsing process (page rendering)

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

3,mv = processHandlerException; Handle the exception occurred in handler, and return ModelAndView after processing;

  • 1. Traverse all * * handlerExceptionResolvers to see who can handle the current exception [* * HandlerExceptionResolver handler exception resolver]

  • -2. The default exception parser of the system;

    • 1. DefaultErrorAttributes handles exceptions first. Save the exception information to the rrequest field and return null;
    • 2. By default, no one can handle exceptions, so exceptions will be thrown
      • 1. If no one can handle it, the bottom layer will send the / error request. Will be handled by the underlying BasicErrorController
      • 2. Parse error view; Traverse all errorviewresolvers to see who can resolve them.

    -

      • 3. The default DefaultErrorViewResolver uses the response status code as the address of the error page, error / 500 html
      • 4. The template engine finally responds to this page error / 500 html

Topics: Java Spring Boot