jackson使用@JsonSerialize格式化BigDecimal解决.00不显示问题

本文详细解析了在使用BigDecimal处理数据时,从数据库读取到前端展示过程中出现的精度丢失问题。通过自定义BigDecimalSerialize类并结合@JsonSerialize注解,实现了数据格式的统一控制,确保了json数据中数值的精度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、 问题

最近开发中使用BigDecimal这个数据类型 返回json数据时出现了点问题:

# 1.前端第一次保存的时候 穿过来的数据格式 
240.00
240.77
# 2. mysql数据库存储的数据格式(数据库字段已经设置了保留小数点后两位)
240
240.77
# 3. java程序中查看从数据库中查询的回来的数据格式:
240.00
240.77
# 4. 返回前端的json字符串里的数据格式:
240
240.77
# 4. 前端想要的json字符串里的数据格式:
240.00
240.77

由上面的一系列分析可知:要想解决这个根源在于返回json数据的时候需要将数据格式化。

二、解决方案:使用@JsonSerialize输出数据保留两位小数

步骤1.创建一个BigDecimal格式化工具

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.math.BigDecimal;
public class BigDecimalSerialize extends JsonSerializer<BigDecimal> {
    @Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
        if (value != null && !"".equals(value)) {
            gen.writeString(value.setScale(2, BigDecimal.ROUND_HALF_DOWN) + "");
        } else {
            gen.writeString(value + "");
        }
    }
}

步骤二:在返回的实体类对应的属性上加上注解:

@JsonSerialize(using = BigDecimalSerialize.class)
	private BigDecimal totalCost;

总结

这个方案可以统一解决json的Date日期类型,String类型。double类型。。。等等的序列化格式问题

@JsonSerialize正确使用 https://juejin.im/post/5c91ad28e51d4574ed4ee0a3

<think>嗯,用户的问题是关于如何在Java中使用@JsonSerialize注解来控制序列化时的小数点位数。首先,我需要回忆一下Jackson库的相关知识,特别是这个注解的用法。记得@JsonSerialize可以指定一个自定义的序列化器,用户可能需要用这个来实现数字格式化的需求。 接下来,我应该确认用户提到的具体场景:他们想控制小数位数,比如保留两位小数。这时候,需要想到Jackson自带的ToStringSerializer可能够用,因为它只是把对象转成字符串,但无法处理数字格式。因此,用户需要自定义一个序列化器。 然后,步骤应该是怎样的呢?首先,用户需要创建一个自定义的序列化器类,继承自JsonSerializer。然后重写serialize方法,在里面使用NumberFormat或者DecimalFormat来格式化数字。例如,设置最小和最大小数位数为两位,并指定舍入模式。接着,在需要序列化的字段上使用@JsonSerialize注解,指定using属性为这个自定义的序列化器类。 还要注意,用户可能对如何编写自定义序列化器太熟悉,所以需要给出具体的代码示例。例如,展示如何创建DoubleDecimalSerializer类,并在其中使用DecimalFormat进行格式化。同时,提醒用户处理可能的异常情况,比如null值。 另外,需要检查是否有现成的Jackson注解可以直接实现这个功能,比如@JsonFormat。虽然用户明确问了@JsonSerialize,但可能提供其他方法作为补充会更好。例如,@JsonFormat(pattern = "#0.00")也可以达到类似效果,但可能在用户的环境下更适用或者更简洁。 还要考虑用户可能的疑问,比如是否需要处理同的数字类型(Double、BigDecimal等),或者是否需要考虑本地化的问题。这时候,在自定义序列化器中,使用NumberFormat.getInstance()可能会根据Locale同而改变格式,但用户如果希望固定格式,应该明确指定格式模式,如new DecimalFormat("#0.00")。 最后,确保示例代码正确无误,包括导入正确的包,处理异常情况,以及正确应用注解到字段或方法上。同时,引用相关的参考资料,比如站内已有的关于@JsonSerialize的说明,帮助用户进一步理解。</think>### 分步说明 要使用`@JsonSerialize`注解控制序列化时的小数点位数,需通过自定义序列化器实现。以下是具体步骤: --- #### **1. 创建自定义序列化器类** 继承`JsonSerializer<T>`并重写`serialize`方法,使用`NumberFormat`或`DecimalFormat`控制小数位数: ```java import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.text.DecimalFormat; public class DoubleDecimalSerializer extends JsonSerializer<Double> { private static final DecimalFormat df = new DecimalFormat("#0.00"); @Override public void serialize(Double value, JsonGenerator gen, SerializerProvider provider) throws IOException { if (value == null) { gen.writeNull(); // 处理空值 return; } gen.writeNumber(df.format(value)); // 格式化为两位小数 } } ``` --- #### **2. 在字段或方法上应用注解** 通过`@JsonSerialize(using = 自定义序列化器.class)`指定目标字段: ```java public class Product { @JsonSerialize(using = DoubleDecimalSerializer.class) private Double price; // Getter/Setter省略 } ``` --- #### **3. 验证序列化结果** 序列化时,`price`字段会被格式化为两位小数: ```java Product product = new Product(); product.setPrice(12.3456); ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(product); // 输出: {"price":12.35} (自动四舍五入) ``` --- ### **其他注意事项** 1. **灵活调整格式** 修改`DecimalFormat`的模式,例如`#0.000`可保留三位小数。 2. **处理同数值类型** 若需支持`BigDecimal`或其他类型,修改泛型参数(如`JsonSerializer<BigDecimal>`)。 3. **直接使用`@JsonFormat`简化** Jackson提供`@JsonFormat`注解直接定义格式: ```java @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "#0.00") private Double price; ``` --- ### **相关引用** - 自定义序列化器需继承`JsonSerializer`并通过`@JsonSerialize(using=...)`绑定[^1][^3]。 - `@JsonFormat`可在简单场景下替代自定义序列化器[^2]。 ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

T-OPEN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值