spring mvc学习心得(一)数据类型转换
来源:互联网 发布:mac office 生成目录 编辑:程序博客网 时间:2024/05/18 08:26
数据类型转换
一、摘要
在一次http请求到响应的过程中,存在各种数据转换操作,现在要分析的是spring mvc数据转换,它的上游数据来源是ServletRequest,下游是处理方法(也就是controller层的各个方法),总而言之就是把ServletRequest 请求参数封装到处理器方法入参中
1.使用场景
- 一般场景,例如在form表单登录时,需要提交用户名和密码到处理器方法中
- 状态int值转换为状态枚举(1正常、0禁用、-1删除)CommonStatusEnum(NORMAL、FORBIDDEN、DELETED)
- 日期字符串转换为Date
- 等等…
2. 相关类
- Converter 接口
- ConverterFactory 接口
- GenericConverter 接口
- ConversionService 接口
- ConversionServiceFactoryBean
二、各个类使用及其分析
1. Converter
最简单的一个转换器接口,接口定义如下
public interface Converter<S, T> { T convert(S var1);}
2. ConverterFactory
可以实现很多同质转换器,也就是目标类存在同一个父类,例如:String转换成Number及其子类,其接口定义如下
public interface ConverterFactory<S, R> { <T extends R> Converter<S, T> getConverter(Class<T> var1); }
下面是我自己定义的枚举转换器
public class ValueToEnumConverterFactory implements ConverterFactory<String, IEnum> { //T为目标类型,也就是需要转换成什么类型,<T extends IEnum> 则说明目标类型要是IEnum的子类才会使用该转换器 public <T extends IEnum> Converter<String, T> getConverter(Class<T> targetType) { Class<?> enumType = targetType; while (enumType != null && !enumType.isEnum()) { enumType = enumType.getSuperclass(); } if (enumType == null) { throw new IllegalArgumentException("The target type " + targetType.getName() + " does not refer to an enum"); } return new StringToEnum(enumType); } private class StringToEnum<T extends IEnum> implements Converter<String, T> { private final Class<T> enumType; public StringToEnum(Class<T> enumType) { this.enumType = enumType; } public T convert(String source) { if (source.length() == 0) return null; return EnumUtil.convert(this.enumType, Integer.valueOf(source.trim()));//根据id和具体枚举类型完成 从int 类型到对应枚举类型的转换 } }}
通过这个转换器可以自动实现int型到枚举类型的自动转换
3. GenericConverter
这个接口是实现转换器最复杂的接口,因为他可以考虑源类型和目标类型所在宿主类的上下文信息,其接口定义如下
public interface GenericConverter { Set<GenericConverter.ConvertiblePair> getConvertibleTypes(); Object convert(Object var1, TypeDescriptor var2, TypeDescriptor var3); public static final class ConvertiblePair { private final Class<?> sourceType; private final Class<?> targetType; public ConvertiblePair(Class<?> sourceType, Class<?> targetType) { Assert.notNull(sourceType, "Source type must not be null"); Assert.notNull(targetType, "Target type must not be null"); this.sourceType = sourceType; this.targetType = targetType; } public Class<?> getSourceType() { return this.sourceType; } public Class<?> getTargetType() { return this.targetType; } public boolean equals(Object other) { if(this == other) { return true; } else if(other != null && other.getClass() == GenericConverter.ConvertiblePair.class) { GenericConverter.ConvertiblePair otherPair = (GenericConverter.ConvertiblePair)other; return this.sourceType == otherPair.sourceType && this.targetType == otherPair.targetType; } else { return false; } } public int hashCode() { return this.sourceType.hashCode() * 31 + this.targetType.hashCode(); } public String toString() { return this.sourceType.getName() + " -> " + this.targetType.getName(); } }}
不想写例子了,这个转换器不常用(主要是懒字当头)
4. ConversionService与ConversionServiceFactoryBean
以上三个转换器需要装载到ConversionService才会生效
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.ouryue.base.convert.ValueToEnumConverterFactory"/> <bean class="com.ouryue.base.convert.StringToDateConverter"></bean> </set> </property> </bean><mvc:annotation-driven conversion-service="conversionService"/><!--装配自定义的conversionService到spingweb上下文-->
- conversionService 是spring类型转换体系的核心接口,ConversionServiceFactoryBean为其工厂方法
- ConversionServiceFactoryBean会把其属性converters中的参数封装到创建的ConversionService中,且内建了很多默认转换器,可以完成大多数java类型转换工作。除了包括将String 转换为基本类型对象外,还包括String、Number、Array、Collection、Map、Properties及Object
三、总结
- 对于这三个实现转换器的接口,绝大部分情况是使用Converter、ConverterFactory
- 虽然从继承结构和内部属性来看,Converter、ConverterFactory和GenericConverter没有什么关系,注册到ConversionService时会被转换为GenericConverter
public void addConverter(Converter<?, ?> converter) { ResolvableType[] typeInfo = this.getRequiredTypeInfo(converter.getClass(), Converter.class); if(typeInfo == null && converter instanceof DecoratingProxy) { typeInfo = this.getRequiredTypeInfo(((DecoratingProxy)converter).getDecoratedClass(), Converter.class); } if(typeInfo == null) { throw new IllegalArgumentException("Unable to determine source type <S> and target type <T> for your Converter [" + converter.getClass().getName() + "]; does the class parameterize those types?"); } else { this.addConverter((GenericConverter)(new GenericConversionService.ConverterAdapter(converter, typeInfo[0], typeInfo[1])));//此处进行转换 } }
Converter、ConverterFactory存在的意义就是为了降低转换器的使用难度吧,认证了那句话:没有什么是封装一层解决不了的,太难了?那就封装一层吧
阅读全文
1 0
- spring mvc学习心得(一)数据类型转换
- Spring MVC学习(七)-------SpringMVC数据类型转换
- Spring MVC-自定义数据类型转换解决方案
- Spring MVC学习(七)-------SpringMVC数据类型转换
- JAVA Spring web mvc 学习 之 6:数据类型转换
- JAVA Spring web mvc 学习 之 6:数据类型转换 -格式转换
- 【Spring】详解Spring MVC中不同格式的POST请求参数的数据类型转换过程
- Spring MVC数据绑定(一) 数据转换
- Spring MVC数据转换
- spring mvc Json转换
- spring mvc 类型转换
- Spring MVC结果转换
- Spring mvc数据转换
- mfc 数据类型转换一
- 第四章:数据类型转换——深入浅出学Spring Web MVC
- 第四章:数据类型转换——深入浅出学Spring Web MVC
- Spring MVC配置(一)
- Spring MVC(一)
- 2017 ACM-ICPC(西安赛区) B-Coin
- spring学习笔记二十一 Hibernate在线安装
- shiro与springmvc整合需要注意xml配置
- 阻止默认行为
- 安装java环境和配置java环境
- spring mvc学习心得(一)数据类型转换
- mybatis框架的一些步骤
- Java语法基础练习题(1)改后
- 如何在Linux下安装Memcached(1.4.21)
- mac查看、修改文件权限
- C++嵌入DLL到资源运行释放的问题
- hsv和余弦相似度的局限
- Docker技术剖析--Supervisor管理
- ar、ranlib、nm命令详解