1.注解引入
1) @ControllerAdvice - 控制器增强
@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作为一个@Component,用以定义 @ExceptionHandler/@InitBinder/@ModelAttribute 修饰的方法 , 适用于所有使用 @RequestMapping的方法.
- Spring4之前,@ControllerAdvice 在同一调度的Servlet中协助所有控制器.Spring4之后,@ControllerAdvice支持配置控制器的子集,且默认的行为仍可用
- Spring4之后,@ControllerAdvice通过annotations()/basePackageClasses()/basePackages()方法定制用于选择控制器子集.
2) @ExceptionHandler - 异常处理器
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ExceptionHandler { Class<? extends Throwable>[] value() default {}; }
单独用@ExceptionHandler,限定当前Controller处理异常.配合@ControllerAdvice则摆脱此限制.
2.使用实例
@ControllerAdvice public class MultipartExceptionControllerAdvice { private static final Logger log = LoggerFactory.getLogger(MultipartExceptionControllerAdvice.class); /** * 捕获文件上传异常 * @param ex * @return */ @ResponseBody @ExceptionHandler(value = MultipartException.class) public FrontResult fileErrorHandler(MultipartException ex) { FrontResult result = new FrontResult(); result.setHasLive(0); result.setCode(500); result.setMsg("FAIL."); log.error("file upload error : " , ex); return result; } }
3.处理Exception在捕获@ResponseStatus修饰的自定义异常时操作
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import javax.servlet.http.HttpServletRequest; @ControllerAdvice public class ExceptionAdvice { @ExceptionHandler(Exception.class) @ResponseBody public String handlerException(HttpServletRequest request , Exception e) throws Exception { e.printStackTrace(); if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) { throw e; } return e.getMessage(); } }
:::: 如果碰到了某个自定义异常加上了@ResponseStatus,就继续抛出,这样就不会让自定义异常失去加上@ResponseStatus的初衷。