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
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; } }