SpringMVC请求参数接收总结

前提

在日常使用SpringMVC进行开发的时候,有可能遇到前端各种类型的请求参数,这里做一次相对全面的总结。SpringMVC中处理控制器参数的接口是HandlerMethodArgumentResolver,此接口有众多子类,分别处理不同(注解类型)的参数,下面只列举几个子类:

  • RequestParamMethodArgumentResolver:解析处理使用了@RequestParam注解的参数、MultipartFile类型参数和Simple类型(如long、int)参数。

  • RequestResponseBodyMethodProcessor:解析处理@RequestBody注解的参数。

  • PathVariableMapMethodArgumentResolver:解析处理@PathVariable注解的参数。

实际上,一般在解析一个控制器的请求参数的时候,用到的是HandlerMethodArgumentResolverComposite,里面装载了所有启用的HandlerMethodArgumentResolver子类。而HandlerMethodArgumentResolver子类在解析参数的时候使用到HttpMessageConverter(实际上也是一个列表,进行遍历匹配解析)子类进行匹配解析,常见的如MappingJackson2HttpMessageConverter。而HandlerMethodArgumentResolver子类到底依赖什么HttpMessageConverter实例实际上是由请求头中的ContentType(在SpringMVC中统一命名为MediaType,见org.springframework.http.MediaType)决定的,因此我们在处理控制器的请求参数之前必须要明确外部请求的ContentType到底是什么。上面的逻辑可以直接看源码AbstractMessageConverterMethodArgumentResolver#readWithMessageConverters,思路是比较清晰的。在@RequestMapping注解中,produces和consumes就是和请求或者响应的ContentType相关的:

  • consumes:指定处理请求的提交内容类型(ContentType),例如application/json, text/html,只有命中了才会接受该请求。

  • produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回,如果返回的是JSON数据一般使用application/json;charset=UTF-8。

另外提一点,SpringMVC中默认使用Jackson作为JSON的工具包,如果不是完全理解透整套源码的运作,一般不是十分建议修改默认使用的MappingJackson2HttpMessageConverter(例如有些人喜欢使用FastJson,实现HttpMessageConverter引入FastJson做转换器)。

SpringMVC请求参数接收

其实一般的表单或者JSON数据的请求都是相对简单的,一些复杂的处理主要包括URL路径参数、文件上传、数组或者列表类型数据等。另外,关于参数类型中存在日期类型属性(例如java.util.Date、java.sql.Date、java.time.LocalDate、java.time.LocalDateTime),解析的时候一般需要自定义实现的逻辑实现String->日期类型的转换。其实道理很简单,日期相关的类型对于每个国家、每个时区甚至每个使用者来说认知都不一定相同。在演示一些例子主要用到下面的模特类:

表单参数

非对象类型单个参数接收:

这种是最常用的表单参数提交,ContentType指定为application/x-www-form-urlencoded,也就是会进行URL编码。

说实话,如果有毅力的话,所有的复杂参数的提交最终都可以转化为多个单参数接收,不过这样做会产生十分多冗余的代码,而且可维护性比较低。这种情况下,用到的参数处理器是RequestParamMapMethodArgumentResolver。

对象类型参数接收:

我们接着写一个接口用于提交用户信息,用到的是上面提到的模特类,主要包括用户姓名、年龄和联系人信息列表,这个时候,我们目标的控制器最终编码如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值