spring中@ControllerAdvice 注解的使用

 更新时间:2024年09月13日 09:54:27   作者:快乐的小三菊  
@ControllerAdvice注解是Spring3.2中新增的注解,主要用于Controller的全局配置,本文就来介绍一下spring中@ControllerAdvice 注解的使用,感兴趣的可以了解一下

一、简介

@ControllerAdvice 注解是 spring3.2 中新增的注解,学名是 Controller 增强器,主要是为了给 Controller 控制器添加统一的操作或处理。

@ControllerAdvice 注解是在类上面声明的注解。

二、作用

1、搭配 @ExceptionHandler 一起使用,可以做到全局异常处理。

2、搭配 @ModelAttribute 一起使用,可以做到添加全局数据,在方法执行前进行一些操作。

3、搭配 @InitBinder 一起使用,可以做到请求参数预处理,即绑定一些自定义参数。

三、搭配 @ExceptionHandler 使用

我们可以使用 @ExceptionHandler 捕获 RuntimeException 异常,代码如下:

@ControllerAdvice
public class SpringControllerAdvice {

    @ExceptionHandler(RuntimeException.class)
    public ModelAndView runtimeExceptionHandler(RuntimeException e) {
        e.printStackTrace();
        return new ModelAndView("error");
    }
}

我们还可以使用 @ExceptionHandler 捕获自定义异常,代码如下:

public class CustomException extends RuntimeException {

    private AppHttpCodeEnum appHttpCodeEnum;

    public CustomException(AppHttpCodeEnum appHttpCodeEnum){
        this.appHttpCodeEnum = appHttpCodeEnum;
    }

    public AppHttpCodeEnum getAppHttpCodeEnum() {
        return appHttpCodeEnum;
    }
}
@ControllerAdvice
@Slf4j
public class ExceptionCatch {

    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public ResponseResult exception(CustomException e){
        log.error("catch exception:{}",e);
        return ResponseResult.errorResult(e.getAppHttpCodeEnum());
    }
}

我们还可以使用 @ExceptionHandler 捕获不可控的全局异常,代码如下:

@ControllerAdvice  
@Slf4j
public class ExceptionCatch {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult exception(Exception e){
        e.printStackTrace();
        log.error("catch exception:{}",e.getMessage());

        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
    }
}

调用下面的测试方法,代码如下,当访问 /users 的时候,因为在该方法中抛出了 RuntimeException,这里的异常捕获器就会捕获该异常,然后返回我们定义的异常视图(默认的error 视图)。 

@Controller
public class UserController {
    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public void users() {
        throw new RuntimeException("没有任何用户。");
    }
}

四、搭配 @InitBinder 使用

对于 @InitBinder,该注解的主要作用是绑定一些自定义的参数。如下代码:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InitBinder {

    // 这里value参数用于指定需要绑定的参数名称,如果不指定,则会对所有的参数进行适配,
    // 只有是其指定的类型的参数才会被转换
    String[] value() default {};
}

一般情况下我们使用的参数通过 @RequestParam@RequestBody 或者 @ModelAttribute等注解就可以进行绑定了。但对于一些特殊类型参数,比如 Date,它们的绑定 Spring 是没有提供直接的支持的。我们只能为其声明一个转换器,将 request 中字符串类型的参数通过转换器转换为 Date 类型的参数,从而供给 @RequestMapping 标注的方法使用。

如下代码,使用 @InitBinder 注册 Date 类型参数转换器的实现:

@ControllerAdvice
public class SpringControllerAdvice {

    @InitBinder
    public void globalInitBinder(WebDataBinder binder) {
        binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
    }
}

这里 @InitBinder 标注的方法注册的 Formatter 在每次 request 请求进行参数转换时都会调用,用于判断指定的参数是否为其可以转换的参数。可以看到当访问 /users 的时候,对 request 参数进行了转换,并且在接口方法中成功接收了该参数,并在控制台打印出日期格式的结果。

五、搭配 @ModelAttribute 使用

关于 @ModelAttribute 的用法,除了用于方法参数时可以用于转换对象类型的属性之外,其还可以用来进行方法的声明。如果声明在方法上,并且结合 @ControllerAdvice,该方法将会在 @ControllerAdvice 所指定的范围内的所有接口方法执行之前执行,并且 @ModelAttribute 标注的方法的返回值还可以供给后续会调用的接口方法使用。

