学习参考 :
- 讲师:孙帅老师
- 课程:www.bilibili.com/video/BV1i5...
springMvc中 类型转换器分为内置类型转换器和自定义类型转换器
内置
概念
SpringMVC提供了内置类型转换器,把客户端提交的字符串类型的请求参数,转换成控制器方法参数需要的数据类型
应用
比如: 下面这段代码中, 控制器方法的形参age是Integer类型,而客户端传过来的参数形式是age="10" ,因为在http请求中,参数都是字符串类型,但是我们却可以在方法中正确获取到Integer类型的age参数值,就是因为spring内置了字符串转数字的类型转换器
kotlin
@RequestMapping("/editor1")
public String editor1(String name, Integer age) {
System.out.println("name = " + name);
System.out.println("age = " + age);
return "param1";
}
但是,SpringMVC并不是对于所有的类型,都提供了内置的类型转换器,他只是提供了常见类型的转换器 比如:8种基本类型,常见的集合类型等,所以在某些场景下,我们需要自定义类型转换器
类型转换器的原理
Converter<S, T> 接口提供了 方法 public T convert(String source)
从此可以看出,S 代表接收到的客户端参数,也就是字符串 ,T是控制器方法形参,也就是我们想要的参数类型
比如内置类型转换器 实现age的转换
scala
private static final class StringToNumber<T extends Number> implements Converter<String, T> {
private final Class<T> targetType;
public StringToNumber(Class<T> targetType) {
this.targetType = targetType;
}
public T convert(String source) {
return source.isEmpty() ? null : NumberUtils.parseNumber(source, this.targetType);
}
}
从上面代码可以分析出,实现类型转换器大体上分为三部
1.获取客户端参数(springMvc 帮我们实现)
2.转换为想要的控制器方法定义的类型参数
3.赋值给控制器方法(springMvc 帮我们实现)
所以我们如果需要自定义类型转换器,编码上 需要自己动手的也只有第二步
那么内置的这些类型转换器,是如何工作的?
各种类型转换器需要一个地方存储他们,也就是FormattingConversionServiceFactoryBean,在其中定义了一个集合去存储各种内置的类型转换器
typescript
public void setConverters(Set<?> converters) {
this.converters = converters;
}
1.在SpringMVC启动时,会通过mvc:annotation-driven/ 把FormattingConversionServiceFactoryBean。引入到SpringMVC体系中
2.FormattingConversionServiceFactoryBean存储了SpringMVC中所有的内置类型转换器
3.后续client提交请求参数时,如果对应控制器方法形参不是字符串类型,那么FormattingConversionServiceFactoryBean就会调用对应的类型转化器,进行类型转换,最终完成控制器方法形参的赋值
自定义
根据上面的描述,可以自己实现一个日期类型转换器
typescript
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
Date parse = null;
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
parse = simpleDateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return parse;
}
}
但是springMvc启动后创建FormattingConversionServiceFactoryBean的时候,这里面只有内置类型转换器,我们自定义的日期类型转换器不在其中,也就意味着不会生效
所以,首先需要将自定义的类型转换器 加入到spring容器中
然后注册FormattingConversionServiceFactoryBean 并在其中引入上面自定义的类型转换器
xml
<bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="converter"/>
</set>
</property>
</bean>
最后让mvc启动的时候加载 我们注册的FormattingConversionServiceFactoryBean,也就是包含自定义类型转换器的FormattingConversionServiceFactoryBean
<mvc:annotation-driven conversion-service="formattingConversionService"/>