2012-07-03 118 views
21

目前,我正在使用Jackson從我的基於Spring的Web應用程序發出JSON結果。Java到Jackson JSON序列化:Money字段

我遇到的問題是試圖讓所有的金錢領域輸出2位小數。我無法使用setScale(2)解決此問題,因爲像25.50這樣的數字被截斷爲25.5等。

有沒有其他人處理過這個問題?我正在考慮用定製的Jackson序列化程序製作Money類......你可以爲字段變量創建一個自定義的序列化程序嗎?您可能可以...但即使如此,我怎麼能讓我的客戶序列化程序將該數字添加爲2位小數的數字?

+0

你在存儲這些值是什麼?一個'BigDecimal'? –

+0

@GregKopff是一個BigDecimal – ControlAltDel

回答

5

我有同樣的問題,我把它格式化爲JSON作爲一個字符串,而不是。可能有點破解,但很容易實現。

private BigDecimal myValue = new BigDecimal("25.50"); 
... 
public String getMyValue() { 
    return myValue.setScale(2, BigDecimal.ROUND_HALF_UP).toString(); 
} 
40

您可以在您的貨幣字段使用自定義序列化器。這是一個MoneyBean的例子。該字段的數量獲得註釋@JsonSerialize(使用= ...)

public class MoneyBean { 
    //... 

    @JsonProperty("amountOfMoney") 
    @JsonSerialize(using = MoneySerializer.class) 
    private BigDecimal amount; 

    //getters/setters... 
} 

public class MoneySerializer extends JsonSerializer<BigDecimal> { 
    @Override 
    public void serialize(BigDecimal value, JsonGenerator jgen, SerializerProvider provider) throws IOException, 
      JsonProcessingException { 
     // put your desired money style here 
     jgen.writeString(value.setScale(2, BigDecimal.ROUND_HALF_UP).toString()); 
    } 
} 

就是這樣。現在BigDecimal以正確的方式打印出來。我用一個簡單的測試用例來表明它:

@Test 
public void jsonSerializationTest() throws Exception { 
    MoneyBean m = new MoneyBean(); 
    m.setAmount(new BigDecimal("20.3")); 

    ObjectMapper mapper = new ObjectMapper(); 
    assertEquals("{\"amountOfMoney\":\"20.30\"}", mapper.writeValueAsString(m)); 
} 
+1

不錯的方法,但它將其打印爲字符串 - 而不是JSON輸出中的數字類型。 – jro

+17

從商業角度來看,這是一種可怕的方法。資金不應該在序列化時四捨五入。如果你想*拖尾*後面的零(不同於盲目設置刻度),那麼你必須不使用'ROUND_HALF_UP'。另外,不同的貨幣期望不同數量的尾隨小數。 –

+1

jro,如果在Steve的serialize()中使用writeNumber()而不是writeString(),那麼該字段將顯示爲JSON中的數字。 – caelumvox

16

而不是設置@JsonSerialize每個成員上或吸氣劑可以配置使用的是定製串行對於一定類型的模塊的:

SimpleModule module = new SimpleModule(); 
module.addSerializer(BigInteger.class, new ToStringSerializer()); 
objectMapper.registerModule(module); 

在上面的例子中,我使用的串序列化器序列化BigIntegers(因爲JavaScript無法處理這些數值)。

+1

*我在哪裏定義客戶序列化程序?這正是我想要做的,但我無法弄清楚代碼的放置位置。 – DaveH

+0

只要你喜歡,你只需要實現com.fasterxml.jackson.databind.JsonSerializer – Modi

+0

你能更具體一點嗎?我仍然沒有把它放在哪裏。 – Wouter

4

我是jackson-datatype-money的維護人員之一,因此我肯定有偏見,因此請帶着一點鹽來回答這個問題。該模塊應該涵蓋您的需求,並且它相當輕量級(沒有額外的運行時依賴)。此外,它在Jackson docs,Spring docs中提到,並且甚至有some discussions已經關於如何將其整合到Jackson的官方生態系統中。

相關問題