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 注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文搞懂Spring循环依赖的原理

    一文搞懂Spring循环依赖的原理

    这篇文章将用实例来为大家详细介绍@Autowired解决循环依赖的原理,文中的示例代码讲解详细,对我们学习Spring有一定帮助,感兴趣的可以学习一下
    2022-07-07
  • 深入浅出JAVA MyBatis-快速入门

    深入浅出JAVA MyBatis-快速入门

    这篇文章主要介绍了在今天这篇博文中,我将要介绍一下mybatis的框架原理,以及mybatis的入门程序,实现用户的增删改查,她有什么优缺点以及mybatis和hibernate之间存在着怎么样的关系,大家这些问题一起通过本文学习吧
    2021-06-06
  • 详解Spring MVC自动为对象注入枚举类型

    详解Spring MVC自动为对象注入枚举类型

    本篇文章主要介绍了Spring MVC自动为对象注入枚举类型,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • SpringBoot实现配置文件自动加载和刷新的示例详解

    SpringBoot实现配置文件自动加载和刷新的示例详解

    在使用Spring Boot开发应用程序时,配置文件是非常重要的组成部分,在不同的环境中,我们可能需要使用不同的配置文件,当我们更改配置文件时,我们希望应用程序能够自动加载和刷新配置文件,本文我们将探讨Spring Boot如何实现配置文件的自动加载和刷新
    2023-08-08
  • 深入理解SpringMVC的参数绑定与数据响应机制

    深入理解SpringMVC的参数绑定与数据响应机制

    本文将深入探讨SpringMVC的参数绑定方式,包括基本类型、对象、集合等类型的绑定方式,以及如何处理参数校验和异常。同时,本文还将介绍SpringMVC的数据响应机制,包括如何返回JSON、XML等格式的数据,以及如何处理文件上传和下载。
    2023-06-06
  • Windows下如何安装配置Redis环境

    Windows下如何安装配置Redis环境

    这篇文章主要介绍了Windows下如何安装配置Redis环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-12-12
  • 详解Java如何进行Base64的编码(Encode)与解码(Decode)

    详解Java如何进行Base64的编码(Encode)与解码(Decode)

    这篇文章主要介绍了详解Java如何进行Base64的编码(Encode)与解码(Decode),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • java中不同版本JSONObject区别小结

    java中不同版本JSONObject区别小结

    本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • Springboot注解@Value读取配置文件参数详解

    Springboot注解@Value读取配置文件参数详解

    Spring Boot提供了灵活的配置文件读取机制,主要有两种方式,第一种是使用@Value注解直接在类属性上读取application.yml文件中的配置,这种方式简单直接,但需要为每个配置项单独设置属性,第二种方式是通过@PropertySource注解读取自定义的Properties文件
    2024-11-11
  • Java中&和&&的区别简单介绍

    Java中&和&&的区别简单介绍

    这篇文章主要介绍了Java中&和&&的区别,&&逻辑与||逻辑或  它们都是逻辑运算符,& 按位与|按位或它们都是位运算符,更多详细内容请需要的小伙伴了解下面文章内容
    2022-01-01

最新评论