栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

fastjson, jackjson, Gson三者异同

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

fastjson, jackjson, Gson三者异同

起源

当后端接口向前端返回数据时,有时response数据是null, 十分不利于前端处理。

因此为了统一格式,需要返回在:

  • 接口返回得数据是String类型时,不返回null,而返回 “”
  • 接口返回得数据是Map类型时,不返回null,而返回 {}
  • 接口返回得数据是List类型时,不返回null,而返回 []

为了解决这个问题,就到了选择json序列化工具得时候,目前有三种工具:

  • fastjson 是阿里巴巴2011年的开源 json 解析库
  • jackjson 是 spring boot 官方内置得 json 解析库
  • Gson 是 Google 官方2008年开源得 json 解析库
如何选择?

选择 jackson.( 2.13.0+版本)速度与性能安全,功能完善适中得选项。

如何使用?

添加坐标


	......
    2.13.2
    ......



	...
   
    
        com.fasterxml.jackson.core
        jackson-databind
        ${jackson.version}
    
    
        com.fasterxml.jackson.core
        jackson-annotations
        ${jackson.version}
    
    
        com.fasterxml.jackson.core
        jackson-core
        ${jackson.version}
    
    ...

全局配置文件:JacksonConfig.java

package com.springblog.config;


import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collection;



@Configuration
public class JacksonConfig {
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer() {
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                String fieldName = jsonGenerator.getOutputContext().getCurrentName();
                try {
                    Field field = jsonGenerator.getCurrentValue().getClass().getDeclaredField(fieldName);
                    if (CharSequence.class.isAssignableFrom(field.getType())) {
                        // 字符串空值 “”
                        jsonGenerator.writeString("");
                    } else if (Collection.class.isAssignableFrom(field.getType())) {
                        //列表型空值返回[]
                        jsonGenerator.writeStartArray();
                        jsonGenerator.writeEndArray();
                    } else {
                        //map类型空值,或者bean对像,返回{}
                        jsonGenerator.writeStartObject();
                        jsonGenerator.writeEndObject();
                    }
                } catch (NoSuchFieldException ignoredException) {
                    // 忽略该异常
                }
            }
        });
        return objectMapper;
    }
}
 
原理讲解 

jackson有三个核心模块,如下,括号内是maven的artifactId:

  • Stre
  • aming(jackson-core):低阶API库,提供流式解析工具JsonParser,流式生成工具JsonGenerator;
  • Annotations(jackson-annotations):jackson注解;
  • Databind (jackson-databind):基于java对象的序列化、反序列化能力,需要前面两个模块的支持才能实现;

当我们用jackson做JSON操作时,常用的是 Databind 模块 的 ObjectMapper 类,对处于核心位置的jackson-core反倒是很少直接用到,那么该模块有什么作用呢?

在 jackson-core 中,有一个叫做 BeanSerializer 的功能类,其 serialize 方法负责 将java对象转为JSON字符串,方法中的处理逻辑就是调用JsonGenerator提供的API,而JsonGenerator就是jackson-core中负责序列化的主要功能类

日常使用序列化功能
  1. 将JSON转换为Java对象
  • 将json字符串序列化为Java对象
    public void jsonDemo() {
        String jsonString = "{ "title" : "json博客标题", "description" : "json文章描述" }";
        
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            BlogEntity blog = objectMapper.readValue(jsonString, BlogEntity.class);

            System.out.println("car brand = " + blog.getTitle());
            System.out.println("car doors = " + blog.getDescription());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

jackjson支持从各种类型数据中进行序列化为java对象,支持类型如下:

  • json字符串
ObjectMapper objectMapper = new ObjectMapper();
String json =
        "{ "title" : "标题", "description" :"描述" }";
Car car = objectMapper.readValue(json, BlogEntity.class);
  • 文件file
ObjectMapper objectMapper = new ObjectMapper();
File file = new File("data/blog.json");
BlogEntity blog = objectMapper.readValue(file, BlogEntity.class);
  • 字符输入流StringReader
ObjectMapper objectMapper = new ObjectMapper();
String json =
        "{ "title" : "标题", "description" :"描述" }";
Reader reader = new StringReader( json);
BlogEntity blog = objectMapper.readValue(file, BlogEntity.class);
  • JSON via URL
ObjectMapper objectMapper = new ObjectMapper();
URL url = new URL("file:data/blog.json");
BlogEntity blog = objectMapper.readValue(url, BlogEntity.class);
  • 字节输入流FileInputStream
ObjectMapper objectMapper = new ObjectMapper();
InputStream input = new FileInputStream("data/blog.json");
BlogEntity blog = objectMapper.readValue(input , BlogEntity.class);
  • 字节数组 List
ObjectMapper objectMapper = new ObjectMapper();
byte[] bytes =
        "{ "title" : "标题", "description" : “描述” }".getBytes("UTF-8");
BlogEntity blog = objectMapper.readValue(bytes , BlogEntity.class);
  • JSON数组字符串 :
ObjectMapper objectMapper = new ObjectMapper();
 String jsonArray = "[{"title":"标题"}, {"description":"描述"}]"
 // 转换为 Array
 BlogEntity[] blogs = objectMapper.readValue(jsonArray  , BlogEntity.class);

// 转换为List
 List blogs2 = objectMapper.readValue(jsonArray, new TypeReference>(){});
  • JSON字符串Map
ObjectMapper objectMapper = new ObjectMapper();
String jsonObject = "{"brand":"ford", "doors":5}";
Map jsonMap = objectMapper.readValue(jsonObject,
    new TypeReference>(){});
  1. 将java对象转换为json字符串
 BlogEntity blogEntity = new BlogEntity();
 blogEntity.setTitle("新博客");
 blogEntity.setDescription("文章描述");
        
ObjectMapper objectMapper = new ObjectMapper();

String str = objectMapper.writeValueAsString(blogEntity);
System.out.println(str);
日常使用序列化注解
注解用法
@JsonProperty用于属性,把属性的名称序列化时转换为另外一个名称。示例:
@JsonProperty(“birth_date”)
private Date birthDate;
@JsonFormat用于属性或者方法,把属性的格式序列化时转换成指定的格式。示例:
@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm”) )
public Date getBirthDate(){ }
@JsonPropertyOrder用于类, 指定属性在序列化时 json 中的顺序 , 示例:)
@JsonPropertyOrder({ “birth_Date”, “name” })
public class Person(){ }
@JsonCreator用于构造方法,和 @JsonProperty 配合使用,适用有参数的构造方法。 示例:
@JsonCreator
public Person(@JsonProperty(“name”) String name) {
  …
}
@JsonAnySetter用于属性或者方法,设置未反序列化的属性名和值作为键值存储到 map 中 )
@JsonAnySetter
public void set(String key, Object,value) {
   map.put(key, value);
}
@JsonAnyGetter用于方法 ,获取所有未序列化的属性 public Map any() { return map; }
参考资料

jackjson官方文档
jackjson方法细节
自定义解析

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号