spring的2种类型转换器
spring有2种类型转换器,一种是propertyEditor,一种是Converter.虽然都是类型转换,但是还是有细微差别.
所以这里以一个例子的形式来分析一下这2种类型转换的使用场景和差别.
平常的应用中应该有很多这样的情况,一个po中有一个字段是status,这个status=0时代表成功,status=1时代表失败...虽然这个status可以定义为Integer的类型,但是有时候可能为了方便管理和更面向对象,直接定义了一个TypeStatus的类来表示这个status字段.这个TypeStatus的实现可能如下,当然这只是个demo不要当真:

public class TypeStatus {
private Integer value;
private String msg;
public TypeStatus(Integer value, String msg) {
this.value = value;
this.msg = msg;
}
public static TypeStatus toBean(Integer value){
if(value==0){
return new TypeStatus(0,"成功");
}else if(value==1){
return new TypeStatus(1,"失败");
}else{
return null;
}
}
public Integer getValue() {
return value;
}
public String getMsg() {
return msg;
}
}

然后问题来了,虽然这样封装了一下后那个status字段变得更生动了..但是我们从前端页面中传过来一个0,到controller中spring如何把0转成一个TypeStatus类型呢?假设含有这个status字段的po如下:
public class PoDemo {
TypeStatus status;
}
controller如下:

public class DemoController {
public String testEditor(PoDemo po){
return "ok";
}
}

从一种类型到另一个类型,这肯定需要用到类型转换,我们先看第一种propertyEditor的实现,在controller中增加如下方法:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(TypeStatus.class, "status", new TypeStatusEditor());
}
方法registerCustomEditor的第二个参数为字段名,标识字段名为status,类型为TypeStatus的属性将会应用此类型转换,如果我们的PoDemo有另一个字段statusToo也为TypeStatus类型,那么将不会应用此类型转换.如果想把所有的TypeStatus类型字段都应用此类型转换,则第二个参数可以设置为null.
TypeStatusEditor的实现如下:

public class TypeStatusEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
TypeStatus ts = (TypeStatus) getValue();
return String.valueOf(ts.getValue());
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
TypeStatus ts = TypeStatus.toBean(Integer.parseInt(text));
setValue(ts);
}
}

PropertyEditor的使用此处不做讨论.从代码中也大体能看出实际是一个String到类型的过程,这个恰恰是propertyEditor和Converter的一个区别所在.PropertyEditor主要应用场景为String到类型的转换.从Editor提供的get和set方法也可以看出,必经过String.一般前台页面传过来的值大多是String类型,此时用PropertyEditor来转换再合适不过了.
ProertyEditor是String到类型,这只是一种特殊情况的转换,而说到最通用的肯定是类型到类型.此时就是Converter的应用了.
还是PoDemo和Controller:
public class PoDemo {
byte[] img;
}

public class DemoController {
public String testEditor(PoDemo po){
return "ok";
}
}

比如我们向数据库中存一个图片,那么数据库中是以blob类型存储的,而java类中对应的类型实际是byte[],那么问题又来了,我前台上传一张图片实际上以MultipartFile类型传到Controller中的,spring如何将MultipartFile转换成byte[]自动封装成PoDemo类呢?此时PropertyEditor显然不行了.这已经是类型到类型转换,只能用Converter.
实现如下:

public class MultipartFileToByteArrayEditor implements Converter<CommonsMultipartFile,byte[]> {
@Override
public byte[] convert(CommonsMultipartFile source) {
return source.getBytes();
}
}

然后我们还需要在spring的配置文件中注册一下:

<mvc:annotation-driven conversion-service="conversionService">
</mvc:annotation-driven>
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="xx.xx.MultipartFileToByteArrayEditor"/>
</list>
</property>
</bean>

