SpringMVC Conveter 和Formatter

Converter

Spring的Converter可以将一种类型转换成另一种类型。在使用时,必须编写一个实现org.springframework.core.convert.converter.Converter接口的java类。这个接口的声明如下

1
2
3
public interface Converter<S, T> {
T convert(S var1);
}//S表示源类型,T表示目标类型。

下面是一个将String类型转换为Date类型的Converter。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class StringToDateConverter implements Converter<String, Date>{
private static final Log logger = LogFactory.getLog(StringToDateConverter.class);
private String datePattern;

public StringToDateConverter(String datePattern) {
this.datePattern = datePattern;
}

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,需要在配置文件中添加一个conversionService bean。Bean的类名称必须为org.springframework.context.support.ConversionServiceFactoryBean。这个bean必须包含一个converters属性,它列出要在应用程序中使用的所有定制Converter。下面bean声明注册了上面StringToDateConverter。

1
2
3
4
5
6
7
8
9
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.converter.StringToDateConverter">
<constructor-arg name="datePattern" value="yyyy-MM-dd"/>
</bean>
</set>
</property>
</bean>

之后,还需要给annotation-driven元素的conversion-service属性赋上bean名称,如下

1
<mvc:annotation-driven conversion-service="conversionService"/>

Formatter

Formatter和Converter一样,也是将一种类型转换成另一种类型。但是,Formatter的源类型必须是一个String。
在使用时,必须编写一个实现org.springframework.format.Formatter接口的java类。这个接口的声明如下

1
2
3
4
5
6
7
8
public interface Formatter<T> extends Printer<T>, Parser<T> {
}
public interface Printer<T> {
String print(T var1, Locale var2);
}
public interface Parser<T> {
T parse(String var1, Locale var2) throws ParseException;
}

这里的T表示输入字符串要转换的目标类型。
parse方法利用指定的Locale将一个String解析成目标类型。print方法相反,它是返回目标对象的字符串表示法。
下面展示了一个将String类型转换成Date类型的Formatter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import org.springframework.format.Formatter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class DateFormatter implements Formatter<Date>{
private String datePattern;
private SimpleDateFormat dateFormat;

public DateFormatter(String datePattern) {
this.dateFormat = dateFormat;
dateFormat = new SimpleDateFormat(datePattern);
dateFormat.setLenient(false);
}
public Date parse(String s, Locale locale) throws ParseException {
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 + "\"");
}
}

public String print(Date date, Locale locale) {
return dateFormat.format(date);
}
}

为了使用Spring MVC应用程序定制的Formatter,需要在配置文件中添加一个conversionService bean。Bean的类名称必须为org.springframework.format.support.FormattingConversionServiceFactoryBean。这个bean可以用一个formatters属性注册Formatter,用一个converters属性注册Converter。下面bean声明注册了上面DateFormatter。

1
2
3
4
5
6
7
8
9
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<bean class="app06a.formatter.DateFormatter">
<constructor-arg name="datePattern" value="yyyy-MM-dd"/>
</bean>
</set>
</property>
</bean>

之后,还需要给annotation-driven元素的conversion-service属性赋上bean名称,如下

1
<mvc:annotation-driven conversion-service="conversionService"/>

用Registrar注册Formatter

注册Formatter的另一种方法是使用Registrar。
下面就用Registrar来注册前面的DateFormatter。
先需要实现org.springframework.format.FormatterRegistrar接口,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}

public void registerFormatters(FormatterRegistry formatterRegistry) {
formatterRegistry.addFormatter(new DateFormatter(datePattern));
//register more formatters here
}
}

有了Registrar,就不需要在Spring MVC配置文件中注册Formatter,只要在配置文件中注册Registrar就行,如下

1
2
3
4
5
6
7
8
9
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatterRegistrars">
<set>
<bean class="app06a.formatter.MyFormatterRegistrar">
<constructor-arg name="datePattern" value="yyyy-MM-dd"/>
</bean>
</set>
</property>
</bean>

选择Converter还是Formatter

Converter是一般工具,可以将一种类型转换成另一种类型。例如,将String转换成Date,或者将Long转换成Date。Converter既可以用在web层,也可以用在其它层中。
Formatter只能将String转成成另一种java类型。例如,将String转换成Date,但它不能将Long转换成Date。所以,Formatter适用于web层。为此,在Spring MVC应用程序中,选择Formatter比选择Converter更合适。

https://segmentfault.com/a/1190000005708254