SpringMVC-Three usage scenarios annotated with @ControllerAdvice

@ControllerAdvice, many beginners may not have heard of this annotation. In fact, 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

Flexible use of these three functions can help us simplify a lot of work. It should be noted that this is a function provided by Spring MVC and can be used directly in Spring Boot. Let's look at them separately below.

 

Global exception handling

Use @ControllerAdvice to implement global exception handling, only need to define the class, add the annotation to define the following way:

@ControllerAdvice
public 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, you can define multiple methods, different methods to deal with different exceptions, such as a method that specifically deals with null pointers, a method that deals specifically with array out-of-bounds ..., or it can be handled directly in the same way as the above code All abnormal information.

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

 

Global data binding

The global data binding function can be used to do some initial data operations. We can define some public data in the class with the @ControllerAdvice annotation, so that in each Controller interface, you can access the data that caused it .

To use the steps, first define the global data as follows:

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

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

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

@RestController
public 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";
    }
}

 

Global data preprocessing

Consider that I have two entity classes, Book and Author, which are defined 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 point, if I define a data addition interface, as follows:

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

At this time, the add operation will be problematic, because both entity classes have a name attribute that cannot be distinguished when passed from the front end. At this time, the global data preprocessing by @ControllerAdvice can solve this problem

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
Add the following code to the class marked by @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 this method is used to process Book and related parameters. In the method, add a b prefix to the parameter, that is, the request parameter must have the b prefix.

3. Send the request

When the request is sent, the parameters can be distinguished by adding different prefixes to the parameters of different objects.

Published 952 original articles · praised 1820 · 890,000 views

Guess you like

Origin blog.csdn.net/Dream_Weave/article/details/105373613