SpringMVC请求参数接收总结(一) (2)

对应的控制器如下:

@PostMapping(value = "/post") public String post(@RequestParam(name = "name") String name, @RequestParam(name = "age") Integer age) { String content = String.format("name = %s,age = %d", name, age); log.info(content); return content; }

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

【对象】 - 对象类型参数接收。

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

@PostMapping(value = "/user") public User saveUser(User user) { log.info(user.toString()); return user; }

我们还是指定Content-Type为application/x-www-form-urlencoded,接着我们需要构造请求参数:

spmvc-p-2

因为没有使用注解,最终的参数处理器为ServletModelAttributeMethodProcessor,主要是把HttpServletRequest中的表单参数封装到MutablePropertyValues实例中,再通过参数类型实例化(通过构造反射创建User实例),反射匹配属性进行值的填充。另外,请求复杂参数里面的列表属性请求参数看起来比较奇葩,实际上和在.properties文件中添加最终映射到Map类型的参数的写法是一致的。那么,能不能把整个请求参数塞在一个字段中提交呢?

spmvc-p-3

直接这样做是不行的,因为实际提交的Form表单,key是user字符串,value实际上也是一个字符串,缺少一个String->User类型的转换器,实际上RequestParamMethodArgumentResolver依赖WebConversionService中Converter实例列表进行参数转换:

spmvc-p-4

解决办法还是有的,添加一个org.springframework.core.convert.converter.Converter实现即可:

@Component public class StringUserConverter implements Converter<String, User> { @Autowaired private ObjectMapper objectMapper; @Override public User convert(String source) { try { return objectMapper.readValue(source, User.class); } catch (IOException e) { throw new IllegalArgumentException(e); } } }

上面这种做法属于曲线救国的做法,不推荐使用在生产环境,但是如果有些第三方接口的对接无法避免这种参数,可以选择这种实现方式。

【数组】 - 列表或者数组类型参数。

极度不推荐使用在application/x-www-form-urlencoded这种媒体类型的表单提交的形式下强行使用列表或者数组类型参数,除非是为了兼容处理历史遗留系统的参数提交处理。例如提交的参数形式是:

list = ["string-1", "string-2", "string-3"]

那么表单参数的形式要写成:

name value
list[0]   string-1  
list[1]   string-2  
list[2]   string-3  

控制器的代码如下:

@PostMapping(path = "/list") public void list(@RequestParam(name="list") List<String> list) { log.info(list); }

一个更加复杂的例子如下,假设想要提交的报文格式如下:

user = [{"name":"doge-1","age": 21},{"name":"doge-2","age": 22}]

那么表单参数的形式要写成:

name value
user[0].name   doge-1  
user[0].age   21  
user[1].name   doge-2  
user[1].age   22  

控制器的代码如下:

@PostMapping(path = "/user") public void saveUsers(@RequestParam(name="user") List<UserVo> users) { log.info(users); } @Data public class UserVo{ private String name; private Integer age; } JSON参数

一般来说,直接在POST请求中的请求体提交一个JSON字符串这种方式对于SpringMVC来说是比较友好的,只需要把Content-Type设置为application/json,提交一个原始的JSON字符串即可,控制器方法参数使用@RequestBody注解处理:

spmvc-p-5

后端控制器的代码也比较简单:

@PostMapping(value = "/user-2") public User saveUser2(@RequestBody User user) { log.info(user.toString()); return user; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypwfy.html