HandlerMethodArgumentResolver(一):Controller方法入参自动封装器(将参数parameter解析为值)【享学Spring MVC】(下)

简介: HandlerMethodArgumentResolver(一):Controller方法入参自动封装器(将参数parameter解析为值)【享学Spring MVC】(下)

在本文末,我搜集了一些自己使用过程中的一些疑惑进行解惑,希望也一样能帮助你豁然开朗。


get请求如何传值数组、集合(List)


如题的这个case太常见了有木有,我们经常会遇到使用get请求向后端需要传值的需求(比如根据ids批量查询)。但到底如何传,URL怎么写,应该是有傻傻分不清楚的不确定的情况。


@PathVariable传参


    @ResponseBody
    @GetMapping("/test/{objects}")
    public Object test(@PathVariable List<Object> objects) {
        System.out.println(objects);
        return objects;
    }


请求URL:/test/fsx,fsx,fsx。控制台打印:

[fsx, fsx, fsx]


集合接收成功(使用@PathVariable Object[] objects也是可以正常接收的)。

使用时应注意如下两点:


  1. 多个值只能使用,号分隔才行(否则会被当作一个值,放进数组/集合里,不会报错)
  2. @PathVariable注解是必须的。否则会交给ServletModelAttributeMethodProcessor兜底去处理,它要求有空构造所以反射创建实例会报错(数组/List)。(注意:如果是这样写ArrayList<Object> objects,那是不会报错的,只是值肯定是封装不进来的,一个空对象而已)


说明:为何逗号分隔的String类型默认就能转化为数组,集合。请参考StringToCollectionConverter/StringToArrayConverter这种内置的GenericConverter通用转换器~~


@RequestParam传参


    @ResponseBody
    @GetMapping("/test")
    public Object test(@RequestParam List<Object> objects) {
        System.out.println(objects);
        return objects;
    }


请求URL:/test/?objects=1,2,3。控制台打印:

[1, 2, 3]


请求URL改为:/test/?objects=1&objects=2&objects=3。控制台打印:

[1, 2, 3]


两个请求的URL不一样,但都能正确的达到效果。(@RequestParam Object[] objects这么写两种URL也能正常封装)


对此有如下这个细节你必须得注意:对于集合List而言@RequestParam注解是必须存在的,否则报错如下(因为交给兜底处理了):


image.png


但如果你这么写String[] objects,即使不写注解,也能够正常完成正确封装。


说明:Object[] objects这么写的话不写注解是不行的(报错如上)。至于原因,各位小伙伴可以自行思考,没想明白的话可以给我留言(建议小伙伴一定要弄明白缘由)~


PS:需要注意的是,Spring MVC的这么多HandlerMethodArgumentResolver它的解析是有顺序的:如果多个HandlerMethodArgumentResolver都可以解析某一种类型,以顺序在前面的先解析(后面的就不会再执行解析了)。


源码参考处:HandlerMethodArgumentResolverComposite.getArgumentResolver(MethodParameter parameter);


由于RequestParamMethodArgumentResolver同样可以对Multipart文件上传进行解析,并且默认顺序在RequestPartMethodArgumentResolver之前,所以如果不添加@RequestPart注解,Multipart类型的参数会被RequestParamMethodArgumentResolver解析。

总结


本文是你理解Spring MVC强大的自动数据封装功能非常重要的一篇文章。它介绍了HandlerMethodArgumentResolver的功能和基本使用,以及深入介绍了最为重要的两个注解@PathVariable和@RequestParam以及各自对应的ArgumentResolver处理器。

由于这个体系庞大,所以我会分多个章节进行描述,欢迎订阅和持续关注~

相关文章
|
10天前
|
Java 数据库连接 Spring
Spring Boot命令行启动添加参数
Spring Boot命令行启动添加参数
|
23天前
|
XML 存储 Java
Spring重要类解析
Spring重要类解析
20 0
|
28天前
|
XML Java 数据库连接
spring boot 参数的过滤注解与实战
在Spring Boot应用中,对于入参的过滤,通常会涉及到对Web层的数据验证和处理。Spring Boot借助Spring框架提供了强大的验证框架支持,主要基于JSR-303/JSR-380(Bean Validation API)规范,以及Spring自身的@Valid或@Validated注解来实现请求参数的验证。以下是一些常见的使用案例来展示如何对参数进行过滤和验证。
24 1
|
25天前
|
机器学习/深度学习 算法 编译器
【C++ 泛型编程 中级篇】深度解析C++:类型模板参数与非类型模板参数
【C++ 泛型编程 中级篇】深度解析C++:类型模板参数与非类型模板参数
46 0
|
1月前
|
消息中间件 Cloud Native Java
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
|
1月前
|
缓存 前端开发 Java
【二十八】springboot之通过threadLocal+参数解析器实现同session一样保存当前登录信息的功能
【二十八】springboot之通过threadLocal+参数解析器实现同session一样保存当前登录信息的功能
29 1
|
21天前
|
安全 Java 数据安全/隐私保护
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
44 1
|
7天前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
17 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
|
7天前
|
XML Java 数据格式
从入门到精通:Spring基础注解的全面解析
从入门到精通:Spring基础注解的全面解析
26 2
从入门到精通:Spring基础注解的全面解析
|
7天前
|
Java 数据库 Spring
切面编程的艺术:Spring动态代理解析与实战
切面编程的艺术:Spring动态代理解析与实战
23 0
切面编程的艺术:Spring动态代理解析与实战

推荐镜像

更多