自定义MonetaryAmount JSR354 / moneta的Databind Json序列化格式

时间:2017-05-17 19:39:24

标签: java json serialization jackson jsr354

我正在尝试使用MonetaryAmount字段作为字符串将Json序列化为POJO,但结果输出不符合规定的形状格式。

// org.javamoney:moneta:1.1 
// com.fasterxml.jackson.core:jackson-annotations:2.7.0
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "CBNOT_CHARGEBACK_AMOUNT"
})
public class TestMonetaryAmountJsonSerialization {
        @JsonProperty("CBNOT_CHARGEBACK_AMOUNT")
        @NotNull
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "¤#,##0.00", locale = "en_US")
        private final MonetaryAmount chargebackAmount = Monetary.getDefaultAmountFactory().setCurrency("USD").setNumber(12.50).create();

        private static final ObjectMapper mapper = new ObjectMapper();

        @Test
        public void testThis() throws JsonProcessingException{
            String json = mapper.writeValueAsString(this);
            System.out.println(json);
            Assert.assertEquals("{\"CBNOT_CHARGEBACK_AMOUNT\":\"¤12.50\"}",json);
        }

}

OUTPUT: {"CBNOT_CHARGEBACK_AMOUNT":{"currency":{"context":{"empty":false,"providerName":"java.util.Currency"},"defaultFractionDigits":2,"currencyCode":"USD","numericCode":840},"number":12.5,"factory":{"defaultMonetaryContext":{"precision":0,"fixedScale":false,"amountType":"org.javamoney.moneta.Money","maxScale":63,"empty":false,"providerName":null},"maxNumber":null,"minNumber":null,"amountType":"org.javamoney.moneta.Money","maximalMonetaryContext":{"precision":0,"fixedScale":false,"amountType":"org.javamoney.moneta.Money","maxScale":-1,"empty":false,"providerName":null}},"context":{"precision":0,"fixedScale":false,"amountType":"org.javamoney.moneta.Money","maxScale":63,"empty":false,"providerName":null},"numberStripped":12.5,"zero":false,"negative":false,"negativeOrZero":false,"positive":true,"positiveOrZero":true}}

任何想法我做错了什么?我在这里的代码中扔了厨房水槽,仅用于说明目的和紧凑的演示。

1 个答案:

答案 0 :(得分:0)

JsonFormat是杰克逊定义的几个(de)序列化程序中使用的注释(例如DateTimeSerializerBaseNumberSerializers.Base和其他一些完整列表here),它不是通用机制将任何对象转换为字符串:

  

与大多数其他杰克逊注释不同,注释没有   具体的通用解释:相反,效果取决于数据类型   被注释的财产(或更具体地说,反序列化器和   正在使用的序列化器。)

除非您为pattern创建自定义序列化程序或使用使用此注释(以及其MonetaryAmount属性)的自定义序列化程序,否则指定它将没有任何效果,但是如果您创建自定义序列化程序,您可能不需要这种灵活性,以便为不同的字段指定不同的模式,并且可以使用固定的MonetaryAmountFormat或者从@JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "CBNOT_CHARGEBACK_AMOUNT" }) public class TestMonetaryAmountJsonSerialization { @JsonProperty("CBNOT_CHARGEBACK_AMOUNT") @NotNull private final MonetaryAmount chargebackAmount = Monetary.getDefaultAmountFactory().setCurrency("USD").setNumber(12.50).create(); private static final ObjectMapper mapper = new ObjectMapper(); static { SimpleModule monetaryModule = new SimpleModule(); monetaryModule.addSerializer(MonetaryAmount.class, new MonetaryAmountSerializer()); mapper.registerModule(monetaryModule); } @Test public void testThis() throws JsonProcessingException { String json = mapper.writeValueAsString(this); System.out.println(json); Assert.assertEquals("{\"CBNOT_CHARGEBACK_AMOUNT\":\"$12.50\"}", json); } public static class MonetaryAmountSerializer extends JsonSerializer<MonetaryAmount> { public void serialize(MonetaryAmount monetaryAmount, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { StringBuilder sb = new StringBuilder(); MonetaryAmountDecimalFormatBuilder .of("¤#,##0.00").withCurrencyUnit(monetaryAmount.getCurrency()).build() .print(sb, monetaryAmount); jsonGenerator.writeString(sb.toString()); } } } 对象构建必要的字符串。

例如

{{1}}