jackson序列化时的bug

本文探讨了SpringBoot中Jackson序列化实体为JSON时遇到的三个问题:大小写差异导致的属性忽略、首字母小写后的键名变化以及@JsonProperty注解的特殊行为。同时提到了double类型小数处理的方法@JsonSerialize。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springboot使用默认的jackson在序列化实体为json字符串时的问题,

属性名只有大小写差异时,后面的会被忽略

public static void main(String[] args) throws JsonProcessingException {
        TestVO testVO = new TestVO();
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(testVO));
    }
    @Getter
    @Setter
    @ToString
    public static class TestVO{
        //@JsonProperty("gNo")
        private String gnO = "gnO";
        private String gNo = "gNo";
        private String gnoA = "gnoA";
        private String gnOA = "gnOA";
        private String gNO1o = "gNO1o";
        private String gNO1O = "gNO1O";
        //@JsonSerialize(using = DoubleJsonSerialize.class)
        private Double qty = 1.0;
        private Double qTy1 = 1.00;
        private Double qTY1 = 1.000;
    }

结果

{"gnO":"gnO","gnoA":"gnoA","qty":1.0,"qty1":1.0,"gno1o":"gNO1o"}

首字母小写而第二个字母开始大写时,会序列化为全小写的key

且中间的数字不会影响

@Getter
    @Setter
    @ToString
    public static class TestVO{
        //@JsonProperty("gNo")
        private String gNo = "gNo";
        private String gnO = "gnO";

        private String gnoA = "gnoA";
        private String gnOA = "gnOA";
        private String gNO1o = "gNO1o";
        private String gNO1O = "gNO1O";
        //@JsonSerialize(using = DoubleJsonSerialize.class)
        private Double qty = 1.0;
        private Double qTY1 = 1.000;
        private Double qTy1 = 1.00;

    }
    结果:{"gnoA":"gnoA","qty":1.0,"gno":"gNo","gno1o":"gNO1o","qty1":1.0}

使用@JsonProperty("")后 ,会按指定key名追加在后面

@Getter
    @Setter
    @ToString
    public static class TestVO{
        @JsonProperty("gNo")
        private String gNo = "gNo";
        private String gnO = "gnO";

        private String gnoA = "gnoA";
        private String gnOA = "gnOA";
        private String gNO1o = "gNO1o";
        private String gNO1O = "gNO1O";
        //@JsonSerialize(using = DoubleJsonSerialize.class)
        private Double qty = 1.0;
        @JsonProperty("qTY1")
        private Double qTY1 = 1.001;
        private Double qTy1 = 1.00;

    }
结果:{"gnoA":"gnoA","qty":1.0,"gno1o":"gNO1o","qty1":1.001,"gno":"gNo","gNo":"gNo","qTY1":1.001}

另外double类型带至少一位小数,可以通过@JsonSerialize()来处理,如下所示:

public static void main(String[] args) throws JsonProcessingException {
        TestVO testVO = new TestVO();
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(testVO));
    }
    @Getter
    @Setter
    @ToString
    public static class TestVO{
        @JsonProperty("gNo")
        private String gNo = "gNo";
        private String gnO = "gnO";

        private String gnoA = "gnoA";
        private String gnOA = "gnOA";
        private String gNO1o = "gNO1o";
        private String gNO1O = "gNO1O";
        @JsonSerialize(using = DoubleJsonSerialize.class)
        private Double qty = 1d;
        @JsonProperty("qTY1")
        private Double qTY1 = 1d;
        private Double qTy1 = 1.00;
    }
    结果:{"gnoA":"gnoA","qty":1,"gno1o":"gNO1o","qty1":1.0,"gno":"gNo","gNo":"gNo","qTY1":1.0} 

DoubleJsonSerialize

/**
 * 版权:taylor
 * 描述: double序列化时的位数
 * 创建时间:2020年07月24日
 */
package com.taylor.common.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;

/**
 * 类用途:double序列化时的位数
 *
 * @author taylor
 * @version [V1.0, 2020年07月24日]
 * @since []
 */
public class DoubleJsonSerialize  extends JsonSerializer<Double> {
    /**5位小数*/
    private DecimalFormat df = new DecimalFormat("0.#####");

    @Override
    public void serialize(Double value, JsonGenerator jgen,
                          SerializerProvider provider) throws IOException{
        if(value != null) {
            df.setMaximumFractionDigits(5);
            ///df.setGroupingSize(0);
            df.setRoundingMode(RoundingMode.FLOOR);
            //根据实际情况选择使用
            // gen.writeString(df.format(value));  // 返回出去是字符串
            jgen.writeNumber(df.format(value));
        }
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值