【发布时间】:2023-04-05 00:06:01
【问题描述】:
我正在使用Jackson 和Spring MVC,将一些简单的对象写成JSON。其中一个对象具有amount 属性,类型为Double。 (我知道Double 不应该用作货币金额。但是,这不是我的代码。)
在JSON 输出中,我想将金额限制为小数点后两位。目前显示为:
"amount":459.99999999999994
我尝试过使用 Spring 3 的 @NumberFormat 注释,但在这个方向上没有成功。看起来其他人也有问题:MappingJacksonHttpMessageConverter's ObjectMapper does not use ConversionService when binding JSON to JavaBean propertiesenter link description here。
另外,我尝试使用带有自定义序列化程序的 @JsonSerialize 注释。
在模型中:
@JsonSerialize(using = CustomDoubleSerializer.class)
public Double getAmount()
和序列化器实现:
public class CustomDoubleSerializer extends JsonSerializer<Double> {
@Override
public void serialize(Double value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
if (null == value) {
//write the word 'null' if there's no value available
jgen.writeNull();
} else {
final String pattern = ".##";
//final String pattern = "###,###,##0.00";
final DecimalFormat myFormatter = new DecimalFormat(pattern);
final String output = myFormatter.format(value);
jgen.writeNumber(output);
}
}
}
CustomDoubleSerializer“似乎”可以工作。但是,任何人都可以提出任何其他更简单(或更标准)的方法吗?
【问题讨论】:
-
一种方法是在 setter 方法中格式化金额,然后将值设置为字段。因此
getAmount()将返回 2 个十进制值。不确定它是否可以满足您的要求。如果其他人期望该字段的精度,此实现可能会产生副作用。 -
舍入序列化程序对我来说似乎是正确的方法。或者,创建两个 getter,即
getAmountPrecise()和getAmountRounded(),并且只序列化后者。 -
您能否使用此属性向 POJO 添加任何新方法?你能改变这个类还是它属于外部库?
-
也许您可以通过使用
private static final DecimalFormat formatter = new DecimalFormat(".##");并在之后引用字段formatter来提高性能,因为无论如何它一直都是一样的? -
你试过
@JsonFormat(shape = JsonFormat.Shape.NUMBER_FLOAT, pattern=...)吗?但我认为你的方式是标准的。