46

を使用しJacksonて、Spring MVCいくつかの単純なオブジェクトを として書き出しますJSON。オブジェクトの 1 つは、amountタイプ のプロパティを持っていますDouble。(Double金額として使用すべきではないことはわかっています。ただし、これは私のコードではありません。)

出力ではJSON、金額を小数点以下 2 桁に制限したいと思います。現在、次のように表示されています。

"amount":459.99999999999994

Spring 3 の@NumberFormatアノテーションを使用してみましたが、その方向では成功していません。他の人にも問題があったようです: MappingJacksonHttpMessageConverter の ObjectMapper は、JSON を JavaBean プロパティにバインドするときに ConversionService を使用しませんここにリンクの説明を入力してください

また、@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見える」は機能します。ただし、これを行うための他のより簡単な(またはより標準的な)方法を誰でも提案できますか。

4

5 に答える 5

0

これまで見てきた最善の方法は、カスタマイズされたシリアライザーと@JsonSerializer(using=NewClass.class). などで試してみたかった@JsonFormat(pattern=".##")のですが、OPの1つのコメントによるとうまくいかないかもしれません(フォーマッターはそれを尊重していないと思います)

ここを参照してください: https://github.com/FasterXML/jackson-databind/issues/632

public class MoneyDeserializer extends JsonDeserializer<BigDecimal> {

    private NumberDeserializers.BigDecimalDeserializer delegate = NumberDeserializers.BigDecimalDeserializer.instance;

    @Override
    public BigDecimal deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        BigDecimal bd = delegate.deserialize(jp, ctxt);
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        return bd;
    }    
}

しかし、より便利でより少ないコードが書かれていますが、通常、フィールドのスケールを決定することはビジネス ロジックの問題であり、(デ) シリアライゼーションの一部ではありません。それについて明確にしてください。ジャクソンはデータをそのまま渡すことができるはずです。

于 2020-06-16T13:51:51.510 に答える
-4

459.99999999999994 は事実上 460 であり、この方法でシリアル化されることが期待されることに注意してください。したがって、ロジックは単に数字を削除するよりもトリッキーにする必要があります。私は次のようなことを提案するかもしれません:

Math.round(value*10)/10.0

それをセッターに入れて、カスタムのシリアライゼーションを取り除きたいと思うかもしれません。

于 2014-03-21T19:07:17.790 に答える