您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# SpringBoot 中如何使用@ControllerAdvice
## 一、引言
在SpringBoot应用开发中,异常处理和全局数据绑定是每个项目必须面对的问题。传统的`try-catch`方式虽然直接,但会导致大量重复代码。Spring 3.2引入的`@ControllerAdvice`注解,提供了一种优雅的全局解决方案。
本文将深入探讨`@ControllerAdvice`的核心用法,包括:
- 异常处理的集中化管理
- 全局数据预处理
- 模型属性增强
- 结合`@ResponseBody`的REST风格应用
- 实际项目中的最佳实践
## 二、@ControllerAdvice基础概念
### 2.1 注解定义
```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
// 可指定包、类、注解等作用范围
String[] value() default {};
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<?>[] assignableTypes() default {};
Class<? extends Annotation>[] annotations() default {};
}
作用类型 | 对应注解 | 说明 |
---|---|---|
异常处理 | @ExceptionHandler | 捕获控制器抛出的异常 |
数据绑定 | @InitBinder | 预处理请求参数 |
模型增强 | @ModelAttribute | 向所有控制器添加公共属性 |
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(NullPointerException.class)
public ResponseEntity<String> handleNullPointer(NullPointerException ex) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("空指针异常:" + ex.getMessage());
}
}
@ExceptionHandler({IllegalArgumentException.class,
IllegalStateException.class})
public ResponseEntity<ErrorResponse> handleIllegal(RuntimeException ex) {
ErrorResponse error = new ErrorResponse(
LocalDateTime.now(),
ex.getClass().getSimpleName(),
ex.getMessage()
);
return ResponseEntity.badRequest().body(error);
}
public class BusinessException extends RuntimeException {
private ErrorCode code;
// 构造方法等
}
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResult> handleBusinessException(
BusinessException ex) {
return ResponseEntity
.status(ex.getCode().getHttpStatus())
.body(ErrorResult.fromException(ex));
}
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class,
new CustomDateEditor(dateFormat, true));
}
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class,
new StringEscapeEditor(true, false));
}
@ModelAttribute
public void addCommonModel(Model model) {
model.addAttribute("version", "1.0.0");
model.addAttribute("systemTime", System.currentTimeMillis());
}
@ModelAttribute("menuList")
public List<Menu> getMenus(Principal principal) {
return menuService.getUserMenu(principal.getName());
}
// 只作用于指定包下的控制器
@ControllerAdvice(basePackages = "com.example.web")
public class WebControllerAdvice {}
// 只作用于带有特定注解的控制器
@ControllerAdvice(annotations = RestController.class)
public class RestControllerAdvice {}
@ControllerAdvice
@ResponseBody
public class RestExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<?> handleValidException(MethodArgumentNotValidException ex) {
// 处理参数校验异常
}
}
@ControllerAdvice
public class ResponseWrapper implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType,
Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
return Result.success(body);
}
}
异常类型 | 处理方式 | HTTP状态码 |
---|---|---|
业务异常 | 返回具体错误信息 | 400/自定义 |
权限异常 | 跳转登录页/返回403 | 401⁄403 |
参数校验异常 | 返回详细校验错误 | 400 |
系统异常 | 记录日志,返回友好提示 | 500 |
@ModelAttribute
会在每次请求时执行@ControllerAdvice
@Order
控制处理优先级A: 默认无序,可通过@Order
注解指定顺序
@WebMvcTest
@Import(GlobalExceptionHandler.class)
class ExceptionHandlerTest {
@Autowired
private MockMvc mockMvc;
@Test
void testHandleException() throws Exception {
mockMvc.perform(get("/api/error"))
.andExpect(status().isInternalServerError());
}
}
A: @RestControllerAdvice
= @ControllerAdvice
+ @ResponseBody
@ControllerAdvice
作为Spring MVC的重要组件,通过本文我们掌握了:
1. 全局异常处理的标准化方案
2. 请求参数的统一预处理
3. 模型属性的动态增强
4. REST API的响应统一包装
5. 实际项目中的优化实践
合理使用该注解可以显著提升代码的可维护性和一致性,是SpringBoot项目中不可或缺的开发技巧。
最佳实践建议:建议在项目中建立
exception
、binder
、model
等子包,按功能拆分不同的@ControllerAdvice
类 “`
这篇文章涵盖了@ControllerAdvice
的核心用法,包含代码示例、表格对比、注意事项等,总字数约3000字。可根据需要进一步扩展具体案例或添加示意图。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。