Jackson: 编写自己的字段格式化方法

Jackson[1] 是我们编写 Java 应用时常用的 JSON 序列化/反序列化库。今天说说使用它的另一个技巧:为特定字段编写自己的序列化方法(或者,在序列化前,怎么先格式化特定字段)。

之前介绍过的 Jackson 的技巧:巧用 @JsonRawValue 注解


假设某 API 返回的 JSON 结构如下:

{
  "a"10000,
  "b"12345
}

前端拿到该数据后,要做如下渲染:

Jackson: 编写自己的字段格式化方法

即,数字要转化为「万」,且保留一位小数。

关于数值格式化,通常的做法是以下 2 种:

  1. 后端返回原始数值,前端拿到数值后,先格式化再显示。

    • 优点:后端返回原始的数值,无需做额外的工作。
    • 缺点:前端需要写格式化逻辑;当前端有多端时(web / ios / android),每一端都要写自己的格式化函数。
  2. 后端直接返回格式化后的字段,前端拿到数据后直接显示。

    • 优点:前端只需要负责显示,无需额外逻辑;当涉及多平台时,省了前端重复的工作量。
    • 缺点:后端不能偷懒了;当这些数字还需要在前端参与数学运算时,只返回格式化的文本是不够的。

本文说说采用2让后端直接返回格式化后的字段,有没有好的实现方式。

2 的返回格式如下:

{"a":"1w","b":"1.2w"}

我们先讨论一下两种可能的实现方法。

假设有 ModelDto 类如下:

@Data
class Model {
    int a;
    int b;
}

@Data
class Dto {
    String a;
    String b;
}

另外有一个格式化数值的方法:

// 格式化数值
String format(int num){
   // 省略
}

方式一:手动转换

即 一个字段一个字段的拷贝,拷贝前先转换一下:

// 手动调用格式化方法
dto.setA(format(model.getA()));
dto.setB(format(model.getB()));

这种方式虽然能达到目的,但每个需要格式化的字段都需要手动调用 format 方法,就问你烦不烦?

而且,像这类从一个 bean 转换到另一个 bean 的操作,由于两边字段类型不同,也不能方便地使用 MapStruct 等工具自动转换,是不是更烦了?

所以我们引入方法二。

方法二:利用注解,声明式配置

其实,Jackson 允许我们在序列化对象时,指定某个字段的序列化方式,如下面这样:

先改写 Dto 类,保持字段类型和 Model 一致,然后给各个字段加一个注解配置:

@Data
class Dto {
    @JsonSerialize(converter = MyConverter.class)
    int a
;
    @JsonSerialize(converter = MyConverter.class)
    int b
;
}

其中,@JsonSerialize 注解用来进行个性化配置,converter 参数的作用,是在序列化指定字段之前,用指定转换器先进行转换操作,Jackson 再对转换后的结果进行序列化。

MyConverter 类的实现如下:

import com.fasterxml.jackson.databind.util.StdConverter;

class MyConverter 
   extends StdConverter<IntegerString
{

    @Override
    public String convert(Integer num) {
        // 格式化数值
        return format(num);
    }
}

如此,该 Dto 中的 ab 字段,在序列化之前,会先被格式化,即:

对于

{
  "a": 10000,
  "b": 12345
}

会自动转换成

{
  "a""1w",
  "b""1.2w"
}

利用注解配置的好处是:

  1. 当某天需求变动,不需要返回格式化的文本或格式化算法有调整时,可以通过修改 MyConverter 类来统一更改。
  2. 避免了每个字段都要去手动调用 format 的繁琐。
  3. 该注解方便在需要的地方进行复用。
  4. 由于 ModelDto 字段名和类型一样,方便使用 MapStruct 等工具自动生成转换类。

总结

文章介绍了 Jackson 工具库在序列化 Java Bean 时,利用 @JsonSerialize 注解的 converter 配置项,可以轻松定制字段的序列化方式。该注解还有别的属性可配置,建议读者查看文档进一步学习。

参考资料

[1]

FasterXML/jackson: https://github.com/FasterXML/jackson

– END –


原文始发于微信公众号(背井):Jackson: 编写自己的字段格式化方法

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/246728.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!