编程知识 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 anomalies

   Let's talk about what global exception processors are ? 

   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 Ask for  : When an exception occurs in the application , When accessing the application interface from the browser address column ,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 take HTML The format returns ; conversely , Ask for accept It doesn't contain text/html When ,Spring Boot Then take JSON Return exception information in the format of .

for example : Accessing an unknown interface resource ( Or background interface definition 10/0 Error of , Responsive HTML The results are as follows )

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

1. Global exception handling mechanism source code parsing

 BasicErrorController The source code is extracted as follows :

@RequestMapping("${server.error.path:${error.path:/error}}") The address of the exception page requested 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 The front desk responds to .

 1 @Controller
 2 @RequestMapping("${server.error.path:${error.path:/error}}")
 3 public class BasicErrorController extends AbstractErrorController {
 4     /**
 5      *  Error information processor method errorHtml, Set the request header Accpet Value type , If you include text/html, That is to execute the method 
 6      * @param request  Request object 
 7      * @param response     Respond to objects 
 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 information processor method error Method , Set the request header Accpet Value type , That is, it does not contain text/html Execute the method 
26      * @param request  Request object 
27      * @param response     Respond to objects 
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 customize the friendly exception page . But it has to be in resources /error/ Under the catalogue , 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 , We use a template engine , So if you need to customize the error page , Then you need to put it in src/main/templates/error Under the catalogue ( Of course, all the premises are , No changes to the default configuration ,SpringBoot Default loaded error page ), And the name of the error page must be in the form of status code .SpringBoot Default error view parser DefaultErrorViewResolver The original code is parsed 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 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, Turn to string call method 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 resources : Incoming 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                 //  Set up the parsing 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 , Refer to 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 information you visited was 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 , Exception information generated by changing the default client access interface .  

   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 custom exception class , Encapsulate exception information ( So JSON Conversion )
     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 
     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;//  Information 
    13 }
  2. Write a 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 , Enhance ( 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 : Implements interception on the specified or satisfied exception type
      @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 Notes
     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 , You can handle the specified exception type , 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 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 wait a moment ...");//  Abnormal information seen by the user 
    14         resultError.setMessage(ex.getMessage());//  The actual exception 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 the 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 exception type , Define more detailed exception response content .
     1 //  This annotation is an exception handler annotation , You can handle the specified exception type , 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 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 captured exception is an air control indicator 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're 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 , It's not enough to just check the page data .JSR yes Java Specification Requests The abbreviation for , intend Java Regulatory proposals . It's pointing JCP(Java Community Process) A formal request for the addition of a standardized technical specification .

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

   Verification rules and usage : Follow bloggers SSM Verification of integrated data !!!( At present, there is no time for writing , Please look forward to !) You can't wait to see Githup Official website , Look at the expository text

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

Scroll to Top