如何让微信同步接收Spring MVC接收的参数可以转换为java对象

SpringMVC接收多个对象的4种方法
转载 & & 作者:kepler08
这篇文章主要为大家详细介绍了SpringMVC接收多个对象的4种方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
问题背景:
我要在一个表单里同时一次性提交多名乘客的个人信息到SpringMVC,前端HTML和SpringMVC Controller里该如何处理?
第1种方法:表单提交,以字段数组接收;
第2种方法:表单提交,以BeanListModel接收;
第3种方法:将Json对象序列化成Json字符串提交,以List接收;
第4种方法:将表单对象序列化成Json字符串提交,以List接收;
第4种方法其实是第3种方法的升级,就是将表单转成Json对象,再转成Json字符串提交;
然而,第4种方法还不支持含有多选控件表单的提交,故应该还有第5种加强版的方法。
以上4种方法都共用同一个User实体类,代码如下:
public class User {
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
// .......后面还有getter、setter方法,省略了
第1种方法:表单提交,以字段数组接收
HTML代码如下:
&form action="/user/submitUserList_1" method="post"&
ID:&input type="text" name="id"&&br/&
Username:&input type="text" name="name"&&br/&
Password:&input type="text" name="pwd"&&br/&&br/&
ID:&input type="text" name="id"&&br/&
Username:&input type="text" name="name"&&br/&
Password:&input type="text" name="pwd"&&br/&&br/&
&input type="submit" value="submit"&
Java代码如下:
@RequestMapping(value = "/submitUserList_1", method ={RequestMethod.POST})
@ResponseBody
public String submitUserList_1(HttpServletResponse response,Integer[] id, String[] name, String[] pwd)
throws Exception{
String result = "";
if(id == null || id.length &= 0){ return "No any ID.中文"; }
List&User& userList = new ArrayList&User&();
for (int i = 0; i & id. i++ ) {
User user = new User();
user.setId(id[i]);
user.setName(name[i]);
user.setPwd(pwd[i]);
userList.add(user);
result = this.showUserList(userList);
第2种方法:表单提交,以BeanListModel接收
HTML代码如下:
&form action="/user/submitUserList_2" method="post"&
ID:&input type="text" name="users[0].id"&&br/&
Username:&input type="text" name="users[0].name"&&br/&
Password:&input type="text" name="users[0].pwd"&&br/&&br/&
ID:&input type="text" name="users[2].id"&&br/&
Username:&input type="text" name="users[2].name"&&br/&
Password:&input type="text" name="users[2].pwd"&&br/&&br/&
&input type="submit" value="Submit"&
Java代码:
除了刚才公用的User类,还要封装一个User的容器类UserModel:
public class UserModel {
private List&User&
public List&User& getUsers() {
public void setUsers(List&User& users) {
this.users =
public UserModel(List&User& users) {
this.users =
public UserModel() {
SpringMVC Controller方法:
@RequestMapping(value = "/submitUserList_2", method ={RequestMethod.POST})
@ResponseBody
public String submitUserList_2(UserModel users)
throws Exception{
String result = "";
List&User& userList = users.getUsers();
if(userList == null || userList.size() &= 0){ return "No any ID.中文"; }
result = this.showUserList(userList);
第3种方法:将Json对象序列化成Json字符串提交,以List接收
HTML代码:
&title&submitUserList_3&/title&
&meta http-equiv="content-type" content="text/ charset=utf-8"&
&script language="JavaScript" src="/js/jquery.min.js" &&/script&
&script language="JavaScript" src="/js/jquery.json.min.js" &&/script&
&script type="text/javascript" language="JavaScript"&
function submitUserList_3() {alert("ok");
var customerArray = new Array();
customerArray.push({id: "1", name: "李四", pwd: "123"});
customerArray.push({id: "2", name: "张三", pwd: "332"});
url: "/user/submitUserList_3",
type: "POST",
contentType : 'application/charset=utf-8', //设置请求头信息
dataType:"json",
//data: JSON.stringify(customerArray),
//将Json对象序列化成Json字符串,JSON.stringify()原生态方法
data: $.toJSON(customerArray),
//将Json对象序列化成Json字符串,toJSON()需要引用jquery.json.min.js
success: function(data){
alert(data);
error: function(res){
alert(res.responseText);
&h1&submitUserList_3&/h1&
&input id="submit" type="button" value="Submit" onclick="submitUserList_3();"&
Java代码:
@RequestMapping(value = "/submitUserList_3", method ={RequestMethod.POST})
@ResponseBody
public String submitUserList_3(@RequestBody List&User& users)
throws Exception{
String result = "";
if(users == null || users.size() &= 0){ return "No any ID.中文"; }
result = this.showUserList(users);
第4种方法:将表单对象序列化成Json字符串提交,以List接收
HTML代码:
&!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"&
&title&submitUserList_4&/title&
&meta http-equiv="content-type" content="text/ charset=utf-8"&
&script language="JavaScript" src="/js/jquery.min.js" &&/script&
&script type="text/javascript" language="JavaScript"&
//将表单序列化成json格式的数据(但不适用于含有控件的表单,例如复选框、多选的select)
(function($){
$.fn.serializeJson = function(){
var jsonData1 = {};
var serializeArray = this.serializeArray();
// 先转换成{"id": ["12","14"], "name": ["aaa","bbb"], "pwd":["pwd1","pwd2"]}这种形式
$(serializeArray).each(function () {
if (jsonData1[this.name]) {
if ($.isArray(jsonData1[this.name])) {
jsonData1[this.name].push(this.value);
jsonData1[this.name] = [jsonData1[this.name], this.value];
jsonData1[this.name] = this.
// 再转成[{"id": "12", "name": "aaa", "pwd":"pwd1"},{"id": "14", "name": "bb", "pwd":"pwd2"}]的形式
var vCount = 0;
// 计算json内部的数组最大长度
for(var item in jsonData1){
var tmp = $.isArray(jsonData1[item]) ? jsonData1[item].length : 1;
vCount = (tmp & vCount) ? tmp : vC
if(vCount & 1) {
var jsonData2 = new Array();
for(var i = 0; i & vC i++){
var jsonObj = {};
for(var item in jsonData1) {
jsonObj[item] = jsonData1[item][i];
jsonData2.push(jsonObj);
return JSON.stringify(jsonData2);
return "[" + JSON.stringify(jsonData1) + "]";
})(jQuery);
function submitUserList_4() {alert("ok");
var jsonStr = $("#form1").serializeJson();
//console.log("jsonStr:\r\n" + jsonStr);
//alert(jsonStr);
url: "/user/submitUserList_4",
type: "POST",
contentType : 'application/charset=utf-8', //设置请求头信息
dataType:"json",
data: jsonStr,
success: function(data){
alert(data);
error: function(res){
alert(res.responseText);
&h1&submitUserList_4&/h1&
&form id="form1"&
ID:&input type="text" name="id"&&br/&
Username:&input type="text" name="name"&&br/&
Password:&input type="text" name="pwd"&&br/&&br/&
ID:&input type="text" name="id"&&br/&
Username:&input type="text" name="name"&&br/&
Password:&input type="text" name="pwd"&&br/&&br/&
&input type="button" value="submit" onclick="submitUserList_4();"&
Java代码:
@RequestMapping(value = "/submitUserList_4", method ={RequestMethod.POST})
@ResponseBody
public String submitUserList_4(@RequestBody List&User& users)
throws Exception{
String result = "";
if(users == null || users.size() &= 0){ return "No any ID.中文"; }
result = this.showUserList(users);
第1、2种方法其实都有一个共同的BUG:假如提交三条记录时,前面两条记录的某些字段不填值的话,在SpringMVC里接收不准确了。而且,每2种方法在HMTL中需要给name属性添加[下标],如果下标有跨度的话(比如第一组控件下标是0,第二组下标是2),那么SpringMVC里其实的是0到2三个对象的,默认下标是1的那个对象全为null值。
第3、4种方法最实用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具自由、创新、研究、探索
Linux/Windows Mono/DotNet [ Open Source .NET Development/ 使用开源工具进行DotNet软件开发]锐意进取,志存高远.成就梦想,只争朝夕.从你开始,创新世界.【That I exist is a perpetual supprise which is life. Focus on eCommerce】
SpringMVC是目前主流的Web MVC框架之一。&
如果有同学对它不熟悉,那么请参考它的入门blog:
public String method(Integer num, Date birth) {
Http请求传递的数据都是字符串String类型的,上面这个方法在Controller中定义,如果该方法对应的地址接收到到浏览器的请求的话,并且请求中含有num和birth参数,那么num会被自动转换成Integer对象;birth会被自动转为Date对象(Date转换需要配置属性编辑器)。
本文将分析这一原理,解释SpringMVC是如何实现数据类型的转换。
属性编辑器介绍
在讲解核心内容之前,我们先来了解一下Java中定义的属性编辑器。
sun设计属性编辑器主要是为IDE服务的,让IDE能够以可视化的方式设置JavaBean的属性。
PropertyEditor是属性编辑器的接口。
我们使用属性编辑器一般都是将String对象转换成我们需要的java对象而使用的。
有个方法setAsText很重要。 比如String对象"1"要使用属性编辑器转换成Integer对象,通过setAsText里Integer.parseInt(text)得到Integer对象,然后将Integer对象保存到属性中。
它的基本实现类是PropertyEditorSupport,一般我们要编写自定义的属性编辑器只需要继承这个类即可。
Spring中有很多自定义的属性编辑器,都在spring-beans jar包下的org.springframework.beans.propertyeditors包里。
CustomBooleanEditor继承PropertyEditorSupport并重写setAsText方法。
重要接口和类介绍
&刚刚分析了sun设计的属性编辑器。 下面我们来看下Spring对这方面的设计。
1.PropertyEditorRegistry接口
  封装方法来给JavaBean注册对应的属性编辑器。
2.PropertyEditorRegistrySupport:PropertyEditorRegistry接口的基础实现类
  PropertyEditorRegistrySupport类有个createDefaultEditors方法,会创建默认的属性编辑器。
3.TypeConverter接口
  类型转换接口。 通过该接口,可以将value转换为requiredType类型的对象。
4.TypeConverterSupport:TypeConverter基础实现类,并继承了PropertyEditorRegistrySupport  
  有个属性typeConverterDelegate,类型为TypeConverterDelegate,TypeConverterSupport将类型转换委托给typeConverterDelegate操作。
5.TypeConverterDelegate
  类型转换委托类。具体的类型转换操作由此类完成。
6.SimpleTypeConverter
  TypeConverterSupport的子类,使用了PropertyEditorRegistrySupport(父类TypeConverterSupport的父类PropertyEditorRegistrySupport)中定义的默认属性编辑器。
7.PropertyAccessor接口
  对类中属性操作的接口。
8.BeanWrapper接口
  继承ConfigurablePropertyAccessor(继承PropertyAccessor、PropertyEditorRegistry、TypeConverter接口)接口的操作Spring中JavaBean的核心接口。
9.BeanWrapperImpl类
  BeanWrapper接口的默认实现类,TypeConverterSupport是它的父类,可以进行类型转换,可以进行属性设置。
10.DataBinder类
  实现PropertyEditorRegistry、TypeConverter的类。支持类型转换,参数验证,数据绑定等功能。
  有个属性SimpleTypeConverter,用来进行类型转换操作。
11.WebDataBinder
  DataBinder的子类,主要是针对Web请求的数据绑定。
部分类和接口测试
由于BeanWrapper支持类型转换,属性设置。以BeanWrapper接口为例,做几个测试,让读者对它们有更清晰的认识:
以TestModel这个JavaBean为例,属性:
测试方法1:
TestModel tm = new TestModel();
BeanWrapper bw = new BeanWrapperImpl(tm);
bw.setPropertyValue("good", "on");
System.out.println(tm);
good是boolean属性,使用BeanWrapperImpl设置属性的时候,内部会使用类型转换(父类TypeConverterSupport提供),将String类型转换为boolean,CustomBooleanEditor对于String值是on,1,true,yes都会转换为true,本文介绍PropertyEditorRegistrySupport的时候说明过,CustomBooleanEditor属于默认的属性编辑器。
测试方法2:
TestModel tm = new TestModel();
BeanWrapperImpl bw = new BeanWrapperImpl(false);
bw.setWrappedInstance(tm);
bw.setPropertyValue("good", "1");
System.out.println(tm);
不使用默认的属性编辑器进行类型转换。 很明显,这段代码报错了,没有找到合适的属性编辑,String类型不能作为boolean类型的值。
错误信息:Failed to convert property value of type 'java.lang.String' to required type 'boolean' for property 'good';&
测试方法3:
TestModel tm = new TestModel();
BeanWrapper bw = new BeanWrapperImpl(tm);
bw.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
bw.setPropertyValue("birth", "");
System.out.println(tm);
默认属性编辑器中并没有日期类型的属性编辑器,我们注册一个Spring提供的CustomDateEditor属性编辑器,对应Date对象,并且为空。有了CustomDateEditor,设置birth的时候会通过类型转换自动转化成Date对象。
关于其他属性的设置,读者自行测试吧。
本文所使用的Spring版本是4.0.2
在分析RequestParamMethodArgumentResolver处理请求参数之前,我们简单回顾一下SpringMVC是如何对http请求进行处理的。
HandlerAdapter会对每个请求实例化一个ServletInvocableHandlerMethod对象进行处理,我们仅看下WebDataBinderFactory的构造过程。
WebDataBinderFactory接口是一个创建WebDataBinder的工厂接口。
以如下方法为例:
public ModelAndView test(boolean b, ModelAndView view) {
view.setViewName("test/test");
view.addObject("attr", "b is true");
view.addObject("attr", "b is false");
楼主在另外一篇博客中已经分析,boolean类型的参数会被RequestParamMethodArgumentResolver这个HandlerMethodArgumentResolver处理。
下面我们进入RequestParamMethodArgumentResolver看看是如何处理的。
RequestParamMethodArgumentResolver的resolveArgument方法是由它的父类AbstractNamedValueMethodArgumentResolver中定义的:
ServletRequestDataBinderFactory创建ExtendedServletRequestDataBinder。
ExtendedServletRequestDataBinder属于DataBinder的子类。
我们在介绍重要接口的时候说过DataBinder进行类型转换的时候内部会使用SimpleTypeConverter进行数据转换。
下面看看测试:
CustomBooleanEditor处理ohmygod会抛出IllegalArgumentException。 最终被截获处理成http 400错误。
PS:以上例子boolean类型改成Boolean类型的话,不传参数的话b就是null,我们解释默认属性编辑器的时候Boolean类型的参数是允许空的。但是boolean类型不传参数的话,默认会是false,而不会抛出异常。 原因就是resolveArgument方法中handleNullValue处理null值,spring进行了特殊的处理,如果参数类型是boolean的话,取false。 读者可以试试。
再看看个例子:
public ModelAndView testObj(Employee e, ModelAndView view) {
view.setViewName("test/test");
view.addObject("attr", e.toString());
该方法会被ServletModelAttributeMethodProcessorr这个HandlerMethodArgumentResolver处理。
ServletModelAttributeMethodProcessorr的resolveArgument方法是由它的父类ModelAttributeMethodProcessor中定义的:
&这里WebDataBinder方法bind中会使用BeanWrapper构造对象,然后设置对应的属性。BeanWrapper本文已介绍过。
编写自定义的属性编辑器
Spring提供的编辑器肯定不会满足我们日常开发的功能,因此开发自定义的属性编辑器也是很有必要的。
下面我们就写1个自定义的属性编辑器。
public class CustomDeptEditor extends PropertyEditorSupport {
public void setAsText(String text) throws IllegalArgumentException {
if(text.indexOf(",") & 0) {
Dept dept = new Dept();
String[] arr = text.split(",");
dept.setId(Integer.parseInt(arr[0]));
dept.setName(arr[1]);
setValue(dept);
throw new IllegalArgumentException("dept param is error");
SpringMVC中使用自定义的属性编辑器有3种方法:
1. Controller方法中添加@InitBinder注解的方法
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Dept.class, new CustomDeptEditor());
2. 实现WebBindingInitializer接口
public class MyWebBindingInitializer implements WebBindingInitializer {
public void initBinder(WebDataBinder binder, WebRequest request) {
binder.registerCustomEditor(Dept.class, new CustomDeptEditor());
之前分析源码的时候,HandlerAdapter构造WebDataBinderFactory的时候,会传递HandlerAdapter的属性webBindingInitializer。
因此,我们在配置文件中构造RequestMappingHandlerAdapter的时候传入参数webBindingInitializer。
3. @ControllerAdvice注解
@ControllerAdvice
public class InitBinderControllerAdvice {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Dept.class, new CustomDeptEditor());
加上ControllerAdvice别忘记配置文件component-scan需要扫描到这个类。
最终结果:
分析了Spring的数据转换功能,并解释这个神奇的转换功能是如何实现的,之后编写了自定义的属性编辑器。
大致讲解了下Spring类型转换中重要的类及接口。
SpringMVC这个系列目前准备在写3篇,拦截器、HandlerAdapter和视图。希望本系列文章对读者有帮助。
文章难免会出现错误,希望读者能够指出。
阅读(...) 评论()
随笔 - 16439
评论 - 1502springController:
@Controller&&
@RequestMapping("/user")&&
public&UserController&extends&BaseController{&&
&&&&@RequestMapping("/addUser")&&&&
&&&&public&void&testBinderOuput(@ModelAttribute&User&user,&HttpServletRequest&request,&HttpServletResponse&response){&&&&
&&&&&&&&System.out.println(user);&&&&
public&Class&User{&&
&&&&private&String&&&&&&&
&&&&private&int&&&&&&&
&&&&private&String&&&
&&&&private&int&&&
&&&&public&int&getSex()&{&&
&&&&&&&&return&&&
&&&&public&void&setSex(int&sex)&{&&
&&&&&&&&this.sex&=&&&
&&&&public&String&getAddress()&{&&
&&&&&&&&return&&&
&&&&public&void&setAddress(String&address)&{&&
&&&&&&&&this.address&=&&&
&&&&public&int&getId()&{&&
&&&&&&&&return&&&
&&&&public&void&setId(int&id)&{&&
&&&&&&&&this.id&=&&&
&&&&public&void&setName(String&name)&{&&
&&&&&&&&this.name&=&&&
请求路径:localhost/user/addUser?user.name="test"那么在后台接受到的参数中,user对象的name属性是null。如果路径换为localhost/user/addUser?name="test",则user对象的name属性是test。这里必须用name="test"而不是user.name="test",因为默认情况下springMVC是不支持user.name这种传参方式的。
如果有个对象manager中也有name这个相同的属性,那么可以采用user.name,manager.name来传输参数。但是这个需要在controller中添加一个前缀绑定:
添加绑定前缀后的controller类如下:
@Controller&&
@RequestMapping("/user")&&
public&UserController&extends&BaseController{&&
&&&&@InitBinder("manager")&&&&
&&&&public&void&initBinder1(WebDataBinder&binder)&{&&&&
&&&&&&&&&&&&binder.setFieldDefaultPrefix("manager.");&&&&
&&&&@InitBinder("user")&&&&
&&&&public&void&initBinder2(WebDataBinder&binder)&{&&&&
&&&&&&&&&&&&binder.setFieldDefaultPrefix("user.");&&&&
&&&&@RequestMapping("/addUser")&&&&
&&&&public&void&testBinderOuput(@ModelAttribute&User&user,&HttpServletRequest&request,&HttpServletResponse&response){&&&&
&&&&&&&&System.out.println(user.getName);&&&&
&&&&@RequestMapping("/addManager")&&&&
&&&&public&void&testBinderOuput(@ModelAttribute&Manager&manager,&HttpServletRequest&request,&HttpServletResponse&response){&&&&
&&&&&&&&System.out.println(manager.getName);&&&&
这样在使用连接localhost/user/addUser?user.name="test",去请求时,后台拿到的name的参数就不为null了。有个专门讨论这个问题的主题:http://www.iteye.com/topic/1124433?page=2可以参考下
阅读(...) 评论()求大神指教,我用springmvc接收页面上的form表单参数,表单里的参数都是对应一个类的字段,我在后台怎么操作才能直接用这个类的对象获取到页面传过来的参数呢【java吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:694,644贴子:
求大神指教,我用springmvc接收页面上的form表单参收藏
求大神指教,我用springmvc接收页面上的form表单参数,表单里的参数都是对应一个类的字段,我在后台怎么操作才能直接用这个类的对象获取到页面传过来的参数呢?
java,博为峰java培训,贯穿式课程体系,保证学员胜任企业岗位需求,0元入学.java,0基础120天 成就java牛人,抢!!!java课程免费试听名额,IT总监名师主讲!
直接在方法的括号里写上这个类
表单字段名和类成员名对应上
直接用类对象接收
登录百度帐号如何让Spring MVC接收的参数可以转换为java对象_百度知道
如何让Spring MVC接收的参数可以转换为java对象
我有更好的答案
controller的参数这样写就行了@RequestBody User user接收的时候会帮你自动装填的
性能测试工程师
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 如何让qq自动接收文件 的文章

 

随机推荐