这里使用的系统提供的FormattingConversionServiceFactoryBean来注册我们的类型转换器类MultipartFileToByteArrayEditor,实际也可以用ConversionServiceFactoryBean来注册.
都配置好后,spring就可以自动将MultipartFile转换成byte[]并封装成PoDemo了.
可能有人想到Converter实际上是包含PropertyEditor的,那么如果2种转换器都适用,那么究竟会适用哪种呢?Spring默认是首先查找PropertyEditor,然后再查找Converter.
总结:PropertyEditor适用于String到类型,而Converter更加通用用于类型到类型.PropertyEditor优先级更高.
spring的2种类型转换器的更多相关文章
- Ⅵ.spring的点点滴滴--自定义类型转换器
承接上文 自定义类型转换器 .net篇(环境为vs2012+Spring.Core.dll v1.31) public class CustomeConverter : TypeConverter{ ...
- Spring支持5种类型的增强
Spring支持5种类型的增强:1.前置增强:org.springframework.aop.BeforeAdvice代表前置增强,因为Spring只支持方法级的增强,所以MethodBeforeAd ...
- Spring MVC__自定义日期类型转换器
WEB层采用Spring MVC框架,将查询到的数据传递给APP端或客户端,这没啥,但是坑的是实体类中有日期类型的属性,但是你必须提前格式化好之后返回给它们.说真的,以前真没这样做过,之前都是一口气查 ...
- Spring的类型转换器
spring有2种类型转换器,一种是propertyEditor,一种是Converter. 第一种属性编辑器用法见Spring的属性编辑器的章节.如果2种转换器都适用,那么究竟会适用哪种呢?Spri ...
- Struts2之自定义类型转换器
Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用d ...
- Struts2之自定义局部类型转换器、全局类型转换器
Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用 ...
- Struts 2 之类型转换器
Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用d ...
- Spring AOP四种实现方式Demo详解与相关知识探究
一.前言 在网络上看到一篇博客Spring实现AOP的4种方式,博主写的很通俗易懂,但排版实在抓狂,对于我这么一个对排版.代码格式有强迫症的人来说,实在是不能忍受~~~~(>_<)~~~~ ...
- 自定义类型转换器 及 使用 ServletAPI 对象作为方法参数
自定义类型转换器使用场景: jsp 代码: <!-- 特殊情况之:类型转换问题 --> <a href="account/deleteAccount?date=2018- ...
随机推荐
- android自定义控件(三) 自定义属性
书接上回 在xml里建立属性,然后java代码里用typedArray获得这些属性,得到属性后,利用属性做一些事.例:得到xml里的color,赋给paint. 1.在res/values/下新建at ...
- bzoj 3872 [Poi2014]Ant colony——二分答案
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3872 可以倒推出每个叶子节点可以接受的值域.然后每个叶子二分有多少个区间符合即可. 注意一开 ...
- 六 Vue学习 首页 (下)
一:Store介绍: state: 相当于数据 action: action去commit mutations mutation: 只有mutation 才能改变state 例: const stor ...
- 网络工具 NetCat
http://netcat.sourceforge.net/ windows 版本 https://joncraton.org/blog/46/netcat-for-windows/ https:// ...
- GET请求中的乱码原理解析和解决方案
2. 乱码问题解决 基础知识 1)浏览器会在中文的UTF-8后加上上%得到URL编码 例如: %e8%b4%b9%e7%94%a8%e6%8a%a5%e9%94%80 2)以get的请求发送到to ...
- css如何改变placeholder的默认颜色值
input:-moz-placeholder {/* Mozilla Firefox 4 to 18*/ color: red; input::-moz-placeholder {/* Mozilla ...
- [hdu2087]剪花布条(KMP)
题意:求存在模式串个数,不可重复. 解题关键:模板题.整理模板用.重复和不可重复的区别在下面已标出.主要是j的变化. #include<cstdio> #include<cstrin ...
- C#闪动任务栏的方法
用FlashWindowEx可以实现窗口的闪烁,结构如下: /// <summary> /// 闪烁窗口 /// </summary> /// <param name=& ...
- Linear Algebra - Determinant(基础)
1. 行列式的定义 一阶行列式: \[ \begin{vmatrix} a_1 \end{vmatrix} = a_1 \] 二阶行列式: \[ \begin{vmatrix} a_{11} & ...
- Java 普通方法和构造方法的区别
构造方法: ①方法名和 类名相同 ②在方法名的前面没有返回值类型的声明 ③在方法中不能使用return语句返回一个值 ④在创建对象时,要调用new,如:book b1=new book(); ⑤当没有 ...