暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Spring-MVC【应用篇】请求入参类型转换

花好夜猿 2019-10-01
1135

环境: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名字好难取 ] 公众号


往期回顾

Spring MVC

Spring-MVC【源码篇】请求入参类型转换


文章转载自花好夜猿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论