SpringMVC:学习笔记(6)——转换器和格式化
转换器和格式化
说明
SpringMVC的数据绑定并非没有限制,有案例表明,在SpringMVC如何正确绑定数据方面是杂乱无章的,比如在处理日期映射到Date对象上。
为了能够让SpringMVC进行正确地数据绑定,我们需要用到Converter和Formatter来协助SpringMVC完成。
举例:
我们知道HTTP表单中的所有请求参数都是String类型的,而且日期时间数据没有特定的形式1997-3-20,1997:03:20乃至20/03/1997对于我们人来说都是正确的形式都应该可以映射到Date对象上,但对于计算机来说都是陌生的,我们就要构建一种桥梁,来让计算机正确绑定数据。
Converter和Formatter都可以用于将一种对象类型转换成另一种对象类型。
区别:
Converter是通用元件,可以在应用程序的任意层使用。
Formatter是专用元件,专门为Web层设计。
Converter
说明
Converter转换器可以进行格式转换,这是一种通用的元件。下面我们要实现的效果是:
按照图示所示的日期格式让SpringMVC可以识别并转换成Date对象。
编写Converter步骤:
1.编写一个实现了org.springframework.core.convert.converter.Converter接口的Java类。
public class MyConverter implements Converter<String,Date> { //<源类型,目标类型> private String dataPattern; public MyConverter(String dataPattern) { this.dataPattern=dataPattern; System.out.println("DataPattern is"+dataPattern); } public Date convert(String s) { try { SimpleDateFormat simpleDateFormat= new SimpleDateFormat(dataPattern); simpleDateFormat.setLenient(false); //设置日期/时间的解析是否不严格,为false表示严格 return simpleDateFormat.parse(s); } catch (ParseException e) { e.printStackTrace(); } return null; } }
2.在SpringMVC的配置文件中编写一个ConversionService bean.
说明:
Bean的类名称必须是org.springframework.context.support.ConversionServiceFactoryBean.
这个Bean必须包含一个converters属性,它将列出在应用程序中用到的所有定制Converter.
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="converter.MyConverter"> <constructor-arg type="java.lang.String" value="MM-dd-yyyy"/> </bean> </list> </property> </bean>
3.要给annotation-driven元素的conversion-service属性赋bean名称
<?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: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.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-3.0.xsd "> <context:component-scan base-package="controller"/> <context:component-scan base-package="Service"/> <!-- <mvc:annotation-driven>元素注册用于支持基于注解的控制器的请求处理方法的Bean对象。 详解:https://my.oschina.net/HeliosFly/blog/205343 --> <mvc:annotation-driven conversion-service="conversionService"/> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="converter.MyConverter"> <constructor-arg type="java.lang.String" value="MM-dd-yyyy"/> </bean> </list> </property> </bean> </beans>
其余代码
1.编写控制器
package controller; import domain.Employee; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; /** * Created by zy on 17-3-3. */ @Controller public class EmployeeController { private static final Log logger = LogFactory.getLog(EmployeeController.class); @RequestMapping("employ_input") public String inputEmployee(Model model) { model.addAttribute("employee",new Employee()); return "EmployeeForm"; } @RequestMapping("employ_save") public String saveEmployee(@ModelAttribute Employee employee,BindingResult bindingResult,Model model) { if(bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); logger.info("Code:" +fieldError.getCode()+",field"+fieldError.getField()); return "EmployeeForm"; } model.addAttribute("employee",employee); return "EmployeeForm"; } }
2.编写视图
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>EmployeeInput</title> </head> <body> <form:form commandName="employee" action="employ_save" method="post"> <legend>Add Employee</legend> <p> <label for="firstName">姓</label> <form:input path="firstName" tabindex="1"/> </p> <p> <label for="lastName">名</label> <form:input path="lastName" tabindex="2"/> </p> <p> <form:errors path="birthDate" cssClass="error"/> </p> <p> <label for="birthDate">出生日期</label> <form:input path="birthDate" tabindex="3"/> </p> <p> <input type="submit" value="Add Employee"> </p> </form:form> </body> </html>
Formatter
说明
Formatter就像Converter一样,也是将一种类型转换成另外一种类型。但是,Formatter的源类型必须是String,而Converter则适用于任意的源类型。
Formatter更适合在Web层使用,处理表单输入,始终应该选择Formatter,而不是Converter。
编写Formatter
1.编写一个实现了org.springframework.format.Formatter接口的Java类。
2.在SpringMVC的配置文件中编写一个ConversionService bean.
<?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: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.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-3.0.xsd "> <context:component-scan base-package="controller"/> <context:component-scan base-package="Service"/> <!-- <mvc:annotation-driven>元素注册用于支持基于注解的控制器的请求处理方法的Bean对象。 详解:https://my.oschina.net/HeliosFly/blog/205343 --> <mvc:annotation-driven conversion-service="conversionService"/> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"/> <property name="suffix" value=".jsp"/> </bean> <!--需要配置此项来扫描Formatter--> <context:component-scan base-package="formatter"/> <bean id="formatterConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <set> <bean class="formatter.DateFormatter"> <constructor-arg type="java.lang.String" value="MM-dd-yyyy"/> </bean> </set> </property> </bean> </beans>
选择Converter还是Formatter
在SpringMVC应用程序中当然是Formatter更合适~\(≧▽≦)/~啦啦啦