本章着重讨论Converter和Formatter的内容。这两者均可用于将一种对象类型转换成另一种对象类型。Converter是通用元件,可以在应用程序的任意层中使用,而Formatter则是专门为Web层设计的。
1.Converter
为了创建Converter,必须编写一个实现org.springframework.core.convert.converter.Converter接口的Java类。这个接口的声明如下:
public interface Converter
这里的S表示源类型,T表示目标类型。
package app06a.converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
public class StringToDateConverter implements Converter<String, Date>
{
private String datePattern;
public StringToDateConverter(String datePattern)
{
this.datePattern = datePattern;
}
@Override
public Date convert(String s)
{
try
{
SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
dateFormat.setLenient(false);
return dateFormat.parse(s);
}
catch (ParseException e)
{
throw new IllegalArgumentException(
"invalid date format.Please use this pattern\"" + datePattern + "\"");
}
}
}
为了使用Spring MVC应用程序中定制的Converter,需要在Spring MVC配置文件中编写一个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="app06a.converter.StringToDateConverter">
<constructor-arg type="java.lang.String" value="MM-dd-yyyy" />
bean>
list>
property>
bean>
随后,要给annotation-driven元素的conversion-service属性赋bean名称:
<mvc:annotation-driven conversion-service="conversionService" />
2.Formatter
Formatter的源类型必须是一个String,而Converter则适用于任意的源类型。Formatter更适合Web层,而Converter则可以用在任意层中。
为了创建Formatter,要编写一个实现org.springframework.format.Formatter接口的java类。下面是这个接口的声明:
public interface Formatter
这里的T表示输入字符串要转换的目标类型。该接口有parse和print两个方法,所有实现都必须覆盖。
T parse(String text, java.util.Locale locale)
String print(T object, java.util.Locale locale)
parse方法利用指定的Locale将一个String解析成目标类型。print方法与之相反,它是返回目标对象的字符串表示法。
package app06b.formatter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.format.Formatter;
public class DateFormatter implements Formatter<Date>
{
private String datePattern;
private SimpleDateFormat dateFormat;
public DateFormatter(String datePattern, SimpleDateFormat dateFormat)
{
this.datePattern = datePattern;
dateFormat = new SimpleDateFormat(datePattern);
dateFormat.setLenient(false);
}
@Override
public String print(Date date, Locale locale)
{
return dateFormat.format(date);
}
@Override
public Date parse(String s, Locale locale)
throws ParseException
{
try
{
return dateFormat.parse(s);
}
catch (ParseException e)
{
// the error message will be dispalyed when using
throw new IllegalArgumentException(
"invalid date format.Please use this pattern\"" + datePattern + "\"");
}
}
}
为了在Spring MVC应用程序中使用Formatter,需要利用conversionService bean对它进行注册。bean的类名称必须为org.springframework.format.support.FormattingConversionServiceFactoryBean。
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<bean class="app06b.formatter.DateFormatter">
<constructor-arg type="java.lang.String" value="MM-dd-yyyy" />
bean>
set>
property>
bean>
还需要给这个Formatter添加一个component-scan元素。
<context:component-scan base-package="app06b.formatter" />
3.用Registrar注册Formatter
package app06c.formatter;
import org.springframework.format.FormatterRegistrar;
import org.springframework.format.FormatterRegistry;
public class MyFormatterRegistrar implements FormatterRegistrar
{
private String datePattern;
public MyFormatterRegistrar(String datePattern)
{
this.datePattern = datePattern;
}
@Override
public void registerFormatters(FormatterRegistry registry)
{
registry.addFormatter(new DateFormatter(datePattern));
// register more formatters here
}
}
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatterRegistrars">
<set>
<bean class="app06c.formatter.MyFormatterRegistrar">
<constructor-arg type="java.lang.String" value="MM-dd-yyyy" />
bean>
set>
property>
bean>