@ControllerAdvice
和 @RestControllerAdvice
都是Spring框架提供的注解,用于创建全局的异常处理器
- @ControllerAdvice:
@ControllerAdvice
注解是Spring 3.2中引入的,用于处理整个Spring MVC应用程序中的异常。- 它通常与
@ExceptionHandler
注解一起使用,以定义全局的异常处理方法。 @ControllerAdvice
注解可以包含对响应体进行操作的方法,这些方法可以返回ModelAndView
或者直接写入响应体(例如使用HttpServletResponse
)。- 如果返回的是对象,那么默认情况下,这个对象会被视图解析器处理,如果没有视图解析器,那么返回的对象会被转换为JSON或者XML等格式,这取决于请求头中的
Accept
类型。
- @RestControllerAdvice:
@RestControllerAdvice
是@ControllerAdvice
的一个特殊版本,它结合了@ControllerAdvice
和@ResponseBody
的功能。- 当使用
@RestControllerAdvice
注解时,任何使用@ExceptionHandler
、@InitBinder
或@ModelAttribute
注解的方法都会返回数据而不是视图。 - 这意味着返回的对象会被直接写入HTTP响应体中,通常是以JSON格式,这是因为在
@RestControllerAdvice
中隐含了@ResponseBody
的功能。
简而言之,如果你需要返回一个视图或者进行复杂的响应处理,你应该使用 @ControllerAdvice
。如果你希望直接返回JSON或XML等格式的数据,那么 @RestControllerAdvice
是更好的选择。
下面通过两个简单的示例来展示@ControllerAdvice
和@RestControllerAdvice
的区别。
首先,假设我们有一个全局异常类GlobalExceptionHandler
。
使用 @ControllerAdvice
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理特定异常
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception e) {
ModelAndView modelAndView = new ModelAndView("error"); // 指向一个错误页面
modelAndView.addObject("errorMessage", "An error occurred: " + e.getMessage());
return modelAndView;
}
}
在这个例子中,当抛出异常时,handleException
方法会被调用。它返回一个ModelAndView
对象,这个对象指向一个名为error
的视图(通常是HTML页面)。Spring MVC会使用视图解析器来渲染这个视图,并将错误信息作为模型数据传递给它。
使用 @RestControllerAdvice
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理特定异常
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("An error occurred: " + e.getMessage());
}
}
在这个例子中,当抛出异常时,handleException
方法同样会被调用。但是,它返回的是一个ResponseEntity<String>
对象,这意味着返回的数据将被直接写入HTTP响应体中,并且不需要视图解析器。通常,返回的数据会以JSON格式发送给客户端。
区别总结
@ControllerAdvice
返回ModelAndView
,适用于需要渲染视图的场景。@RestControllerAdvice
返回ResponseEntity
或其他对象,适用于需要直接返回数据的RESTful API场景。
以下是模拟的请求处理流程来展示这两个注解的不同表现:
// 模拟一个使用@ControllerAdvice的请求
@RequestMapping("/errorView")
public String showErrorView() {
throw new RuntimeException("View Error Occurred!");
}
// 模拟一个使用@RestControllerAdvice的请求
@RequestMapping("/errorData")
public String showErrorData() {
throw new RuntimeException("Data Error Occurred!");
}
如果客户端访问/errorView
,将会看到由error
视图渲染的HTML页面。如果客户端访问/errorData
,将会接收到一个包含错误信息的JSON响应。