@ControllerAdvice+@ExceptionHandler处理架构异常捕获

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 {};
}
  1. @ControllerAdvice作为一个@Component,用以定义 @ExceptionHandler/@InitBinder/@ModelAttribute 修饰的方法 , 适用于所有使用 @RequestMapping的方法.
  2. Spring4之前,@ControllerAdvice 在同一调度的Servlet中协助所有控制器.Spring4之后,@ControllerAdvice支持配置控制器的子集,且默认的行为仍可用
  3. 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的初衷。

posted @ 2019-01-04 15:14  来兮子宁  阅读(1163)  评论(0编辑  收藏  举报