该注解的定义方法如下所示:

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {

    // 该属性与name属性的作用一致,用于指定目标参数的名称
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    // 与name属性一起使用,如果指定了binding为false,那么name属性指定名称的属性将不会被处理
    boolean binding() default true;
}

这里 @ModelAttribute 的各个属性值主要是用于其在接口方法参数上进行标注时使用的,如果是作为方法注解,其 name 或 value 属性则指定的是返回值的名称。如下面的例子:

@ControllerAdvice
public class SpringControllerAdvice {

    @ModelAttribute(value = "message")
    public String globalModelAttribute() {
        System.out.println("添加了message全局属性。");
        return "输出了message全局属性。";
    }
}

测试代码如下:

@Controller
public class UserController {

    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public void users(@ModelAttribute("message") String message) {
        System.out.println(message);
  }
}

这里 @ModelAttribute 注解的方法提供了一个 String 类型的返回值,而 @ModelAttribute 注解中指定了该属性的名称是 message,这样在 Controller 层就可以通过 @ModelAttribute 注解接收名称为 message 的参数,从而获取到前面绑定的参数了。

需要说明的是,@ModelAttribute 标注的方法的执行是在所有的拦截器的 preHandle() 方法执行之后才会执行。

参考博客地址:https://www.cnblogs.com/hdfu/p/17699137.html

到此这篇关于spring中@ControllerAdvice 注解的使用的文章就介绍到这了,更多相关spring @ControllerAdvice 注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java Ribbon与openfeign区别和用法讲解

    Java Ribbon与openfeign区别和用法讲解

    Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具,主要功能是提供客户端的软件负载均衡算法和服务调用。openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便
    2022-08-08
  • SpringBoot框架底层原理解析

    SpringBoot框架底层原理解析

    这篇文章主要介绍了SpringBoot底层原理,包括配置优先级的配置方式给大家讲解的非常详细,需要的朋友可以参考下
    2024-03-03
  • Springboot中的异步任务执行及监控详解

    Springboot中的异步任务执行及监控详解

    这篇文章主要介绍了Springboot中的异步任务执行及监控详解,除了自己实现线程外,springboot本身就提供了通过注解的方式,进行异步任务的执行,下面主要记录一下,在Springboot项目中实现异步任务,以及对异步任务进行封装监控,需要的朋友可以参考下
    2023-10-10
  • Java后端面试高频题整理(面试版答案)

    Java后端面试高频题整理(面试版答案)

    后端Java开发是现代软件工程的重要组成部分,对于应聘后端Java开发岗位的求职者来说,笔试是一项常见的考核方式,这篇文章主要介绍了Java后端面试高频题整理的相关资料,需要的朋友可以参考下
    2026-05-05
  • 基于SpringMVC的全局异常处理器介绍

    基于SpringMVC的全局异常处理器介绍

    下面小编就为大家带来一篇基于SpringMVC的全局异常处理器介绍。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Java基础之方法重写详解

    Java基础之方法重写详解

    这篇文章主要介绍了Java基础之方法重写详解,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-05-05
  • javaweb中静态文件的常用处理方法汇总

    javaweb中静态文件的常用处理方法汇总

    这篇文章主要介绍了javaweb中静态文件的常用处理方法汇总,非常实用的技巧,需要的朋友可以参考下
    2014-08-08
  • SpringBoot和VUE源码直接整合打包成jar的踩坑记录

    SpringBoot和VUE源码直接整合打包成jar的踩坑记录

    这篇文章主要介绍了SpringBoot和VUE源码直接整合打包成jar的踩坑记录,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • 关于Springboot2.x集成lettuce连接redis集群报超时异常Command timed out after 6 second(s)

    关于Springboot2.x集成lettuce连接redis集群报超时异常Command timed out afte

    这篇文章主要介绍了Springboot2.x集成lettuce连接redis集群报超时异常Command timed out after 6 second(s),本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2021-03-03
  • java list和map切割分段的实现及多线程应用案例

    java list和map切割分段的实现及多线程应用案例

    这篇文章主要为大家介绍了java list和map切割分段的实现及多线程应用案例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12

最新评论