输入绑定的各种情况:
1、多参数接收数据
<form action="<%=path%>/users/regist" method="post">
用户名:<input type="text" name="userName" />
登录名:<input type="text" name="loginName" />
码:<input type="password" name="password" />
性别:<input type="radio" name="gender" value="0" checked="checked" />女
<input type="radio" name="gender" value="1" />男
个人收入:<input type="text" name="income" />
是否婚配:<input type="radio" name="marry" value="true" checked="checked" />已婚
<input type="radio" name="marry" value="false" />未婚
出生日期:<td><input type="text" name="birthday" /></td>
个人爱好:<input type="checkbox" name="hobby" value="0" />吃
<input type="checkbox" name="hobby" value="1" />喝
<input type="checkbox" name="hobby" value="2" />嫖
<input type="checkbox" name="hobby" value="3" />赌
<input type="checkbox" name="hobby" value="4" />抽
<input type="checkbox" name="hobby" value="5" />坑
<input type="checkbox" name="hobby" value="6" />蒙
<input type="checkbox" name="hobby" value="7" />拐
<input type="checkbox" name="hobby" value="8" />骗
<input type="checkbox" name="hobby" value="9" />偷
<input type="submit" value="注册" />
</form>
从表单传下来的数据要在后台接收到,就要进行数据绑定,用这种多参数接收数据的话,在后台方法中的参数的名字必须和页面中对应的每个提交项的名字保持一致(就是上面的name属性的值),否则接收不到
@RequestMapping(value="/regist")
public ModelAndView regist(String userName,String loginName,String password,int gender,boolean marry,double income,int[] hobby) {
log.info("UserController-----regist()",birthday);
log.info("UserController-----regist()",userName);
log.info("UserController-----regist()",loginName);
log.info("UserController-----regist()",password);
log.info("UserController-----regist()",gender);
log.info("UserController-----regist()",marry);
log.info("UserController-----regist()",income);
log.info("UserController-----regist()",Arrays.toString(hobby));
ModelAndView mv = new ModelAndView("/index");
return mv;
}
表单提交数据的方式,后台方法接受数据的参数可以是基本数据类型、String、对象、数组、Data等,但是List、Set、Map必须在对象中才能生效。
2、对象接收数据
@RequestMapping(value="/regist02")
public ModelAndView regist02(UserBean user) {
log.info("UserController-----regist02()", user);
ModelAndView mv = new ModelAndView("/index");
return mv;
}
<form action="<%=path%>/users/regist02" method="post">
用户名:<input type="text" name="userName" />
登录名:<input type="text" name="loginName" />
码:<input type="password" name="password" />
性别:<input type="radio" name="gender" value="0" checked="checked" />女
<input type="radio" name="gender" value="1" />男
个人收入:<input type="text" name="income" />
是否婚配:<input type="radio" name="marry" value="true" checked="checked" />已婚
<input type="radio" name="marry" value="false" />未婚
出生日期:<td><input type="text" name="birthday" /></td>
个人爱好:<input type="checkbox" name="hobby" value="0" />吃
<input type="checkbox" name="hobby" value="1" />喝
<input type="checkbox" name="hobby" value="2" />嫖
<input type="checkbox" name="hobby" value="3" />赌
<input type="checkbox" name="hobby" value="4" />抽
<input type="checkbox" name="hobby" value="5" />坑
<input type="checkbox" name="hobby" value="6" />蒙
<input type="checkbox" name="hobby" value="7" />拐
<input type="checkbox" name="hobby" value="8" />骗
<input type="checkbox" name="hobby" value="9" />偷
家庭住址01:<input type="text" name="adds[0]" />
家庭住址02:<input type="text" name="adds[1]" />
家庭住址03:<input type="text" name="adds[2]" />
小孩01:<input type="text" name="childs[0].childrenName" />
小孩02:<input type="text" name="childs[1].childrenName" />
小孩03:<input type="text" name="childs[2].childrenName" />
联系方式01:<input type="text" name="map['tel01']" />
联系方式02:<input type="text" name="map['tel02']" />
联系方式03:<input type="text" name="map['tel03']" />
角色选择:<select name="role.id">
<option value="1">农夫</option>
<option value="2">地主</option>
<option value="3">屠夫</option>
<option value="4">酒鬼</option>
</select>
<input type="submit" value="注册" />
</form>
如果用对象来接收的话,同样的对象里属性名必须和页面中对应的每个提交项的名字保持一致(就是上面的name属性的值),否则接收不到
接收数据的对象UserBean(属性展示):
private String loginName;
private String userName;
private String password;
private Date birthday;
private int age;
private int gender;
private double income;
private boolean marry;
private int[] hobby;
private List<String> adds = new ArrayList<String>();
private Set<ChildrenBean> childs = new HashSet<ChildrenBean>();
private Map<String,String> map = new HashMap<>();
private RoleBean role;
值得注意的是,上面我已经说了,如果要用List、Set、Map接收数据,必须在对象中才能生效。
在使用这三个类型接收数据的时候,也有要注意的地方,下面我进行说明:
1、List接收数据
家庭住址01:<input type="text" name="adds[0]" />
家庭住址02:<input type="text" name="adds[1]" />
家庭住址03:<input type="text" name="adds[2]" />
private List<String> adds = new ArrayList<String>();
可以看到,用list接收数据的时候,页面的提交项的name属性的值必须写成 “属性名[下标]” 的形式,后台才能接收到数据
2、Set接收数据
小孩01:<input type="text" name="childs[0].childrenName" />
小孩02:<input type="text" name="childs[1].childrenName" />
小孩03:<input type="text" name="childs[2].childrenName" />
private Set<ChildrenBean> childs = new HashSet<ChildrenBean>();
public UserBean() {
super();
// TODO Auto-generated constructor stub
//set必须要初始化childs的个数
childs.add(new ChildrenBean());
childs.add(new ChildrenBean());
childs.add(new ChildrenBean());
}
可以看到我们用Set的话必须初始化Set中对象的个数,List和Map就不需要进行初始化个数,页面的提交项的name属性的值必须写成 “属性名[下标]包含对象的属性名” 的形式,后台才能接收到数据
3、Map接收数据
联系方式01:<input type="text" name="map['tel01']" />
联系方式02:<input type="text" name="map['tel02']" />
联系方式03:<input type="text" name="map['tel03']" />
private Map<String,String> map = new HashMap<>();
可以看到用Map接收数据,页面提交项的name属性必须写成 “属性名[键名] ” 的形式,在后台才能通过键名拿到值。
4、对象中的对象
角色选择:<select name="role.id">
<option value="1">农夫</option>
<option value="2">地主</option>
<option value="3">屠夫</option>
<option value="4">酒鬼</option>
</select>
private RoleBean role;
可以看到,对象中的对象,要接收到数据,页面提交项的name属性要写成 “属性名.包含对象的属性名”
类型转换的情况
有些情况下,SpringMVC中有些类型的数据没有进行自动转换的功能,所以还得手写转换器。下面就介绍String转Data。
一、本类中使用
手写转换规则的类:(继承PropertyEditorSupport,重写setAsText(String text)方法)
public class CustomDateEditor extends PropertyEditorSupport {
/**
* 解析Date类型的数据,从text中,使用特定的转换规则
*/
@Override
public void setAsText(String text) throws IllegalArgumentException {
// TODO Auto-generated method stub
if (StringUtils.hasLength(text)) {
Date date = null;
SimpleDateFormat sdf = null;
int lenth = text.length();// 获取字符串的长度
switch (lenth) {
case 10:
sdf = new SimpleDateFormat("yyyy-MM-dd");
break;
case 19:
sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
break;
default:
String msg = text + ",参数的长度不合法!";
throw new IllegalArgumentException(msg);
}
try {
date = sdf.parse(text);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setValue(date);
return;
}
setValue(null);
}
}
再在需要使用的类中定义一个方法,传入WebDataBinder类,用它来绑定我们自己写的转换类(new一个我们自己的类)
@RequestMapping("/users")
@Controller
public class UserController {
private Logger log = LoggerFactory.getLogger(this.getClass());
/**
* 自定义一个属性绑定规则
* 只针对当前类有限
* @param binder
*/
@InitBinder
public void str2dateConverter(WebDataBinder binder) {
//定义表单数据在向Date类型转换时,需要使用new CustomDateEditor() 所定义的转换规则
binder.registerCustomEditor(Date.class, new CustomDateEditor());
}
@RequestMapping(value="/regist")
public ModelAndView regist(Date birthday,String userName,String loginName,String password,int gender,boolean marry,double income,int[] hobby) {
log.info("UserController-----regist()",birthday);
log.info("UserController-----regist()",userName);
log.info("UserController-----regist()",loginName);
log.info("UserController-----regist()",password);
log.info("UserController-----regist()",gender);
log.info("UserController-----regist()",marry);
log.info("UserController-----regist()",income);
log.info("UserController-----regist()",Arrays.toString(hobby));
ModelAndView mv = new ModelAndView("/index");
return mv;
}
}
二、整个程序中使用
首先定义一个转换类(实现Converter接口,<String, Date>表示什么转什么类型)页面上的数据传到后台都是字符串的形式,然后再去实现convert方法就可以了,text表示页面传入的数据
/**
* 字符串转换为日期的转换类
* @author Administrator
*
*/
public class StringToDateConverter implements Converter<String, Date> {
@Override
public Date convert(String text) {
// TODO Auto-generated method stub
Date date = null;
if (StringUtils.hasLength(text)) {
SimpleDateFormat sdf = null;
int lenth = text.length();// 获取字符串的长度
switch (lenth) {
case 10:
sdf = new SimpleDateFormat("yyyy-MM-dd");
break;
case 19:
sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
break;
default:
String msg = text + ",参数的长度不合法!";
throw new IllegalArgumentException(msg);
}
try {
date = sdf.parse(text);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return date;
}
}
然后向自己写的spring-mvc配置文件中去注册:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 开启spring容器的自动扫描功能 -->
<context:component-scan base-package="com.ge.springmvcanno"></context:component-scan>
<!-- 开启springmvc的注解支持 -->
<!-- conversion-service="conversionService" 告知springmvc使用conversionService里面的转换规则 -->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 指定静态资源文件的位置 -->
<mvc:resources location="/static/" mapping="/static/**"></mvc:resources>
<!-- 定义spring框架的转换工厂,并且向转换工厂中注册"自定义的转换器"-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.ge.springmvcanno.converter.StringToDateConverter"></bean>
</set>
</property>
</bean>
<!-- 不再需要配置处理映射器,因为框架会自动使用 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
去根据我们定义的@RequestMapping该注解,完成"请求路径"到"处理该请求方法"之间的映射关系 -->
<!-- 不再需要配置处理适配器,因为框架会自动使用 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
去根据我们定义的@RequestMapping该注解,完成"Servlet数据"到"Controller数据"之间的数据适配 -->
<!-- 配置视图解析器 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<!-- 前缀 -->
<property name="prefix" value="/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>