编程知识 cdmana.com

Springboot episode 7: exception handling and jsr303 verification

SpringBoot Episode 7 : Exception handling and integration JSR303 check (2020 Up to date and easy to understand )

One .SpringBoot Global exception

   Let's talk about what a global exception handler is ? 

   The global exception processor is to process the exception of the whole system automatically , Programmers can do without writing try... catch.SpringBoot Built in default global exception handler .

  Spring Boot There is a default mechanism for exception handling ,BasicErrorController Handle default exception forwarding or this error request  : When an exception occurs in the application , When accessing the application interface from the browser address bar ,SpringBoot Will get the data in the request header , If In the request header accept contain text/html Information , When an exception occurs ,Spring Boot Will pass ModelAndView Model Object to load exception information , and With HTML The format returns ; conversely , In the request header accept It doesn't contain text/html when ,Spring Boot be With JSON Return exception information in the format of .

for example : Access to an unknown interface resource ( Or background interface definition 10/0 Error of , Responsive HTML give the result as follows )

for example : utilize Postman Testing tools , Access to unknown resources test :( You can try other plug-in tools : Use Chrome plug-in unit Restlet Client

1. Global exception handling mechanism source code parsing

 BasicErrorController The source code is intercepted as follows :

@RequestMapping("${server.error.path:${error.path:/error}}") Requested  The address of the exception page is /error/ The following resources 

  When there is no custom exception page , By default, the build is executed according to the source code below HTML or JSON Respond to the front desk .

 1 @Controller
 2 @RequestMapping("${server.error.path:${error.path:/error}}")
 3 public class BasicErrorController extends AbstractErrorController {
 4     /**
 5      *  Error message processor method errorHtml, Set request header Accpet Value type , If you include text/html, That is to execute the method 
 6      * @param request  Request object 
 7      * @param response     The response object 
 8      * @return
 9      *  MediaType.TEXT_HTML_VALUE The actual value of is a string “text/html”
10      */
11     @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
12     public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
13         //  Get status code 
14         HttpStatus status = getStatus(request);
15         Map<String, Object> model = Collections
16                 .unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
17         //  Response status code description 
18         response.setStatus(status.value());
19         //  Create a view model object 
20         ModelAndView modelAndView = resolveErrorView(request, response, status, model);
21         return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
22     }
23 
24     /**
25      *  Error message processor method error Method , Set request header Accpet Value type , That is, it does not contain text/html Execute the method 
26      * @param request  Request object 
27      * @param response     The response object 
28      */
29     @RequestMapping
30     public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
31         HttpStatus status = getStatus(request);
32         if (status == HttpStatus.NO_CONTENT) {
33             return new ResponseEntity<>(status);
34         }
35         Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
36         return new ResponseEntity<>(body, status);
37     }
38     
39 }

We can Custom friendly exception page . But it has to be in resources /error/ Under the table of contents , The default address of the resource directory is optional
 src/main/resources/static/,src/main/resources/resources/,src/main/resources/public/,src/main/templates/

explain : The first three are static resource directories , Page us Using a template engine , So if you need to customize the error page , You need to Put it in src/main/templates/error Under the table of contents ( Of course, all the premises are , No change to the default configuration ,SpringBoot By default, the error page is loaded ), And The name of the error page must be in the form of status code .SpringBoot Default error view parser DefaultErrorViewResolver The source code analysis is as follows :

 1 public class DefaultErrorViewResolver implements ErrorViewResolver, Ordered {
 2 
 3     private static final Map<Series, String> SERIES_VIEWS;
 4     
 5     //  Static initialization error state type :4xx   or   5xx
 6     static {
 7         Map<Series, String> views = new EnumMap<>(Series.class);
 8         views.put(Series.CLIENT_ERROR, "4xx");
 9         views.put(Series.SERVER_ERROR, "5xx");
10         SERIES_VIEWS = Collections.unmodifiableMap(views);
11     }
12         
13 
14     //  Parse the error view 
15     @Override
16     public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
17         //  Get the error status code, for example :404, Call the method as a string resolve( analytic method )
18         ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
19         if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
20             modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
21         }
22         return modelAndView;
23     }
24     
25     //  Analytical processing method 
26     private ModelAndView resolve(String viewName, Map<String, Object> model) {
27         //  Splicing error view access prefix :error/500
28         String errorViewName = "error/" + viewName;
29         TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName,
30                 this.applicationContext);
31         if (provider != null) {
32             return new ModelAndView(errorViewName, model);
33         }
34         //  Call resolution resource : Pass in error/500
35         return resolveResource(errorViewName, model);
36     }
37 
38     //  Parsing resources 
39     private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
40         for (String location : this.resourceProperties.getStaticLocations()) {
41             try {
42                 //  Access to information analysis 
43                 Resource resource = this.applicationContext.getResource(location);
44                 //  Create resolution file as :error/500.html
45                 resource = resource.createRelative(viewName + ".html");
46                 if (resource.exists()) {
47                     return new ModelAndView(new HtmlResourceView(resource), model);
48                 }
49             }
50             catch (Exception ex) {
51             }
52         }
53         return null;
54     }
55 }

    About the integration of template engine , Reference resources Episode 9 : Integrate JSP And template engine

 2. Custom exception page

  1. stay src/main/templates/error Create a new error page in the directory : for example :404.html

  2. Test access .

 1 <!DOCTYPE html>
 2 <html  xmlns:th="http://www.thymeleaf.org">  <!-- Thymeleaf Template constraints  -->
 3 <head>
 4 <meta charset="UTF-8">
 5 <title>Insert title here</title>
 6 </head>
 7 <body>
 8      Customize 404 Friendly error page !<br>
 9      I'm sorry , The data you access has been stolen by aliens ……
