环境:Spring Boot 2.1.5.RELEASE 对应 Springframework 5.1.7.RELEASE
在 Spring-MVC【源码篇】请求入参类型转换 一文中,从源码的角度解析了 Spring MVC 针对两种入参类型(表单入参,Json格式入参)如何对入参进行类型转换。
下面通过简单的案例看看在项目中如何通过自定义类型转换类使得代码更整洁,统一入参类型格式,更专注与业务逻辑,而不是参数类型。
背景问题:将入参为保留两位小数单位为元的数字字符串,通过 Long 类型,单位为分 进行接收。
在金融项目中,存在大量针对数值的操作,例如:数据库中存入的数值为 long 类型(以分为单位),而前端传入操作值是单位为元的字符串。(在返回给前端的时候又需要转化为元)。
针对该场景,可以定义一个工具类对数值在代码中进行转换操作,如:
// 实现 (分->元)的转换AmountUtils.transferTradeAmount(xxx)
当在项目中存在大量的转换操作,会存在频繁的转换操作。在排查代码的时候,也需要在代码中进行查看。
通过自定义 类型转换,可以简化使用工具类的频繁操作,通过注解的方式,减少转换操作,同时在查看代码时,只需关注对应字段上是否增加相对应的注解。
自定义 【表单入参】 类型转换
分析
思考:在看完源码后,如何实现一个自定义的表单入参类型转换类?
在 Spring 中,给我们提供了现成的参考实现对象 @DateTimeFormat。
通过查看相关代码得知 @DateTimeFormat 功能实现相关的三个类:
DateFormatter
进行类型转化处理操作的类
DateTimeFormat
注解类,用来标注需要被处理的字段
DateTimeFormatAnnotationFormatterFactory
工厂类:用来获取 DateFormatter 处理类
@DateTimeFormat 通过定义三个类来实现 “时间类型” 入参的类型转化功能。
还有重要的一点,就是需要将实现工厂 DateTimeFormatAnnotationFormatterFactory 注册到 Spring MVC 的处理器类 WebConversionService 中。
Spring Boot 中,在自动配置类 WebMvcAutoConfiguration 对该类进行了注册。
自定义实现
1、注解类:DollarToCentFormat
用户对入参映射字段进行标注,被标注的字段才会被匹配到该类型转换

2、处理类:DollarToCentFormatter
完成 “字符串数值 -> long 类型整数值” 的功能实现

3、工厂类:DollarToCentFormatAnnotationFormatterFactory
获取 处理类 DollarToCentFormatter 的工厂

4、关键步骤:将 工厂类,注册到 Spring MVC 配置中

功能演示
演示代码

关键点:在需要使用 DollarToCentFormatter 进行类型转化的字段上使用自定义注解 @DollarToCentFormat 进行标注。
演示结果

演示结果:入参为:2.55 输出结果为:255
自定义【Json格式入参】 类型转换
分析
Spring Boot 默认使用 JackSon 框架对 Json 入参进行 反序列化操作,所以实现只需要符合 JackSon 写法即可。
知识点:当切换其他 Json 框架,如 FastJson 时,可以通过 FastJson 的特定实现方式,进行实现。
自定义实现
反序列化类:DollarToCentDeserializer
完成对 Json 入参的反序列化操作

演示
演示代码

代码逻辑:对入参进行乘法操作。
关键点
1、请求头中的 Content-Type 必须符合 application/json 或者 application/ + json (在源码中,能够得到该结果*)
2、Json 格式入参接收需要使用 @RequestBody
3、在需要进行反序列化类型转换的字段上加 @JsonDeserialize(using = DollarToCentDeserializer.class)
演示结果

演示结果:入参:2.55 结果:255 * 3 = 765
扩展:JackSon 返回结果值类型转换
背景问题:解决了入参从 元 -> 分 的,但是针对前端展示,需要在返回给前端值实现 分 -> 元
分析
区别于 JackSon 入参处理,入参处理使用的反序列化,将入参映射到接收对象中,需要实现 JsonDeserializer。
而对于结果的返回,是对对象的 Json 格式序列化操作,需要实现 JsonSerializer 。
自定义实现
Json 序列化类:CentToDollarSerializer
实现对象 -> Jsno 字符串 时的类型转换
该操作在 HandlerMethodReturnValueHandler 的实现类 RequestResponseBodyMethodProcessor 完成操作。
友链:Spring-MVC【源码篇】请求参数和响应结果解析

演示
演示代码

代码逻辑:对入参 乘以 3
关键点:
1、返回的结果必须为指定的对象。如:这里的 JsonDTO
2、在需要进行序列化的字段上加 @JsonSerialize(using = CentToDollarSerializer.class)
演示结果

演示结果: 入参:2.55 ,结果:7.65
-- END --

长按二维码 ▲
关注 [ WTF名字好难取 ] 公众号
往期回顾





