美文网首页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