轉換器和格式化
說明
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更合適~\(≧▽≦)/~啦啦啦
