@ControllerAdvice 全局异常业务案例与设计说明
@ControllerAdvice
注解,它用于定义一个或多个控制器的全局异常处理、模型属性的预处理、以及其他全局方法。这个注解通常用于处理跨多个控制器的通用逻辑。
业务场景:
假设你正在开发一个 Web 应用程序,需要对所有控制器的异常进行统一处理,同时还需要在每个请求处理之前向模型中添加一些通用属性。
1. 全局异常处理:
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.http.HttpStatus;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleException(Exception e) {
// 可以记录日志或进行其他异常处理操作
return "error"; // 返回错误页面的视图名称
}
}
在这个例子中,GlobalExceptionHandler
类使用 @ControllerAdvice
注解,表示它包含全局异常处理方法。@ExceptionHandler
注解的方法可以捕获并处理特定类型的异常。
2. 模型属性的预处理:
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import javax.servlet.http.HttpServletRequest;
@ControllerAdvice
public class GlobalModelPreparator {
@ModelAttribute
public void addAttributes(HttpServletRequest request) {
// 向模型中添加通用属性
}
@InitBinder
public void initBinder(WebDataBinder binder) {
// 注册自定义属性编辑器
}
}
在这个例子中,GlobalModelPreparator
类使用 @ControllerAdvice
注解,表示它包含全局模型属性的预处理方法。@ModelAttribute
注解的方法会在每个请求处理之前执行,向模型中添加通用属性。
注解作用说明:
-
@ModelAttribute
:- 用于将方法参数绑定到 Web 请求的参数上,并将绑定的值添加到模型中。这对于从表单提交中获取数据并将其传递给控制器方法非常有用。
-
@InitBinder
:- 用于初始化
WebDataBinder
,它可以注册自定义属性编辑器,这些编辑器可以用于自定义数据类型到字符串的转换逻辑。
- 用于初始化
-
@ExceptionHandler
:- 用于处理控制器抛出的异常。可以捕获特定类型的异常,并定义异常处理的逻辑。
-
@ControllerAdvice
:- 用于定义全局的控制器逻辑,包括异常处理、模型属性的预处理等。可以应用于所有控制器,或者通过指定
basePackages
或basePackageClasses
属性来限定其适用范围。
- 用于定义全局的控制器逻辑,包括异常处理、模型属性的预处理等。可以应用于所有控制器,或者通过指定
注解属性作用:
-
value 和 basePackages:
- 这两个属性用于指定控制器的基础包。
@ControllerAdvice
注解的类将只对这些包或其子包中的控制器有效。 - 例如,
@ControllerAdvice("org.my.pkg")
表示只对org.my.pkg
包及其子包中的控制器提供建议(即异常处理和模型属性的预处理)。 value
是basePackages
的别名,允许更简洁的注解声明。
- 这两个属性用于指定控制器的基础包。
-
basePackageClasses:
- 这是一个类型安全的属性,用于指定控制器所在的包。与
basePackages
相比,使用basePackageClasses
可以避免字符串错误,是一种更安全的指定包的方式。 - 开发者可以在每个包中创建一个特殊的标记类或接口,仅用于被
basePackageClasses
属性引用。
- 这是一个类型安全的属性,用于指定控制器所在的包。与
-
assignableTypes:
- 这个属性允许你通过类类型来指定控制器。
@ControllerAdvice
注解的类将对所有可以被assignableTypes
中的类所处理的控制器提供建议。 - 例如,
@ControllerAdvice(assignableTypes = {MyController.class})
表示只对MyController
类或其子类提供建议。
- 这个属性允许你通过类类型来指定控制器。
-
annotations:
- 这个属性用于指定注解类型。
@ControllerAdvice
注解的类将对所有被annotations
中指定的注解所注解的控制器提供建议。 - 这可以用于针对特定类型的控制器进行定制化处理,例如,只处理带有
@RestController
注解的控制器。
- 这个属性用于指定注解类型。
总结:
@ControllerAdvice
允许开发者集中处理跨多个控制器的通用逻辑,如异常处理和模型属性的预处理。- 它提高了代码的复用性和可维护性,避免了在每个控制器中重复相同的逻辑。
- 通过使用
@ControllerAdvice
,可以更容易地实现应用程序的一致性和标准化。
转载自:https://juejin.cn/post/7382891974942294042