@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, you can achieve three functions:

  1. Global exception handling
  2. Global data binding
  3. Global data preprocessing

Flexible use of these three functions can help simplify a lot of work. It is important to note that these functions are provided by SpringMVC and can be used directly in Spring Boot.

Global exception handling

To implement global exception handling using @controllerAdvice, you just need to define the class. Add this annotation to define it 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");
        returnmv; }}Copy the code

In this class, you can define multiple methods, with different methods handling different exceptions, such as a method for handling null Pointers, a method for handling arrays out of bounds… Or you can handle all exception information in a single method just like the code above.

The @ExceptionHandler annotation is used to specify the type of exception to be handled, that is, if NullpointerException is specified, the array out-of-bounds exception will not enter the method.

Global data binding

Global data binding can be used to do some initial data operations. We can define some common data in a class annotated with the @ControllerAdvice annotation so that the resulting data can be accessed in every Controller interface.

Using steps, first define global data as follows:

@ControllerAdvice
public class MyGlobalExceptionHandler {
    @ModelAttribute(name = "md")
    public Map<String,Object> mydata(a) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("age".99);
        map.put("gender"."Male");
        returnmap; }}Copy the code

Use the @modelAttribute annotation to indicate that the data returned by this method is global data. By default, the key of this global data is the name of the returned variable and the value is the value returned by the method. Of course, the developer can respecify the key via the @ModelAttribute name attribute.

Once defined, the data defined here is available 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"; }}Copy the code

Global data preprocessing

Consider that I have two entity classes, Book and Author, 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
}
Copy the code

At this point, if I define a data add interface, it looks like this:

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

At this point, the add operation becomes problematic because both entity classes have a name attribute that is indistinguishable when passed from the front end. At this point, global data preprocessing via @ControllerAdvice solves this problem

The solution steps are as follows:

1. Alias variables on the interface

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

Add the following code to the @controllerAdvice class:

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

The @initBinder (“b”) annotation indicates that the method is used to process parameters related to Book and Book. In the method, the parameters are prefixed with a B prefix, i.e. the request parameters are prefixed with a B prefix.

3. Send the request

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

conclusion

These are a few simple uses of @ControllerAdvice that Songo introduced to us. These points can be used in both traditional SSM projects and Spring Boot + Spring Cloud microservices.

Pay attention to the public account [Jiangnan little Rain], focus on Spring Boot+ micro service and front and back end separation and other full stack technology, regular video tutorial sharing, after attention to reply to Java, get Songko for you carefully prepared Java dry goods!