springmvc中@ControllerAdvice全局处理异常

Scroll Down

1.介绍

@ControllerAdvice是SpringMVC中的一个增强Controller,使用这个 Controller ,可以实现三个方面的功能:

  1. 全局异常处理
  2. 全局数据绑定
  3. 全局数据预处理

2.使用

2.1.全局异常处理

在方法上使用@ExceptionHandler注解,就能全局处理注解内的异常。

@ControllerAdvice
public class MyGlobalExceptionHandler {
    @ResponseBody
    @ExceptionHandler(MyException.class)
    public JsonResult<String> handleException(Exception e) {
        return JsonResult.failed(e.getMessage());
    }
}

2.2.全局数据绑定

在方法上使用@ModelAttribute注解,该方法就会在此Controller中第一个执行。

@ControllerAdvice
public class MyGlobalExceptionHandler {
    @ModelAttribute
    public void initData(HttpServletRequest request) {
        request.setAttribute("hello", "world");
    }
}

在普通Controller中,就可以取到这个属性。

@Controller
@RequestMapping("/")
public class MyController {
    public JsonResult<String> hello(HttpServletRequest request){
        String data = request.getAttribute("hello");
        return JsonResult.success(data);
    }
}

2.3.全局数据预处理

假设有两个实体类Book和Author

@Data
public class Book {
    private String name;
    private Long price;
}

@Data
public class Author {
    private String name;
    private Integer age;
}

在Controller中直接绑定实体,就会出现问题,由于Book和Author中都有属性name,请求参数中的name参数就无法区分到底绑定哪个实体。

@PostMapping("/book")
public void addBook(Book book, Author author) {
    // save
}

这时,可以用@ModelAttribute注解给接口中的变量取别名。

@PostMapping("/book")
public void addBook(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author) {
    // save
}

在@ControllerAdvice 标记的类中,使用@InitBinder注解对数据进行绑定,注解中的值和@ModelAttribute中的别名对应。

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

前端请求时需要将请求参数加上前缀,如b.name, b.price, a.name, a.age,数据就可以被正确绑定。