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