环境:Spring Boot 2.1.5.RELEASE 对应 Springframework 5.1.7.RELEASE
在 Spring-MVC【应用篇】请求入参类型转换 一文中,从源码的角度解析了 Spring MVC 针对两种入参类型(表单入参,Json格式入参)如何对入参进行类型转换。
下面通过简单的案例看看在项目中如何通过自定义类型转换类使得代码更整洁。
背景问题:将入参为保留两位小数单位为元的数字字符串,通过 Long 类型,单位为分 进行接收。
在金融项目中,存在大量针对数值的操作,例如:数据库中存入的数值为 long 类型(以分为单位),而前端传入操作值是单位为元的字符串。(在返回给前端的时候又需要转化为元)。
针对该场景,可以定义一个工具类对数值在代码中进行转换操作,但是当数值字段多的时候,这些操作会变得繁琐。
通过自定义 类型转换,简化使用工具类的频繁操作。
表单入参 类型转换
分析
思考:在看完源码后,如何实现一个自定义的表单入参类型转换类?
在 Spring 中,给我们提供了想成的参考实现对象 @DateTimeFormat。
通过查看代码能够得知 @DateTimeFormat 功能的实现定义了三个类:
- DateFormatter
进行类型转化处理操作的类
- DateTimeFormat
注解类,用来标注需要被处理的字段
- DateTimeFormatAnnotationFormatterFactory
工厂类:用来获取 DateFormatter 处理类
@DateTimeFormat 通过定义三个类来实现 “时间类型” 入参的类型转化功能,但是还有重要的一点,就是需要将实现工厂 DateTimeFormatAnnotationFormatterFactory 注册到 Spring MVC 的处理器类 WebConversionService 中。
Spring Boot 中,在自动配置类 WebMvcAutoConfiguration 对该类进行了注册。
实现
注解类:DollarToCentFormat
用户对入参映射字段进行标注,被标注的字段才会被匹配到该类型转换
/**
* <p> Formatter 注解 </p>
*
* @Author WTF名字好难取
* @Since V1.0
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface DollarToCentFormat {
}
处理类:DollarToCentFormatter
完成 “字符串数值 -> long 类型整数值” 的功能实现
/**
* <p> Format 处理器 </p>
*
* @Author WTF名字好难取
* @Since V1.0
*/
public class DollarToCentFormatter implements Formatter<Long> {
@Override
public Long parse(String dollar, Locale locale) throws ParseException {
if(StringUtils.isNotBlank(dollar)){
BigDecimal bigDecimal = BigDecimal.