天增的博客
首页
博客
  • 分布式解决方案
  • Java并发工具包
  • redis
  • LeetCode
  • 系统设计
  • JVM体系
Github (opens new window)
Rss (opens new window)
  • zh-CN
  • en-US
首页
博客
  • 分布式解决方案
  • Java并发工具包
  • redis
  • LeetCode
  • 系统设计
  • JVM体系
Github (opens new window)
Rss (opens new window)
  • zh-CN
  • en-US
  • post
2024-03-19

Jackson配置BigDecimal序列化保留小数点位数

# Jackson配置BigDecimal序列化保留小数点位数

在项目中,某些业务中的BigDecimal有的要保留2位,有的需要保留4位,如果需要在代码中挨个判断,非常繁琐。

所以,可以利用Jackson自定义序列化的方式实现动态配置。

先声明自定义的JsonSerializer​

public class BigDecimalDynamicSerializer extends JsonSerializer<BigDecimal>{
	@Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (ObjectUtil.isNotEmpty(value)) {
            BigDecimal number = value.setScale(2, RoundingMode.HALF_UP);
            gen.writeNumber(number);
        } else {
            gen.writeNumber(value);
        }
    }
}

在使用中直接在字段上加上,@JsonSerialize(using = BigDecimalDynamicSerializer.class)​

‍

这种方式只能统一序列化成2位小数。

因此还需要借助自定义注解,将注解中声明字段

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = BigDecimalDynamicSerializer.class)
public @interface BigDecimalScale {

    int scale() default 2;

    RoundingMode roundingMode() default RoundingMode.HALF_UP;
}

类还需要继承ContextualSerializer​。

​ContextualSerializer​是 Jackson 提供的另一个序列化相关的接口,它的作用是通过字段已知的上下文信息定制JsonSerializer​,只需要实现createContextual​方法即可:

完整代码如下:

public class BigDecimalDynamicSerializer extends JsonSerializer<BigDecimal> implements ContextualSerializer {
    private final int scale;
    private final RoundingMode roundingMode;

    public BigDecimalDynamicSerializer() {
        this.scale = 2;
        this.roundingMode = RoundingMode.HALF_UP;
    }

    public BigDecimalDynamicSerializer(int scale, RoundingMode roundingMode) {
        this.scale = scale;
        this.roundingMode = roundingMode;
    }

    @Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (ObjectUtil.isNotEmpty(value)) {
            BigDecimal number = value.setScale(scale, roundingMode);
            gen.writeNumber(number);
        } else {
            gen.writeNumber(value);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        if (property != null) {
            BigDecimalScale annotation = property.getAnnotation(BigDecimalScale.class);
            if (annotation != null) {
                return new BigDecimalDynamicSerializer(annotation.scale(), annotation.roundingMode());
            }
        }
        return prov.findValueSerializer(BigDecimal.class, property);
    }
}

最近更新
01
以 root 身份启动 transmission-daemon
12-13
02
Debian系统安装qbittorrent-nox
12-09
03
LXC Debain12安装zerotier并实现局域网自动nat转发
07-29
更多文章>
Theme by Vdoing | Copyright © 2015-2024 天增 | 苏ICP备16037388号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式