Spring中@ControllerAdvice注解的用法解析

 更新时间:2023年10月12日 11:38:43   作者:探索er  
这篇文章主要介绍了Spring中@ControllerAdvice注解的用法解析,顾名思义,@ControllerAdvice就是@Controller 的增强版,@ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler、@ModelAttribute以及@InitBinder使用,需要的朋友可以参考下

@ControllerAdvice 用法

顾名思义,@ControllerAdvice就是@Controller 的增强版。

@ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler、@ModelAttribute以及@InitBinder使用。

全局异常处理

@ControllerAdvice最常见的使用场景就是全局异常处理。

比如文件上传大小限制的配置,如果用户上传的文件超过了限制大小,就会抛出异常,此时可以通过@ControllerAdvice结合@ExceptionHandler定义全局异常捕获机制,代码如下:

@ControllerAdvice
public class CustomExceptionHandler {
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public void uploadException(MaxUploadSizeExceededException e, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/html;charset=utf-8");
        System.out.println(1111);
        PrintWriter out = resp.getWriter();
        out.write("上传文件大小超出限制!");
        out.flush();
        out.close();
    }
}

只需在系统中定义CustomExceptionHandler类,然后添加@ControllerAdvice注解即可。当系统启动时,该类就会被扫描到Spring容器中,然后定义uploadException方法,在该方法上添加了@ExceptionHandler注解,其中定义的MaxUploadSizeExceededException.class 表明该方法用来处理MaxUploadSizeExceededException类型的异常。如果想让该方法处理所有类型的异常,只需将MaxUploadSizeExceededException改为 Exception即可。方法的参数可以有异常实例、HttpServletResponse以及HttpServletRequest、Model 等,返回值可以是一段JSON、一个ModelAndView、一个逻辑视图名等。此时,上传一个超大文件会有错误提示给用户。

在这里插入图片描述

如果返回参数是一个ModelAndView,假设使用的页面模板为Thymeleaf(注意添加Thymeleaf相关依赖),此时异常处理方法定义如下:

@ControllerAdvice
public class CustomExceptionHandler {
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ModelAndView uploadException(MaxUploadSizeExceededException e) throws IOException {
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "上传文件大小超出限制! ");
        mv.setViewName("error");
        return mv;
    }
}

然后在resources/templates目录下创建error.html文件,内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title></head>
<body>
<div th:text="${msg}"></div>
</body>
</html>

此时上传出错效果一致。

添加全局数据

@ControllerAdvice是一个全局数据处理组件,因此也可以在@ControllerAdvice中配置全局数据,使用@ModelAttribute注解进行配置,代码如下:

@ControllerAdvice
public class GlobalConfig {
    @ModelAttribute(value = "info")
    public Map<String, String> userInfo() {
        HashMap<String, String> map = new HashMap<>();
        map.put("username", "罗贯中");
        map.put("gender", "男");
        return map;
    }
}

代码解释:

  • 在全局配置中添加userInfo方法,返回一个map。该方法有一个注解@ModelAttribute,其中的value属性表示这条返回数据的key,而方法的返回值是返回数据的value。
  • 此时在任意请求的Controller 中,通过方法参数中的Model都可以获取info 的数据。

Controller 例代码如下:

public class MyController {
    @GetMapping("/hello")
    @ResponseBody
    public void hello(Model model) {
        Map<String, Object> map = model.asMap();
        Set<String> keySet = map.keySet();
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            Object value = map.get(key);
            System.out.println(key + ">>>>>" + value);
        }
    }
}

在请求方法中,将Model 中的数据打印出来,如图所示。

在这里插入图片描述

请求参数预处理

@ControllerAdvice结合@InitBinder还能实现请求参数预处理,即将表单中的数据绑定到实体类上时进行一些额外处理。

