此问题有下面代码产生:
@Autowired
HttpServletRequest request;
@ResponseBody
@RequestMapping("/test222") // StringToArrayConverter
public Object test222(User user) {
// @RequestParam("id") String id,
// @RequestParam("name") String name,
System.err.println(request.getParameter("id"));
System.err.println(request.getParameter("name"));
return user;
}
@Setter
@Getter
@ToString
class User {
public User() {
System.err.println("user()...");
}
Integer id;
String name;
}
请求接口是:
http://localhost:8080/CustomDispatcherServlet/test222.json
如果是get请求,无论是form-data方式还是x-www-form-urlencoded,
user都绑定不了数据,有关绑定的原理可以查看ServletModelAttributeMethodProcessor
,上面的入参是由这个包尾的HandelrMethodArgumentResolver
解析的,如果改成post请求则可以成功完成绑定。其中get请求那两个控制台也没有输出。后面仔细想了下,如果是get请求,Tomcat不会解析body里面的数据,所以从
request.getParameter(“id”)就为null了,自然就没有数据可以完成绑定了。
验证:把代码改成如下:
@ResponseBody
@RequestMapping("/test222") // StringToArrayConverter
public Object test222(User user,@RequestBody String body) {
// @RequestParam("id") String id,
// @RequestParam("name") String name,
System.err.println(request.getParameter("id"));
System.err.println(request.getParameter("name"));
System.err.println(body);
return user;
}
打印:
user()....
null
null
id=44&name=qyj
那为什么我们在浏览器用get请求调用同样的接口也可以完成绑定,我想如果是get请求,浏览器会把表单的数据放到url后面
下面用谷歌浏览器做下实验:
1、get请求
2、post请求
所以说上面问题就很清楚了,数据是传到服务器了,只是由于tomcat的原因当get请求的时候不会接收body的数据。
另外再说一个坑,上面的User类一定要写set和get方法,不然也是完成不了绑定的,springmvc完成数据绑定的类是DataBinder
,这个能力可不是springmvc的,属于spring,所以说springmvc能完成这么多强大的功能都归功于spring核心的功能,el,数据类型转换,绑定,格式化,校验这些。
@ToString
@Setter
@Getter
class User {
public User() {
System.err.println("user()...");
}
Integer id;
String name;
}
User user=new User();
DataBinder dataBinder=new DataBinder(user,"user");
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("id",33);
pvs.add("name","qydqyj");
dataBinder.bind(pvs);
System.out.println(user);
输出:
User修改如下:
@ToString
class User {
public User() {
System.err.println("user()...");
}
Integer id;
String name;
}
现在知道了把