1.Converter:转换器 :可以在应用程序的任意层中使用
2.Formatter格式化:专门为Web设计
二者都可以将一种对象转换成另一种对象类型
1.Converter
必须实现org.springframework.core.convert.converter.Converter
public interface Converter<S,T>
S:是源类型
T:是目标类型
在类Body中,需要编写一个来自Converter接口的convert方法实现。
T convert(S source);
1 package app06a.converter; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 import org.springframework.core.convert.converter.Converter; 8 9 public class StringToDateConverter implements Converter<String, Date> { 10 11 private String datePattern; 12 13 public StringToDateConverter(String datePattern) { 14 this.datePattern = datePattern; 15 } 16 17 @Override 18 public Date convert(String s) { 19 try { 20 SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern); 21 dateFormat.setLenient(false); 22 return dateFormat.parse(s); 23 } catch (ParseException e) { 24 // the error message will be displayed when using <form:errors> 25 throw new IllegalArgumentException( 26 "invalid date format. Please use this pattern"" 27 + datePattern + """); 28 } 29 } 30 }
为了使用SpringMVC应用程序中定制Converter
需要在Spring MVC配置文件中编写converterService bean
Bean的类名称为org.springframework.context.support.ConversionServiceFactoryBean
这个Bean必须包含一个converts属性,它将列出要在应用程序中使用所有定制的Converter
要给<mvc:annotation-driven conversion-service="conversionService"/>
conversion-service属性赋bean名称
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xmlns:mvc="http://www.springframework.org/schema/mvc" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xsi:schemaLocation=" 8 http://www.springframework.org/schema/beans 9 http://www.springframework.org/schema/beans/spring-beans.xsd 10 http://www.springframework.org/schema/mvc 11 http://www.springframework.org/schema/mvc/spring-mvc.xsd 12 http://www.springframework.org/schema/context 13 http://www.springframework.org/schema/context/spring-context.xsd"> 14 15 <context:component-scan base-package="app06a.controller"/> 16 17 <mvc:annotation-driven conversion-service="conversionService"/> 18 <mvc:resources mapping="/css/**" location="/css/"/> 19 <mvc:resources mapping="/*.html" location="/"/> 20 21 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 22 <property name="prefix" value="/WEB-INF/jsp/"/> 23 <property name="suffix" value=".jsp"/> 24 </bean> 25 26 <bean id="conversionService" 27 class="org.springframework.context.support.ConversionServiceFactoryBean"> 28 <property name="converters"> 29 <list> 30 <bean class="app06a.converter.StringToDateConverter"> 31 <constructor-arg type="java.lang.String" value="MM-dd-yyyy"/> 32 </bean> 33 </list> 34 </property> 35 </bean> 36 </beans>
Employee类
1 package app06a.domain; 2 3 import java.io.Serializable; 4 import java.util.Date; 5 6 public class Employee implements Serializable { 7 private static final long serialVersionUID = -908L; 8 9 private long id; 10 private String firstName; 11 private String lastName; 12 private Date birthDate; 13 private int salaryLevel; 14 15 public long getId() { 16 return id; 17 } 18 19 public void setId(long id) { 20 this.id = id; 21 } 22 23 public String getFirstName() { 24 return firstName; 25 } 26 27 public void setFirstName(String firstName) { 28 this.firstName = firstName; 29 } 30 31 public String getLastName() { 32 return lastName; 33 } 34 35 public void setLastName(String lastName) { 36 this.lastName = lastName; 37 } 38 39 public Date getBirthDate() { 40 return birthDate; 41 } 42 43 public void setBirthDate(Date birthDate) { 44 this.birthDate = birthDate; 45 } 46 47 public int getSalaryLevel() { 48 return salaryLevel; 49 } 50 51 public void setSalaryLevel(int salaryLevel) { 52 this.salaryLevel = salaryLevel; 53 } 54 55 }
Controller
有了StringToDateConverter converter,就不需要劳驾
controller类将字符串转换成日期了
1 package app06a.controller; 2 3 import org.apache.commons.logging.Log; 4 import org.apache.commons.logging.LogFactory; 5 import org.springframework.ui.Model; 6 import org.springframework.validation.BindingResult; 7 import org.springframework.validation.FieldError; 8 import org.springframework.web.bind.annotation.ModelAttribute; 9 import org.springframework.web.bind.annotation.RequestMapping; 10 11 import app06a.domain.Employee; 12 13 @org.springframework.stereotype.Controller 14 15 public class EmployeeController { 16 17 private static final Log logger = LogFactory.getLog(ProductController.class); 18 19 @RequestMapping(value="employee_input") 20 public String inputEmployee(Model model) { 21 model.addAttribute(new Employee()); 22 return "EmployeeForm"; 23 } 24 25 @RequestMapping(value="employee_save") 26 public String saveEmployee(@ModelAttribute Employee employee, BindingResult bindingResult, 27 Model model) { 28 if (bindingResult.hasErrors()) { 29 FieldError fieldError = bindingResult.getFieldError(); 30 logger.info("Code:" + fieldError.getCode() 31 + ", field:" + fieldError.getField()); 32 return "EmployeeForm"; 33 } 34 35 // save employee here 36 37 model.addAttribute("employee", employee); 38 return "EmployeeDetails"; 39 } 40 }
1 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 2 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 3 <!DOCTYPE HTML> 4 <html> 5 <head> 6 <title>Add Employee Form</title> 7 <style type="text/css">@import url("<c:url value="/css/main.css"/>");</style> 8 </head> 9 <body> 10 11 <div id="global"> 12 <form:form commandName="employee" action="employee_save" method="post"> 13 <fieldset> 14 <legend>Add an employee</legend> 15 <p> 16 <label for="firstName">First Name: </label> 17 <form:input path="firstName" tabindex="1"/> 18 </p> 19 <p> 20 <label for="lastName">First Name: </label> 21 <form:input path="lastName" tabindex="2"/> 22 </p> 23 <p> 24 <form:errors path="birthDate" cssClass="error"/> 25 </p> 26 <p> 27 <label for="birthDate">Date Of Birth: </label> 28 <form:input path="birthDate" tabindex="3" /> 29 </p> 30 <p id="buttons"> 31 <input id="reset" type="reset" tabindex="4"> 32 <input id="submit" type="submit" tabindex="5" 33 value="Add Employee"> 34 </p> 35 </fieldset> 36 </form:form> 37 </div> 38 </body> 39 </html>
2.Formatter
Formatter也是将一种类型转换成另一种类型
但Formatter源类型必须是一个String,而Converter则适用于任意的源类型
为了创建Formmatter要编写一个org.springframework.format.Formatter接口的java类
public interface Formatter<T>
这里T表示输入字符串要转换的目标类型
T parse(String text,java.util.Locale.locale);
String print(T object,java.util.Locale.locale);
1 package app06b.formatter; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 import java.util.Locale; 7 8 import org.springframework.format.Formatter; 9 10 public class DateFormatter implements Formatter<Date> { 11 12 private String datePattern; 13 private SimpleDateFormat dateFormat; 14 15 public DateFormatter(String datePattern) { 16 System.out.println("DateFormatter()5b========"); 17 this.datePattern = datePattern; 18 dateFormat = new SimpleDateFormat(datePattern); 19 dateFormat.setLenient(false); 20 } 21 22 @Override 23 public String print(Date date, Locale locale) { 24 return dateFormat.format(date); 25 } 26 27 @Override 28 public Date parse(String s, Locale locale) throws ParseException { 29 try { 30 return dateFormat.parse(s); 31 } catch (ParseException e) { 32 // the error message will be displayed when using <form:errors> 33 throw new IllegalArgumentException( 34 "invalid date format. Please use this pattern"" 35 + datePattern + """); 36 } 37 } 38 }
为了在String MVC应用程序中使用Formmatter,需要利用conversionService bean
进行注册。
bean的类名称必须为org.springframework.format.support.FormattingConversionServiceFactoryBean.
还需要给Formatter添加一个<context:component-scan base-package="app06b.formatter" />
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation=" 6 http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/mvc 9 http://www.springframework.org/schema/mvc/spring-mvc.xsd 10 http://www.springframework.org/schema/context 11 http://www.springframework.org/schema/context/spring-context.xsd"> 12 13 <context:component-scan base-package="app06b.controller" /> 14 <context:component-scan base-package="app06b.formatter" /> 15 16 <mvc:annotation-driven conversion-service="conversionService" /> 17 18 <mvc:resources mapping="/css/**" location="/css/" /> 19 <mvc:resources mapping="/*.html" location="/" /> 20 21 <bean id="viewResolver" 22 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 23 <property name="prefix" value="/WEB-INF/jsp/" /> 24 <property name="suffix" value=".jsp" /> 25 </bean> 26 27 <bean id="conversionService" 28 class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> 29 <property name="formatters"> 30 <set> 31 <bean class="app06b.formatter.DateFormatter"> 32 <constructor-arg type="java.lang.String" value="MM-dd-yyyy" /> 33 </bean> 34 </set> 35 </property> 36 </bean> 37 38 </beans>
3.用Registrar注册Formmatter
注册Formmatter的另一个方法是Registrar
1 public class MyFormmatterRegistrar implements FormatterRegistrar{ 2 3 private String datePattern; 4 public MyFormmatterRegistrar(String datePattern){ 5 this.datePattern = datePattern; 6 } 7 8 public void registerFormatters(FormatterRegistry resgitry){ 9 resgitry.addFormatter(new DateFormatter(datePattern)); 10 } 11 }
1 1 1 <?xml version="1.0" encoding="UTF-8"?> 2 2 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 3 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4 4 4 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 5 5 5 xsi:schemaLocation=" 6 6 6 http://www.springframework.org/schema/beans 7 7 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 8 8 http://www.springframework.org/schema/mvc 9 9 9 http://www.springframework.org/schema/mvc/spring-mvc.xsd 10 10 10 http://www.springframework.org/schema/context 11 11 11 http://www.springframework.org/schema/context/spring-context.xsd"> 12 12 12 13 13 13 <context:component-scan base-package="app06b.controller" /> 14 14 14 <context:component-scan base-package="app06b.formatter" /> 15 15 15 16 16 16 <mvc:annotation-driven conversion-service="conversionService" /> 17 17 17 18 18 18 <mvc:resources mapping="/css/**" location="/css/" /> 19 19 19 <mvc:resources mapping="/*.html" location="/" /> 20 20 20 21 21 21 <bean id="viewResolver" 22 22 22 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 23 23 23 <property name="prefix" value="/WEB-INF/jsp/" /> 24 24 24 <property name="suffix" value=".jsp" /> 25 25 25 </bean> 26 26 26 27 27 27 <bean id="conversionService" 28 28 28 class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> 29 29 29 <property name="formatterRegistrars"> 30 30 30 <set> 31 31 31 <bean class="app06b.formatter.MyFormatterRegistrar"> 32 32 32 <constructor-arg type="java.lang.String" value="MM-dd-yyyy" /> 33 33 33 </bean> 34 34 34 </set> 35 35 35 </property> 36 36 36 </bean> 37 37 37 38 38 38 </beans>
选Converter还是Formatter,一般选Formatter,
因为Formmatter是在Web层