笔者的项目使用了 jackson 序列化
要求
主要是两个方面:
- 位数:位数大于等于 4,则保留 4 位小数,否则保留对应的小数位数;
- 格式:不出现科学技术法,不以 0 结尾.
代码
序列化实现:
public class KeepMostFourBigDecimalSerializer extends JsonSerializer<BigDecimal> {/*** Method that can be called to ask implementation to serialize* values of type this serializer handles.** @param value Value to serialize; can <b>not</b> be null.* @param gen Generator used to output resulting Json content* @param serializers Provider that can be used to get serializers for* serializing Objects value contains, if any.*/@Overridepublic void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {if (Objects.nonNull(value) && value.scale() >= 4) {gen.writeString(value.setScale(8, RoundingMode.DOWN).stripTrailingZeros().toPlainString());} else {gen.writeString(value.stripTrailingZeros().toPlainString());}}
}
其中:
stripTrailingZeros()
是为了去结尾的 0toPlainString()
是为了防止出现科学计数法以及 JSON 格式中的 {“value”: 1.01} 变成 {“value”: “1.01”}.
BTW:有的同事通过 extends JsonSerializer<Object>
然后再重写 serialize(Object value, JsonGenerator gen, SerializerProvider serializers)
方法的时候针对 value 的数据类型来实现响应的需求。我认为这种方式从达成目标的角度来说是可以达成目的的,但是有点违反 单一职责,创建相关的序列化类的时候(比如说小数点)还是按照业务需求(保留规则)来而不是场景(用来做什么,比如说人民币、美元)来编码。
使用的时候直接使用 @JsonSerialize
注解标注在对应的实体类的属性上即可:
public static class YourClass{@JsonSerialize(using = KeepMostFourBigDecimalSerializer .class)private BigDecimal value;// 省略 getter 和 setter}
One More Thing
由于 Spring Boot 默认使用 jackson 序列化,这里分享下 Fastjson 相关方案:
- 在 Spring MVC 中集成 Fastjson
- 在 Spring MVC 中集成 Fastjson2