例如有两个实体类 Book和 Author,代码如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@ToString
public class Book {
    private String name;
    private String author;
    @JsonIgnore//一般标记在属性或者方法上,返回的json数据即不包含该属性
    private Float price;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date publicationDate;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Author {
    private String name;
    private int age;
}

在 Controller 上需要接收两个实体类的数据,Controller 中的方法定义如下:

@ControllerAdvice
public class GlobalConfig1 {
    @InitBinder("b")
    public void init(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("b.");
    }
    @InitBinder("a")
    public void init2(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("a.");
    }
}

代码解释:

  • 在 GlobalConfig类中创建两个方法,第一个@InitBinder(“b”)表示该方法是处理@ModelAttribute(“b”)对应的参数的,第二个@InitBinder(“a”)表示该方法是处理@ModelAttribute(“a”)对应的参数的。
  • 在每个方法中给相应的 Field设置一个前缀,然后在浏览器中请求http:/ocalhost:8080/book?b.name=三国演义&b.author=罗贯中&a.name=曹雪芹&a.age=48,即可成功地区分出name属性。
  • 在WebDataBinder对象中,还可以设置允许的字段、禁止的字段、必填字段以及验证器等。

ld设置一个前缀,然后在浏览器中请求/ocalhost:8080/book?b.name=三国演义&b.author=罗贯中&a.name=曹雪芹&a.age=48,即可成功地区分出name属性。

在WebDataBinder对象中,还可以设置允许的字段、禁止的字段、必填字段以及验证器等。

在这里插入图片描述

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

相关文章

  • 浅谈Mybatis SqlSession执行流程

    浅谈Mybatis SqlSession执行流程

    本文主要介绍了浅谈Mybatis SqlSession执行流程,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2021-07-07
  • Flink支持哪些数据类型?

    Flink支持哪些数据类型?

    Apache Flink 以其独特的方式来处理数据类型以及序列化,这种方式包括它自身的类型描述符、泛型类型提取以及类型序列化框架.本文档描述了它们背后的概念和基本原理,需要的朋友可以参考下
    2021-06-06
  • SecurityUtils.getSubject().getPrincipal()为null的问题

    SecurityUtils.getSubject().getPrincipal()为null的问题

    这篇文章主要介绍了SecurityUtils.getSubject().getPrincipal()为null的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • Java Map.Entry的使用方法解析

    Java Map.Entry的使用方法解析

    这篇文章主要介绍了Java Map.Entry的使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Spring/SpringBoot @RequestParam注解无法读取application/json格式数据问题解决

    Spring/SpringBoot @RequestParam注解无法读取application/json格式数据问题

    RequestParam用于将指定的请求参数赋值给方法中的形参,可以接受简单类型属性,也可以接受对象类型,一般用于GET请求,下面这篇文章主要给大家介绍了关于Spring/SpringBoot @RequestParam注解无法读取application/json格式数据问题解决的相关资料,需要的朋友可以参考下
    2022-10-10
  • Spring Security如何使用URL地址进行权限控制

    Spring Security如何使用URL地址进行权限控制

    这篇文章主要介绍了Spring Security如何使用URL地址进行权限控制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • JAVA函数的定义、使用方法实例分析

    JAVA函数的定义、使用方法实例分析

    这篇文章主要介绍了JAVA函数的定义、使用方法,结合实例形式分析了JAVA函数的基本概念、功能、原理、定义、使用方法与操作注意事项,需要的朋友可以参考下
    2020-04-04
  • SpringBoot logback日志框架使用过程解析

    SpringBoot logback日志框架使用过程解析

    这篇文章主要介绍了SpringBoot logback日志框架使用过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • redis 使用lettuce 启动内存泄漏错误的解决方案

    redis 使用lettuce 启动内存泄漏错误的解决方案

    这篇文章主要介绍了redis 使用lettuce 启动内存泄漏错误的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • @ControllerAdvice 用法解析

    @ControllerAdvice 用法解析

    @ControllerAdvice就是@Controller 的增强版,@ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler、@ModelAttribute以及@InitBinder使用,这篇文章主要介绍了@ControllerAdvice 用法,需要的朋友可以参考下
    2022-11-11

最新评论