如何在springBoot优雅的处理异常?
异常处理在任何项目中都尤为重要,所以这使得如何统一处理异常变得非常重要,本文记录在SpringBoot
中解决统一异常处理最优雅的方式。
spring 3.2新增注解@ControllerAdvice
package org.springframework.web.bind.annotation;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<?>[] assignableTypes() default {};
Class<? extends Annotation>[] annotations() default {};
}
ControllerAdvice拆分开来就是Controller Advice,关于Advice,可以理解为AOP
面向切面编程中的环绕增强,为指定范围内的controller进行相应方法的增强代理。结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而
达到不同类型的异常区别处理的目的;@ControllerAdvice的用法基本是将其声明在某个bean上,然后在该bean的方法上使用其他的注解来指定不同的织入逻辑。
不过这里@ControllerAdvice并不是使用AOP的方式来织入业务逻辑的,而是Spring内置对其各个逻辑的织入方式进行了内置支持
@ExceptionHandler注解
@ExceptionHandler的作用主要在于声明一个或多个类型的异常,当符合条件的Controller
抛出这些异常之后将会对这些异常进行捕获,然后按照其标注的方法的逻辑进行处理,从而改变返回的信息
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
// 指定需要捕获的异常的Class类型
Class<? extends Throwable>[] value() default {};
}
实例说明
统一异常配置类
@ControllerAdvice(basePackages = "xxx.xxx")//指定controller所在的包
public class MyExceptionHandler {
@ExceptionHandler(Exception.class)//需要处理的异常类型
@ResponseBody
public Map<String, String> handleException(Exception e) {
HashMap<String, String> errorMap = new HashMap<>();
errorMap.put("errorMsg", e.getMessage());
errorMap.put("code", 500 + "");
return errorMap;
}
}
写个简单的controller 直接抛出异常
@RestController
public class MyController {
@GetMapping("/test")
public void test() {
throw new ArrayIndexOutOfBoundsException("数组越界");
}
}
访问 /test 并没有直接返回结果 而是上述返回异常处理的map
{
"code":500,
"errorMsg":"数组越界"
}