序言
自spring 3.2以后,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。
@ExceptionHandler在使用时一般需要配合@RequestBody使用。
public @interface RestControllerAdvice一种方便的注释,它本身用@ControllerAdvice和@ResponseBody注解实现。带有此注解的类型被视为控制器,其中@ExceptionHandler方法默认采用@ResponseBody语义。
以下是反编译源码:(方便了解RestControllerAdvice是基于ControllerAdvice实现的注解)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice
@ResponseBody
public @interface RestControllerAdvice {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<?>[] assignableTypes() default {};
Class<? extends Annotation>[] annotations() default {};
}
@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还是RestControllerAdvice都可以通过以下几种方式使用
//指向所有带有注解@RestController的控制器
@ControllerAdvice(annotations = RestController.class)
public class AnnotationAdvice {}
// 指向所有指定包中的控制器
@ControllerAdvice("org.example.controllers")
public class BasePackageAdvice {}
// 指向所有带有指定签名的控制器
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class AssignableTypesAdvice {}
示例
ControllerAdvice使用示例
@ControllerAdvice
public class MyControllerAdvice {
/**
* 全局异常捕捉处理
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = Exception.class)
public Map errorHandler(Exception ex) {
Map map = new HashMap();
map.put("code", 100);
map.put("msg", ex.getMessage());
return map;
}
/**
* 拦截捕捉自定义异常 MyException.class
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = MyException.class)
public Map myErrorHandler(MyException ex) {
Map map = new HashMap();
map.put("code", ex.getCode());
map.put("msg", ex.getMsg());
return map;
}
}
RestControllerAdvice使用示例
@RestControllerAdvice
public class RRExceptionHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 处理自定义异常
*/
@ExceptionHandler(RRException.class)
public Result handleRRException(RRException e){
Result r = new Result();
r.put("status", e.getCode());
r.put("message", e.getMessage());
return r;
}
}