Common notes: @ ControllerAdvice of spring MVC

1, @ ControllerAdvice

@ ControllerAdvice @ actually, this is a very useful annotation. As the name suggests, this is an enhanced Controller. Using this Controller, three functions can be realized:

1. Global exception handling

2. Global data binding

3. Global data preprocessing

Using these three functions flexibly can help us simplify a lot of work. It should be noted that these functions are provided by spring MVC and can be used directly in Spring Boot. Let's look at them respectively.

 

2, Global exception handling

Use @ ControllerAdvice to implement global exception handling. You only need to define the class and add the annotation. The definition method is as follows:

@ControllerAdvice 
class MyGlobalExceptionHandler {    
    @ExceptionHandler(Exception.class)    
    public ModelAndView customException(Exception e) {        
        ModelAndView mv = new ModelAndView();        
        mv.addObject("message", e.getMessage());                                     
        mv.setViewName("myerror");        
        return mv;   
 }
}    

 

In this class, multiple methods can be defined. Different methods deal with different exceptions, such as methods that deal with null pointers and methods that deal with array out of bounds, You can also handle all exception information in one method directly like the above code.

The @ ExceptionHandler annotation is used to indicate the exception handling type, that is, if NullpointerException is specified here, the array out of bounds exception will not be entered into this method.

 

3, Global data binding

The global data binding function can be used to perform some initialization data operations. We can define some public data in the class annotated with @ ControllerAdvice, so that these data can be accessed in each Controller interface.

To use this procedure, first define the global data as follows:

@ControllerAdvice 
class MyGlobalExceptionHandler {    
  @ModelAttribute(name = "md")    
  public Map<String,Object> mydata() {        
    HashMap<String, Object> map = new HashMap<>();        
    map.put("age", 99);        
    map.put("gender", "male");        
    return map;    
  }
}

 

Use the @ ModelAttribute annotation to mark that the returned data of the method is global data. By default, the key of the global data is the returned variable name, and value is the returned value of the method. Of course, developers can re specify the key through the name attribute of the @ ModelAttribute annotation.

After the definition is completed, the data defined here can be obtained in any Controller interface:

@RestController
class HelloController {    
  @GetMapping("/hello")    
  public String hello(Model model) {        
    Map<String, Object> map = model.asMap();                        
       System.out.println(map);        
    int i = 1 / 0;        
    return "hello controller advice";    
  }
}

 

4, Global data preprocessing

Create two entity classes: Book and Author, as follows:

public class Book {    
    private String name;    
    private Long price;    
    //getter/setter
}
public class Author {    
    private String name;    
    private Integer age;    
    //getter/setter
}

 

At this time, if I define a data addition interface, it is as follows:

@PostMapping("/book")
public void addBook(Book book, Author author) {        
  System.out.println(book);    
  System.out.println(author);
}

 

At this time, the addition operation will have problems, because both entity classes have a name attribute, which cannot be distinguished when passed from the front end. At this time, this problem can be solved through the global data preprocessing of @ ControllerAdvice.

The solution steps are as follows:

1. Alias the variables in the interface

@PostMapping("/book")
public void addBook(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author) {    
  System.out.println(book);    
  System.out.println(author);
}

 

2. Preprocess the request data and add the following code to the class marked @ ControllerAdvice:

@InitBinder("b")
public void b(WebDataBinder binder) {    
    binder.setFieldDefaultPrefix("b.");
}
@InitBinder("a")
public void a(WebDataBinder binder) {    
    binder.setFieldDefaultPrefix("a.");
}

 

The @ InitBinder("b") annotation indicates that the method is used to handle Book and related parameters. In the method, add a b prefix to the parameters, that is, the request parameters must have a b prefix.

3. Send the request. By adding different prefixes to the parameters of different objects, the parameters can be distinguished

  

 

The Class defined by ControllerAdvice has a scope. By default, when no parameters are specified, its scope is all ranges. ControllerAdvice provides some parameters that can narrow its processing range.

value: Array type, used to specify the base package that can be used, that is, the Controller And its sub packages Controller work.
basePackages: Array type, equivalent to value. 
basePackageClasses: Array type. At this time, the base package will be in the specified format Class The package in which it is located shall prevail.
assignableTypes: Array type, used to specify the specific Controller Type, which can be a common interface or parent class, etc.
annotations: Array type, used to specify Class With the specified annotation on Controller. 

  

 

Keywords: Spring MVC

Added by dc_jt on Tue, 04 Jan 2022 19:21:07 +0200