记一次由jackson-PropertyNamingStrategy.SNAKE_CASE-导致的问题

json里有命名为home_test的字段需要反序列化
可直接看情景5-解决方案

情景1

正常情况下

json字段

jsonString包含"home_test"字段

String newjson1 = "{\"biztype\":1236,\"hometown\":\"11\",\"hoMe\":\"hm\",\"home_test\":\"hm_test_value\"}";

目标类

注意这里的命名方式,有下划线

package json;

public class Obj {
    // 注意这里的命名方式
    private String home_test;
    public String getHome_test() {
        return home_test;
    }
    public void setHome_test(String home_test) {
        this.home_test = home_test;
    }
    @Override
    public String toString() {
        return "Obj{" +
                "home_test='" + home_test + '\'' +
                '}';
    }
}

测试用例

package json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

public class Test {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注意是否开启
        // objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        String newjson1 = "{\"biztype\":1236,\"hometown\":\"11\",\"hoMe\":\"hm\",\"home_test\":\"hm_test_value\"}";

        Obj obj = objectMapper.readValue(newjson1, Obj.class);
        System.out.println(obj);
    }
}

输出结果

Obj{home_test='hm_test_value'}

情景2

json字段-同1

目标类

注意这里的命名方式,没有下划线

package json2;

public class Obj {
    // 注意这里的命名方式
    private String homeTest;
    public String getHomeTest() {
        return homeTest;
    }
    public void setHomeTest(String homeTest) {
        this.homeTest = homeTest;
    }
    @Override
    public String toString() {
        return "Obj{" +
                "homeTest='" + homeTest + '\'' +
                '}';
    }
}

测试用例-同1

package json2;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Test {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注意是否开启
        // objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        String newjson1 = "{\"biztype\":1236,\"hometown\":\"11\",\"hoMe\":\"hm\",\"home_test\":\"hm_test_value\"}";

        Obj obj = objectMapper.readValue(newjson1, Obj.class);
        System.out.println(obj);
    }
}

输出结果

Obj{homeTest='null'}

开启PropertyNamingStrategy.SNAKE_CASE

// 注意是否开启
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

测试用例

package json2;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

public class Test {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注意是否开启
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        String newjson1 = "{\"biztype\":1236,\"hometown\":\"11\",\"hoMe\":\"hm\",\"home_test\":\"hm_test_value\"}";

        Obj obj = objectMapper.readValue(newjson1, Obj.class);
        System.out.println(obj);
    }
}

输出结果

Obj{homeTest='hm_test_value'}

注意!!!!有坑

情景3

PropertyNamingStrategy.SNAKE_CASE开启后,带来的问题

json字段-同1

注意“hoMe”字段

String newjson1 = "{\"biztype\":1236,\"hometown\":\"11\",\"hoMe\":\"hm\",\"home_test\":\"hm_test_value\"}";

目标类

增加hoMe属性,注意home的命名方式,与json一致

package json3;

public class Obj {
    // 注意这里的命名方式
    private String homeTest;
    // 注意home的命名方式
    private String hoMe;
    public String getHomeTest() {
        return homeTest;
    }
    public void setHomeTest(String homeTest) {
        this.homeTest = homeTest;
    }
    public String getHoMe() {
        return hoMe;
    }
    public void setHoMe(String hoMe) {
        this.hoMe = hoMe;
    }
    @Override
    public String toString() {
        return "Obj{" +
                "homeTest='" + homeTest + '\'' +
                ", hoMe='" + hoMe + '\'' +
                '}';
    }
}

测试用例-同2

开启 objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

package json3;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

public class Test {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注意是否开启
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        String newjson1 = "{\"biztype\":1236,\"hometown\":\"11\",\"hoMe\":\"hm\",\"home_test\":\"hm_test_value\"}";

        Obj obj = objectMapper.readValue(newjson1, Obj.class);
        System.out.println(obj);
    }
}

输出结果

Obj{homeTest='hm_test_value', hoMe='null'}

存在问题


开启PropertyNamingStrategy.SNAKE_CASE,解决了home_test转homeTest问题,但是引入了hoMe转hoMe失败问题

问题原因

个人怀疑源码hash存在问题

在这里插入图片描述

情景4-暂时性解决方案

不开启PropertyNamingStrategy.SNAKE_CASE,并解决home_test转homeTest问题
**

目标对象

只新增了私有的setHome_test方法

package json4;

public class Obj {
    // 注意这里的命名方式
    private String homeTest;
    // 注意home的命名方式
    private String hoMe;
    public String getHomeTest() {
        return homeTest;
    }
    public void setHomeTest(String homeTest) {
        this.homeTest = homeTest;
    }
    // 新增了私有的setHome_test方法
    private void setHome_test(String homeTest) {
        this.homeTest = homeTest;
    }
    public String getHoMe() {
        return hoMe;
    }
    public void setHoMe(String hoMe) {
        this.hoMe = hoMe;
    }
    @Override
    public String toString() {
        return "Obj{" +
                "homeTest='" + homeTest + '\'' +
                ", hoMe='" + hoMe + '\'' +
                '}';
    }
}

测试用例

关闭PropertyNamingStrategy.SNAKE_CASE

package json4;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

public class Test {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注意是否开启
        // objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        String newjson1 = "{\"biztype\":1236,\"hometown\":\"11\",\"hoMe\":\"hm\",\"home_test\":\"hm_test_value\"}";

        Obj obj = objectMapper.readValue(newjson1, Obj.class);
        System.out.println(obj);
    }
}

输出结果

Obj{homeTest='hm_test_value', hoMe='hm'}

在这里插入图片描述

情景5-解决方案

直接字段映射注解

// 注意这里的命名方式
@JsonProperty(value = "home_test")
private String homeTest;
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值