Jackson替换FastJson的注意点(坑)


Jackson替换FastJson的注意点(坑)


一、Jackson与FastJson的不同默认配置

1、序列化时Jackson与FastJson的默认配置区别
配置jackSonFastJsonJackson统一配置代码
默认是否输出transient字段输出不输出mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
默认是否开启排序不开启开启mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
默认都是时间对象都是时间戳输出mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

测试代码:

@Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class User {
        private int id;
        private String name;
        private Date birthDay;
        private List  feature;
        private transient String idCard;
    }

    @Test
    public void serial() {
        User user = new User(10, "钟无常", new Date(),new LinkedList(),"350913156158164165x");

        /*Jackon序列化*/
        ObjectMapper mapper = new ObjectMapper(); // jackson的核心类
        //默认都是时间对象都是时间戳输出
        //mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        //默认输出transient字段,FastJson默认不输出
        mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
        //默认不开启排序,FastJson根据字典排序(指定order除外)
        mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);

        // java对象转json字符串
        String jacksonStr;
        try {
            jacksonStr = mapper.writeValueAsString(user);
            System.out.println("Jackson对象转Json:" + jacksonStr);
        } catch (JsonProcessingException e) {
            System.out.println("解析失败");
        }

        /*FastJson序列化*/
        String fastJsonStr = JSON.toJSONString(user);
        System.out.println("FastJson对象转Json:" + fastJsonStr);
    }
2、反序列化时Jackson与FastJson的默认配置区别
配置JacksonFastJsonJackson统一配置代码
是否识别不带引号的key关闭开启mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
是否识别单引号的key关闭开启mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
浮点数默认类型doubleBigDecimalmapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
是否无视JavaBean中不存在的字段异常无视objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
默认开启Json@type指定类型解析mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
默认key或value是null时也输出(只对VO起作用,Map List不起作用)输出不输出mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
key是否主动常量池交换FastJson会主动调用key.intern()
枚举变量名FastJson获取枚举名时会从枚举name字段获取

测试代码:

    String str = "{'Switch_1':{\"null\":null,\"date\":2021-06-01T12:23:00.235+08:00,\"age\":1.22},\"女生\":{\"id\":null,\"name\":\"李四\",\"age\":24}}";

    @Test
    public void deSerial() {
        /*Jackson*/
        ObjectMapper mapper = new ObjectMapper();
        /*区别FastJson的配置,并赋予调整至和FastJson一致配置代码*/
        /*反序列化*/
        //是否识别不带引号的key-默认关闭,FastJson默认开启
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        //是否识别单引号的key-默认关闭,FastJson默认开启
        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        //浮点数类型-默认double,FastJson默认BigDecimal
        mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
        //默认开启Json@type指定类型解析,FastJson默认关闭
        //mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        /*序列化*/
        //默认key或value是null时也输出(只对VO起作用,Map List不起作用),FastJson默认不输出
        mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);


        Map<String, User> map2 = null;
        try {
            map2 = mapper.readValue(str, new TypeReference<Map>() {
            });
        } catch (IOException e) {
            System.out.println("解析失败");
        }
        System.out.println("Jackson字符串转map:" + map2);
        /*FastJson*/
        Map map = JSON.parseObject(str);
        /*区别Jackson的配置*/
        //key字符串默认会调用key.intern()加入常量池
        //序列化枚举时会使用枚举名-默认开启

        System.out.println("FastJson字符串转map:" + map);
    }

二、引用依赖

Spring 支持的三个JSON库(Gson、Jackson、JSON-B)中,Jackson是首选默认库,所以在引用Jackson时Spring项目不需要额外引用依赖

1、Springboot

spring-boot-starter-web间接引入了Jackson依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
2、Web Starter

web starter中依赖json starter:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-json</artifactId>
</dependency>
2、Maven项目

Maven项目中以来Jackson(version移步去仓库选)
Jackson的Maven地址

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.module</groupId>
  <artifactId>jackson-module-parameter-names</artifactId>
</dependency>

三、其他坑位

1、非明确转换类型

在断点处我们的预期结果应该是testFastjson,打jackson中是"testFastjson",而在FastJson中它是没有引号的。
其主要原因是指定的默认解析类型是ObjectNode.class,该类型实际解析类型是LinkedHashMap,value值内容将会被完整保留。
故在使用时应结合业务指定具体类型
在这里插入图片描述

2、未知JavaBean字段异常

在FastJson和Gson中解析到映射不上的字段时并不会报错,而Jackson就会报错,该默认配置在会影响到不规范的前端请求,以导致报错。

解决方式:添加以下配置

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); //忽略未知字段

测试代码

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class User {
        private int id;
        private String name;
        private Date birthDay;
        private List  feature;
        private transient String idCard;
    }

    @Test
    public void bugTest2() {
        String jsonString="{\"id\":11,\n" +
                "  \"name\":\"钟无艳\",\n" +
                "        \"birthDay\":\"2021-06-01T12:23:00.235+08:00\",\n" +
                "        \"feature\":[],\n" +
                "        \"idCard\":\"35092312316514\",\n" +
                "\"other\":null\n" +
                "}";
        //Jackson解析json
        ObjectMapper objectMapper = new ObjectMapper();
        //objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            User user  = objectMapper.readValue(jsonString, User.class);
            System.out.println("Jackson解析结果:"+user);
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }

        //FastJson解析
        User user1 = JSON.parseObject(jsonString, User.class);
        System.out.println("FastJson解析结果:"+user1);
    }

异常结果
在这里插入图片描述

–eof–

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
jacksonfastjson都是用于处理JSON数据的Java库。它们提供了序列化和反序列化JSON数据的功能。 在序列化方面,这两个库有一些差异。fastjson默认情况下不会序列化null值,也就是说如果一个属性的值是null,在序列化后,该属性将不会出现在JSON字符串中。而jackson则默认会序列化null值,即使属性的值为null,该属性也会在JSON字符串中呈现。 两个库在序列化时也有一些其他的功能配置。例如,fastjson可以通过设置fastjson的序列化过滤器进行定制化处理,还可以美化输出JSON字符串等。而jackson可以全局配置序列化的行为,比如将驼峰命名转换为下划线命名,忽略某些属性的序列化等。 在反序列化方面,fastjsonjackson都提供了相应的功能。它们可以将JSON字符串转化为Java对象。 总结来说,jacksonfastjson都是功能强大的Java库,用于处理JSON数据。它们在序列化和反序列化方面有一些差异,并且提供了不同的配置选项来满足不同的需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [jacksonfastjson](https://blog.csdn.net/xuxuxux123/article/details/126625323)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [JacksonFastJson快速入门(整合SpringMVC)](https://blog.csdn.net/qq_45173404/article/details/108417438)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值