10 </body>
11 </html>

 

 

 3. Custom exception information

   In addition to being able to customize friendly exception pages (HTML) Outside , We can also customize exception handling information , Change the default client provider to generate exception information .  

   Due to the separation of the front end and the back end in the work , So there is almost no need to go back directly to the resource page , Generally, it returns a fixed response format JSON, Such as respCoderespMsgdata etc. , The front end judges respCode The value of business judgment , Pop up window or jump page .

  1. Write a custom exception class , Encapsulate exception information ( Easy JSON transformation )
     1 @Data
     2 @NoArgsConstructor
     3 @AllArgsConstructor
     4 public class ExceptionResponseResult{
     5     @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")   //  Date formatting 
     6     private Date timestamp;//  Time 
     7     private int respCode;//  Status code 
     8     private String respMsg;//  Description information for users to see 
     9     private String message;//  Actual error exception information 
    10     private String exceptionName;//  Actual error exception name 
    11     private String path;// URI
    12     private Object data;//  data 
    13 }
  2. Write the global exception handler
    a, Write a global exception handler class
    b, Add annotations to the class @ControllerAdvice
      @ControllerAdvice: effect : For all controllers , By @RequestMapping How to annotate , enhanced ( It can also be used directly @RestControllerAdvice)
    c, Custom exception handling methods , And use annotations @ExceptionHandler(Throwable.class),@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR),@ResponseBody
      @ExceptionHandler(Throwable.class): Exception handler comments , Usually cooperate @ControllerAdvice Annotations use . Role is : Implement interception on specified or satisfied exception types
      @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR): Used to specify the response status code ,HttpStatus yes Spring A built-in state code enumeration class , The detailed status code and description are set .
      @ResponseBody: effect : Turn the result of the response to JSON Information . If used @RestControllerAdvice The method does not need to use @ResponseBody annotation
     1 // @ControllerAdvice
     2 @RestControllerAdvice    //  Controller class enhancement : It can be done to Controller All use @RequestMapping Annotation methods enhance 
     3 public class GlobalExceptionHandler {
     4 
     5     //  This annotation is an exception handler annotation , Exception types can be specified , How to execute annotation annotation ( Whenever a specified exception occurs, it will be intercepted )
     6     @ExceptionHandler(Throwable.class)    
     7     //  This annotation is used to specify the... Of the response page after the exception handling method is executed HTTP Status code ,HttpStatus yes Spring A built-in state code enumeration class , A detailed state code and description are defined , What you're getting right now is 500
     8     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)//  Respond to 500
     9     public Object exceptonResponse(Exception ex,HttpServletRequest request) {
    10         ExceptionResponseResult resultError = new ExceptionResponseResult();
    11         resultError.setTimestamp(new Date());//  Set the time when the exception occurs 
    12         resultError.setRespCode(0);//  You can choose a custom enumeration class , Define the status code 
    13         resultError.setRespMsg(" Server refresh exception , Please later ...");//  Abnormal information that users see 
    14         resultError.setMessage(ex.getMessage());//  The actual abnormal information 
    15         resultError.setExceptionName(ex.getClass().getName());//  The name of the actual exception 
    16         resultError.setPath(request.getRequestURI());//  abnormal RUI
    17         return resultError;
    18     }
    19     
    20 }
  3. Write controller Controller Define background error
     1 @Controller
     2 public class HtmlController {
     3 
     4     @RequestMapping("/indexHtml")
     5     public String indexHtml(Model model) {
     6         model.addAttribute("url","XSGE Personal website :http://www.xsge123.com");
     7         System.out.println(" test "+(10/0));
     8         return "indexHtml";
     9     }
    10 }
  4. Use Postman Test access

     

      Page access test results : Normal response , But the status code is 500

     
  5. Exception handling optimization
    In the exception handler method , Determine the type of exception , Define more detailed exception response content .
     1 //  This annotation is an exception handler annotation , Exception types can be specified , How to execute annotation annotation ( Whenever a specified exception occurs, it will be intercepted )
     2 @ExceptionHandler(Throwable.class)    
     3 //  This annotation is used to specify the... Of the response page after the exception handling method is executed HTTP Status code ,HttpStatus yes Spring A built-in state code enumeration class , A detailed state code and description are defined , What you're getting right now is 500
     4 @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)//  Respond to 500
     5 public Object exceptonResponse(Exception ex,HttpServletRequest request) {
     6     ExceptionResponseResult resultError = new ExceptionResponseResult();
     7     if (ex instanceof NullPointerException) {//  If the exception caught is a null pointer exception 
     8         // **** Set exception information *****
     9     } else if (ex instanceof ArithmeticException) {
    10         // **** Set exception information *****
    11     }// *****
    12     return resultError;
    13 }

Two .JSR-303 data verification

   At any time , When you are dealing with the business logic of an application , Data validation is something you have to consider and face . Then only front-end page verification can guarantee security ? Children are still young , There are a lot of basic front-end attack technologies on the Internet , therefore , Page data validation is not enough .JSR yes Java Specification Requests Abbreviation , intend Java Specification proposal . It's pointing JCP(Java Community Process) A formal request to add a standardized technical specification .

  JSR-303 yes JAVA EE 6 A subspecification of , be called Bean Validation,Hibernate Validator yes Bean Validation Reference implementation of . Hibernate Validator Provides JSR 303 All built-in... In the specification constraint( constraint ) The implementation of the , In addition, there are some additional constraint( constraint ).( Be careful : This implementation and Hibernate ORM It doesn't matter ).

   Verification rules and usage : Bloggers focus on SSM Integrated data validation !!!( At present, there is no time for writing , Coming soon !) You can't wait to see Githup Official website , see documentation .

版权声明
本文为[Net weight 21g]所创,转载请带上原文链接,感谢

Scroll to Top