2012-07-03 16 views
21

Attualmente sto usando Jackson per inviare i risultati JSON dalla mia applicazione web Spring.Serializzazione da Java a Jackson JSON: Campi monetari

Il problema che sto avendo sta tentando di far uscire tutti i campi con 2 cifre decimali. Non ero in grado di risolvere questo problema usando setScale (2), dato che numeri come 25.50 sono troncati a 25.5 ecc.

Qualcun altro ha affrontato questo problema? Stavo pensando di creare una classe Money con un serializzatore Jackson personalizzato ... puoi creare un serializzatore personalizzato per una variabile di campo? Probabilmente puoi ... Ma ancora, come posso ottenere il serializzatore cliente per aggiungere il numero come numero con 2 cifre decimali?

+0

In che cosa stai memorizzando questi valori? Un 'BigDecimal'? –

+0

@GregKopff yes a BigDecimal – ControlAltDel

risposta

5

Ho avuto lo stesso problema e lo avevo formattato in JSON come stringa. Potrebbe essere un po 'un trucco, ma è facile da implementare.

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

È possibile utilizzare un serializzatore personalizzato nel proprio campo economico. Ecco un esempio con MoneyBean. Il campo importo viene annotato con @JsonSerialize (usando = ...).

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()); 
    } 
} 

Questo è tutto. Un BigDecimal viene ora stampato nel modo giusto. Ho usato un semplice banco di prova per mostrarlo:

@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

Approccio gradevole, ma viene stampato come stringa - non un tipo numerico nell'output JSON. – jro

+17

Dal punto di vista del business, questo è un approccio terribile. Il denaro non dovrebbe essere arrotondato al momento della serializzazione. Se si desidera * pad * con zeri finali (diverso dall'impostazione cieca della scala), è necessario farlo senza 'ROUND_HALF_UP'. Inoltre, valute diverse prevedono un numero diverso di decimali finali. –

+1

jro, Se writeNumber() viene utilizzato al posto di writeString() in serialize di Steve(), il campo verrà visualizzato come numero nel JSON. – caelumvox

16

Invece di impostare la @JsonSerialize in ogni membro o getter è possibile configurare un modulo che utilizzano un serializzatore custome per un certo tipo:

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

Nell'esempio di cui sopra, ho usato la stringa serializzatore per serializzare BigIntegers (dal momento che javascript non può gestire tali valori numerici).

+1

* dove * definisco il serializzatore cliente? Questo è esattamente ciò che voglio fare, ma non posso risolvere il punto in cui inserire questo codice. – DaveH

+0

Ovunque ti piaccia, devi solo implementare com.fasterxml.jackson.databind.JsonSerializer – Modi

+0

Puoi essere un po 'più specifico? Ancora non capisco dove metterlo. – Wouter

4

Sono uno dei manutentori di jackson-datatype-money, quindi prendi questa risposta con un pizzico di sale dato che sono certamente di parte. Il modulo dovrebbe coprire le tue esigenze ed è piuttosto leggero (senza ulteriori dipendenze di runtime). Inoltre è menzionato nel numero Jackson docs, Spring docs e c'erano addirittura some discussions già su come integrarlo nell'ecosistema ufficiale di Jackson.

Problemi correlati