← 返回首页
SpringMVC教程(十六)
发表时间:2023-03-04 18:56:23
@ControllerAdvice和@RestControllerAdvice

在Spring 3.2中,新增了@ControllerAdvice、@RestControllerAdvice 注解,都是对Controller进行增强。

1.@ControllerAdvice和@RestControllerAdvice

ControllerAdviceh和RestControllerAdvice一样,本质上是一个Component,因此也会被当成组件注册到IOC容器中。

以@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或者@RestControllerAdvice 提供了多种指定Advice规则的定义方式,默认什么都不写,则是对所有的Controller起作用,当然你也可以通过下列的方式指定规则 比如: 写成@ControllerAdvice("org.my.pkg") 或者 @ControllerAdvice(basePackages="org.my.pkg"), 则匹配org.my.pkg包及其子包下的所有Controller,当然也可以用数组的形式指定,如:@ControllerAdvice(basePackages={"org.my.pkg", "org.my.other.pkg"}), 也可以通过指定注解来匹配,比如我自定了一个 @CustomAnnotation 注解,我想匹配所有被这个注解修饰的 Controller, 可以这么写:@ControllerAdvice(annotations={CustomAnnotation.class})

@RestControllerAdvice作用与@ControllerAdvice类似,可以理解为@RestControllerAdvice = @ControllerAdvice + @ResponseBody。

2.实例

处理全局异常。

例如:有以下登录接口。

@RestController
@RequestMapping("users")
public class UsersController {

    @GetMapping("/auth")
    public R login(@RequestParam("username") String username, @RequestParam("password") String password){
        try{

            if("admin".equals(username)&&"123456".equals(password)){
                return R.success("登录成功!");
            }
            return R.fail("登录失败!");
        }catch(Exception ex){
            ex.printStackTrace();
            return R.error("出现异常!");
        }
    }
}

如果调用这个接口,参数不完整,则抛出以下异常。但是这样的界面显然不友好。

我们可以通过@RestControllerAdvice实现全局异常处理。


@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public R handleException(MissingServletRequestParameterException e){

        return R.error("参数不符合规范!");
    }
}

如果再次调用该接口,出现参数不完整的情况,将会显示更友好的报错信息。

{"data":null,"msg":"参数不符合规范!","code":500,"token":null}