当前台传数据给spring的control时,如果后台方法的参数或参数对象的对应属性是基本类型或者string类型时,前台值自动的注入到后台方法参数或对象属性中。如果方法参数或对象属性不是基本类型或string,比如是date类型,则不能直接赋值。
解决方法有一下三种:
一、使用注解
<mvc:annotation-driven />
2、在参数或对象属性上添加注解
如:如果是date类型可以添加@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd") 可将形如1980-0-01的字符串转换到Date类
@NumberFormat(pattern="#,###.##") 可将形如4,500.00的字符串转换成long类型
. . .
此种方法缺点:如要在每一个参上加个注解,如果实体类改变,则注解可能也需要添加修改,比如通过mybatis逆向工程成的实体类是不带注解的,如果项目需要修改了表,重新生产实体类,则需要重新添加注解,比较麻烦,且容易出错。
二、Controller中使用SpringMVC的注解@initbinder
和Spring自带的WebDateBinder
类来操作
1、在springmvc配置文件中开启注解<mvc:annotation-driven />
2、WebDataBinder是用来绑定请求参数到指定的属性编辑器.由于前台传到controller里的值是String类型的,当往Model里Set这个值的时候,如果set的这个属性是个对象,Spring就会去找到对应的editor进行转换,然后再set进去。
代码如下:在自己的Controller代码中加入:
1 @InitBinder
2 protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) {
3 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
4 simpleDateFormat.setLenient(false);
5 CustomDateEditor dateEditor = new CustomDateEditor(simpleDateFormat, true);
6 binder.registerCustomEditor(Date.class, dateEditor);
7 } spring mvc在绑定表单之前,都会先注册这些编辑器,Spring自己提供了大量的实现类,诸如CustomDateEditor ,CustomBooleanEditor,CustomNumberEditor等许多,基本上够用。
spring mvc在绑定表单之前,都会先注册这些编辑器,Spring自己提供了大量的实现类,诸如CustomDateEditor ,CustomBooleanEditor,CustomNumberEditor等许多,基本上够用。
使用时候调用WebDataBinder的registerCustomEditor方法registerCustomEditor源码:
public void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor) {
getPropertyEditorRegistry().registerCustomEditor(requiredType, propertyEditor);
}
第一个参数requiredType是需要转化的类型。
第二个参数PropertyEditor是属性编辑器,它是个接口,以上提到的如CustomDateEditor等都是继承了实现了这个接口的PropertyEditorSupport类。
我们也可以不使用他们自带的这些编辑器类。
我们可以构造自己的:
import org.springframework.beans.propertyeditors.PropertiesEditor;
public class DoubleEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (text == null || text.equals("")) {
text = "0";
}
setValue(Double.parseDouble(text));
}
@Override
public String getAsText() {
return getValue().toString();
}
}
此种方法作用预为本control,但是可以针对整个项目,像实例一样抽出公共BaseController,让所有的controller继承BaseController,即可
1 @Controller
2 public class BaseController {
3 @InitBinder
4 protected void initBinder(WebDataBinder binder) {
5 binder.registerCustomEditor(Date.class, new MyDateEditor());
6 /*
7 从PropertyEditorSupport 实现的方法可以看出,这里的绑定是为了处理空和null的数据,
8 开发者可根据实际情况绑定
9 */
10 binder.registerCustomEditor(Double.class, new DoubleEditor());
11 binder.registerCustomEditor(Integer.class, new IntegerEditor());
12 }
13
14 private class MyDateEditor extends PropertyEditorSupport {
15 @Override
16 public void setAsText(String text) throws IllegalArgumentException {
17 //通过两次异常的处理可以,绑定两次日期的格式
18 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
19 Date date = null;
20 try {
21 date = format.parse(text);
22 } catch (ParseException e) {
23 format = new SimpleDateFormat("yyyy-MM-dd");
24 try {
25 date = format.parse(text);
26 } catch (ParseException e1) {
27 log.error("系统异常:"+e1);
28 }
29 }
30 setValue(date);
31 }
32 }
33
34 public class DoubleEditor extends PropertiesEditor {
35 @Override
36 public void setAsText(String text) throws IllegalArgumentException {
37 try {
38 if (text == null || text.equals("")) {
39 text = "0";
40 }
41 } catch (Exception e) {
42 log.error("系统异常:"+e);
43 }
44
45 setValue(Double.parseDouble(text));
46 }
47
48 @Override
49 public String getAsText() {
50 return getValue().toString();
51 }
52 }
53
54 public class IntegerEditor extends PropertiesEditor {
55 @Override
56 public void setAsText(String text) throws IllegalArgumentException {
57 try {
58 if (text == null || text.equals("")) {
59 text = "0";
60 }
61 } catch (Exception e) {
62 log.error("系统异常:"+e);
63 }
64
65 setValue(Integer.parseInt(text));
66 }
67
68 @Override
69 public String getAsText() {
70 return getValue().toString();
71 }
72 }
73 }
三、定义的类型转换类
1、自定义类型转换规则
SpringMvc提供了Converter接口,它支持从一个Object转换为另一个Object
1 public class DateConvert implements Converter<String, Date> {
2
3 @Override
4 public Date convert(String stringDate) {
5 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
6 try {
7 return simpleDateFormat.parse(stringDate);
8 } catch (ParseException e) {
9 e.printStackTrace();
10 }
11 return null;
12 }
13
14 }
2、注册自定义的类型转换类
1 <!-- 第一步: 创建自定义日期转换规则 -->
2 <bean id="dateConvert" class="zpark.convert.DateConvert"/>
3 <!-- 第二步: 创建convertion-Service ,并注入dateConvert-->
4 <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
5 <property name="converters">
6 <set>
7 <ref bean="dateConvert"/>
8 </set>
9 </property>
10 </bean>
11 <!-- 第三步:注册处理器映射器/处理器适配器 ,添加conversion-service属性-->
12 <mvc:annotation-driven conversion-service="conversionService"/>