说实话,如果有毅力的话,所有的复杂参数的提交最终都可以转化为多个单参数接收,不过
这样做会产生十分多冗余的代码,而且可维护性比较低。这种情况下,用到的参数处理器是
RequestParamMapMethodArgumentResolver 。
【对象】 - 对象类型参数接收。
我们接着写一个接口用于提交用户信息,用到的是上面提到的模特类,主要包括用户姓名、
年龄和联系人信息列表,这个时候,我们目标的控制器最终编码如下:
@PostMapping(value = "/user")
public User saveUser(User user) {
log.info(user.toString());
return user;
}
我们还是指定 Content-Type 为 application/x-www-form-urlencoded ,接着我们需要构造请
求参数:
因为没有使用注解,最终的参数处理器为 ServletModelAttributeMethodProcessor ,主要是
把 HttpServletRequest 中的表单参数封装到 MutablePropertyValues 实例中,再通过参数类
型实例化(通过构造反射创建 User 实例),反射匹配属性进行值的填充。另外,请求复杂参
数里面的列表属性请求参数看起来比较奇葩,实际上和在 .properties 文件中添加最终映射
到 Map 类型的参数的写法是一致的。那么,能不能把整个请求参数塞在一个字段中提交呢?
直接这样做是不行的,因为实际提交的 Form 表单, key 是 user 字符串, value 实际上
也 是 一 个 字 符 串 , 缺 少 一 个 String->User 类 型 的 转 换 器 , 实 际 上
RequestParamMethodArgumentResolver 依赖 WebConversionService 中 Converter 实例列
表进行参数转换:
解决办法还是有的,添加一个 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);
}
}
评论0