Three usage scenarios of ControllerAdvice annotation in spring MVC

Three usage scenarios of @ ControllerAdvice annotation in spring MVC!
@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:

Global exception handling
 Global data binding
 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.
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
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, 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 deal with 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.
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
public 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 a global data. By default, the key of the global data is the returned variable name and the 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
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 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 request data
Add the following code to the class marked with @ 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 request

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

summary

These are some simple usages of @ ControllerAdvice introduced by SongGe to you. These points can be used not only in traditional SSM projects, but also in Spring Boot + Spring Cloud microservices. Welcome to discuss your questions together.

Reprinted from: https://www.cnblogs.com/lenve/p/10748453.html

Tags: Java Spring Boot Spring MVC

Posted on Mon, 29 Nov 2021 02:51:25 -0500 by andylai