美文网首页Spring-Boot
@ControllerAdvice结合@ExceptionHan

@ControllerAdvice结合@ExceptionHan

作者: chzne | 来源:发表于2019-04-28 22:36 被阅读1次

    ControllerAdvice从名称上我们能看出它是Controller层的AOP注解
    关注于控制器中公共处理部分:如 异常处理,数据绑定,模型填充 日志记录等。
    如常见的异常如果我们每个控制器的方法都显示的加上try catch 的话
    代码就显得很冗余,重复,代码看上去不太优雅。
    所以对于异常捕获这一类代码我们可以用@ControllerAdvice来实现统一的处理。

    所有带@ControllerAdvice注释的类可以用@Component显示的声明为Spring Bean 或
    通过自动扫描。
    所有这些类都会通过AnnotationAwareOrderComparator来排序
    通过@Order注解或者实现Ordered接口来指定执行的顺序优先级。
    但对于异常处理来说@ExceptionHandler只选择第一个匹配上的处理器,不支持多个。
    @InitBinder 和 @ModelAttribute 是遵循@Order的顺序挨个执行。

    默认@ControllerAdvice是对所有的Controllers都生效的。

    可以使用basePackages来定义作用的包路径或用它的别名value
    定义多个Controller的子集。

    @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 {};
    
    }
    

    简单案例:

    在我们做API接口开发的时候都有一个统一的JSON格式
    如下:
    {"code":200,"message":"成功","data":""}
    使用@ControllerAdvice处理全局异常
    如果发生异常统一返回 FailHttpApiResponse
    返回给客户端如下:
    {"code":400,"message":"系统发生异常","data":""}
    具体的错误码我们可以通过Exception的具体类型来判断是不是业务类型的异常,如果是那么返回具体对应的错误码和消息

    @Slf4j
    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        @ExceptionHandler(Exception.class)
        @ResponseBody
        public FailHttpApiResponse handle(Exception e) {
            log.error("exception", e);
            return new FailHttpApiResponse(400,"系统发生异常", "");
        }
    
    }
    

    不同异常分别处理

    @Slf4j
    @ControllerAdvice
    public class GlobalExceptionHandler {
    
    
        @ExceptionHandler(Exception.class)
        @ResponseBody
        public FailHttpApiResponse handle(Exception e) {
    
    
            return new FailHttpApiResponse("系统发生异常", "");
    
        }
    
        @ExceptionHandler(MethodArgumentNotValidException.class)
        @ResponseBody
        public FailHttpApiResponse methodArgumentNotValidException(MethodArgumentNotValidException e){
            BindingResult bindingResult =e.getBindingResult();
            String message = bindingResult.getFieldErrors().get(0).getDefaultMessage();
            return new FailHttpApiResponse(HttpServletResponse.SC_BAD_REQUEST, "参数非法: " +message , "");
        }
    
        @ExceptionHandler(BusinessException.class)
        @ResponseBody
        public FailHttpApiResponse businessException(BusinessException e){
            return new FailHttpApiResponse(e.getCode(), e.getMsg(), "");
        }
    
    }
    

    相关文章

      网友评论

        本文标题:@ControllerAdvice结合@ExceptionHan

        本文链接:https://www.haomeiwen.com/subject/unusnqtx.html