Spring 里常用的类型转换工具有
- PropertyEditor: 字符串转换为对象, Controller 里使用
- Formatter: 字符串和对象互相转换, spring-mvc 配置里使用
- Converter: 不同类型之间互相转换, spring-mvc 配置里使用
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
| package com.xtuer.formatter;
import com.xtuer.bean.User; import org.springframework.format.Formatter;
import java.text.ParseException; import java.util.Locale;
public class UserFormatter implements Formatter<User> { @Override public User parse(String text, Locale locale) throws ParseException { String[] components = text.split(","); User user = new User(); user.setUsername(components[0].trim()); user.setAge(Integer.parseInt(components[1].trim()));
return user; }
@Override public String print(User object, Locale locale) { return null; } }
|
AdminConverter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.xtuer.converter;
import com.xtuer.bean.Admin; import org.springframework.core.convert.converter.Converter;
public class AdminConverter implements Converter<String, Admin> { @Override public Admin convert(String source) { String[] components = source.split(","); Admin admin = new Admin(); admin.setUsername(components[0].trim()); admin.setAge(Integer.parseInt(components[1].trim()));
return admin; } }
|
1 2 3 4 5 6 7 8 9 10
| <mvc:annotation-driven conversion-service="customConversionService"/>
<bean id="customConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <bean class="com.xtuer.formatter.UserFormatter"/> </property> <property name="converters"> <bean class="com.xtuer.converter.AdminConverter"/> </property> </bean>
|
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13
| @RequestMapping("/format") @ResponseBody public User format(User user) { return user; }
@RequestMapping("/convert") @ResponseBody public Admin convert(Admin admin) { return admin; }
|
如果只是字符串和对象之间转换,Formatter 和 Converter 的功能是一样的,SpringMVC 的数据绑定也只是把 URL 中的参数部分转换为对象,所以这时使用 Formatter 或者 Converter 都是一样的。如果从语意上来说,Formatter 用于格式化输出时好一些,可以有本地化的信息,例如日期,货币,时间等,而 Converter 用于类型转换更恰当。
DateEditor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @RequestMapping("/editor") @ResponseBody public Date editor(Date date) { return date; } @InitBinder("date") public void initDate(WebDataBinder binder) { binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true)); }
|
比较诡异的问题是自己实现一个 Editor 继承自 PropertyEditorSupport,然后使用 @InitBinder
注册为 custom editor,不会生效,但是上面注册的 CustomDateEditor 却能生效。
自定义 PropertyEditor 还有一个很重要的用途就是在 Spring Bean 配置文件里配置好后定义 Bean 时可以把字符串转换为 Bean 的属性,例如下面的例子
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
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="customEditors"> <map> <entry key="com.xtuer.beans.Address" value="com.xtuer.beans.editor.AddressEditor"/> </map> </property> </bean>
<bean id="user" class="com.xtuer.beans.User"> <property name="username" value="Alice"/> <property name="password" value="Passw0rd"/> <property name="address" value="2|China|BeiJing|WangJin"/> </bean> </beans>
|
Formatter 和 Converter 不能用于 Spring Bean 配置文件里把字符串转换为对象,只能用于 SpringMVC 的 Controller 里把 URL 中的字符串转换为对象,而 PropertyEditor 2 个地方都可以使用。
User
1 2 3 4
| public class User { private String username; private int age; }
|
Admin
1 2 3 4
| public class Admin { private String username; private int age; }
|