当前位置: 首页 > 知识库问答 >
问题:

为什么在jackson序列化期间省略了小数点为零的Double?

钮博裕
2023-03-14

我使用jackson与Spring来序列化/反序列化从Java到JSON,反之亦然。

当杰克逊将我的Java对象序列化为JSON时,十进制值为零的双精度值被剥离,而具有十进制值的双精度值被考虑在内。例如:550.77被正确序列化为550.77,而440.00被序列化为440(相当于整数)。

如何确保我的double的序列化。00作为保留的十进制值?

@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility =  Visibility.ANY, setterVisibility = Visibility.NONE)
public class Price extends DTO {

private static final long serialVersionUID = -3986616090347452845L;


private Double _exclVat;

private Double _inclVat;


public Price(){
    super();
}

public Price(Double pExclVat, Double pInclVat) {
    this();
    _exclVat = pExclVat;
    _inclVat = pInclVat;
}


public Double getExclVat() {
    return _exclVat;
}

public void setExclVat(Double pExclVat) {
    _exclVat = pExclVat;
}

public Double getInclVat() {
    return _inclVat;
}

public void setInclVat(Double pInclVat) {
    _inclVat = pInclVat;
}
}

JSON格式

"price" : {
  "excl_vat" : 250.0,
  "incl_vat" : 208.33
}

在JSON序列化而不是250.0时,是否可能返回250.00?

共有2个答案

皇甫逸清
2023-03-14

它表现为这样的原因在Double toString方法java doc中已经清楚地指出了。所以在您的情况下,分形部分中有多少个零并不重要。这是摘录

m或a的小数部分必须打印多少位数?必须至少有一个数字来表示小数部分,除此之外,还必须有尽可能多的数字来唯一区分参数值与double类型的相邻值。也就是说,假设x是由该方法为有限非零变元d生成的十进制表示形式表示的精确数学值。那么d必须是最接近x的双倍值;或者,如果两个双精度值与x相等,则d必须是其中之一,d的有效位的最低有效位必须为0。

正如另一个答案所指出的,您可以使用自定义serailizer和十进制格式化程序来格式化您喜欢的值。

或者,您应该考虑对具有所需精度和规模的货币变量使用BigDecimal。

邹山
2023-03-14

如果您确实需要小数点后两位,您可以尝试编写自己的数字序列化器,例如

public class DecimalJsonSerializer extends JsonSerializer<Double> {
  @Override
  public void serialize(Double value, JsonGenerator jgen, SerializerProvider provider) 
    throws IOException, JsonProcessingException {
      jgen.writeString( String.format("%.2f", value));
  }
}

然后使用它为每个字段添加注释

@DecimalJsonSerializer(using=PriceJsonSerializer.class)
private Double _exclVat;

@DecimalJsonSerializer(using=PriceJsonSerializer.class)
private Double _inclVat;

不需要自定义反序列化器。默认反序列化器应该能够很好地处理以这种方式格式化的数字。

 类似资料:
  • 我正在使用Jackson 2.1.4将POJO序列化为JSON,但我想忽略序列化的特定字段。我使用了瞬态,但它仍然在序列化该元素。 我正在序列化如下: 请不要建议,因为我不想将我的模型与杰克逊特定的注释联系起来。是否可以仅使用瞬态完成?对象映射器上是否有任何用于可见性设置的 API?

  • 在这种情况下,如果验证失败,我希望将请求返回给用户,并附上相应的错误消息。我遇到的问题是,我使用Jackson处理JSON请求,验证失败也会导致Jackson无法序列化消息。 例如,如果我有此对象: ...当我去序列化时,字段无效(假设它有11个字符)... ...我得到了一个JsonProcessingException(错误验证对象)。我已经确认一个有效的对象序列化没有问题。所以我的问题是:我

  • 下面是一个演示这个问题的小提琴:https://dotnetfiddle.net/yi47ey 问题是,我们的客户机正在崩溃,因为他们期望一致的格式(例如,总是返回毫秒,即使在) 我找到了这个引用:https://www.w3.org/tr/note-datetime 其中规定: 允许几分之一秒的采用标准必须同时规定最小位数(大于或等于1的数字)和最大位数(最大位数可以说是“无限制”)。 那么,这

  • 我试图使用Jackson的XMLMapper将对象序列化为XML。我希望它在适当的区域有名称空间。然而,当我序列化对象时,每个属性都有一个名称空间--直接属于我试图序列化的类的属性将有一个xmlns=“”,被引用类上的每个属性都包含它们自己的名称空间前缀(而不是整个被引用类的单个前缀)。 我用的是杰克逊2.9.8 我要序列化的主类: 一种特殊类型: XmlMapper配置和测试: 实际的XML输出

  • 我有以下设置: ValidationResults类序列化后,我收到以下错误: 我使用play.libs.Json实用程序类,它只是Jackson对象映射器的包装器。有人知道问题是什么吗?我如何解决这个问题? ValidationError类的结构如下:

  • 无法从字符串“1979-12-05T08:00Z”反序列化java.util.Date类型的值:无效表示(错误:无法分析日期值“1979-12-05T08:00Z”:无法分析日期“1979-12-05T08:00.000Z”:虽然它似乎符合格式“yyyy-mm-dd't'hh:mm:ss.sss'z'',但分析失败 到目前为止,我试图包含这种依赖关系: 还有: 但没有奏效。