FastJson、JackJson 以及 Gson 的区别

简介: FastJson、JackJson 以及 Gson 是 Java 生态圈中三种常用的 Json 解析器,它们均可将 Java 对象序列化为 Json 格式的字符串,也可将 Json 字符串反序列化为 Java 对象。下面我们讨论一下三者在序列化和反序列化操作中的一些区别。

基本介绍

FastJson、JackJson 以及 Gson 是 Java 生态圈中三种常用的 Json 解析器,它们均可将 Java 对象序列化为 Json 格式的字符串,也可将 Json 字符串反序列化为 Java 对象。下面我们讨论一下三者在序列化和反序列化操作中的一些区别。

Spring Boot 默认使用 JackJson 作为 Json 解析器。

序列化

FastJson 和 JackJson 会根据 getter 方法(如 getXXX)或 is 方法(如 isXXX)获取属性名(XXX),然后调用 getter 方法或 is 方法获取属性值,最终将属性和属性值添加到 Json 字符串中。而 Gson 则是通过遍历实体类中的所有属性并直接获取属性值(未调用 getter 方法)来完成序列化操作。

isXXX 方法生效的前提条件是其返回值的类型为 boolean 或 Boolean。

引入 FashJson 和 Gson 的依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.58</version>
</dependency>

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.9</version>
</dependency>

创建实体类 User:

public class User {

    private Integer id;

    private String name;

    public void setId(Integer id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }
}

测试:

public class Test {
    public static void main(String[] args) throws JsonProcessingException {
        User user = new User();
        user.setId(1);
        user.setName("John同学");

        // FastJson 序列化
        String json1 = JSONObject.toJSONString(user);
        System.out.println("FastJson 解析结果: " + json1);
        // Gson 序列化
        Gson gson = new Gson();
        String json2 = gson.toJson(user);
        System.out.println("Gson 解析结果: " + json2);
        // JackJson 序列化
        ObjectMapper objectMapper = new ObjectMapper();
        String json3 = objectMapper.writeValueAsString(user);
        System.out.println("JackJson 解析结果: " + json3);
    }
}

测试结果:

FastJson 解析结果: {}
Gson 解析结果: {"id":1,"name":"John同学"}
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.example.test.User and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

在 User 类中,我们并未添加任何的 getter 方法,因此 FastJson 返回了一个 "空串"。由于 Gson 不依赖 getter,所以它可以解析出完整的属性以及属性值。默认情况下,若 JackJson 未获取到任何属性(通过 getter 方法),那么程序将抛出异常。根据提示,我们可以通过关闭 SerializationFeature.FAIL_ON_EMPTY_BEANS 来忽略该异常。

关闭 SerializationFeature.FAIL_ON_EMPTY_BEANS

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
String json3 = objectMapper.writeValueAsString(user);
System.out.println("JackJson 解析结果: " + json3);

测试结果:

FastJson 解析结果: {}
Gson 解析结果: {"id":1,"name":"John同学"}
JackJson 解析结果: {}

下面我们为 User 类添加 getter 方法和 is 方法,再次测试序列化操作:

public boolean isRemoved() {
    return false;
}

public Integer getId() {
    return id;
}

public String getName() {
    return name;
}

测试结果:

FastJson 解析结果: {"id":1,"name":"John同学","removed":false}
Gson 解析结果: {"id":1,"name":"John同学"}
JackJson 解析结果: {"id":1,"name":"John同学","removed":false}

可见,FashJson 和 JackJson 均解析出了 removed 属性,虽然该属性并未在 User 类中定义,但由于我们添加了 isRemoved 方法且该方法的返回值类型为 boolean,因此 removed 会出现在 Json 串中。反观 Gson,其仅会将 User 类中定义的属性进行序列化。

反序列化

FastJson 和 JackJson 会根据 Json 字符串中的属性,在实体类中查找对应的 setter 方法来为该属性赋值。若未查找到属性对应的 setter 方法,那么 FastJson 会忽略该属性,Jackson 则会抛出异常。相比之下,Gson 会根据 Json 串中的属性以及属性值来填充实体类中对应的属性。

测试:

public class Test {
    public static void main(String[] args) throws JsonProcessingException {
        // FastJson 反序列化
        String json = "{\"id\":1,\"name\":\"John同学\",\"removed\":false}";
        User user1 = JSONObject.parseObject(json, User.class);
        System.out.println("FastJson 解析结果: " + user1);
        // Gson 反序列化
        Gson gson = new Gson();
        User user2 = gson.fromJson(json, User.class);
        System.out.println("Gson 解析结果: " + user2);
        // JackJson 反序列化
        ObjectMapper objectMapper = new ObjectMapper();
        User user3 = objectMapper.readValue(json, User.class);
        System.out.println("JackJson 解析结果: " + user3);
    }
}

测试结果:

FastJson 解析结果: User{id=1, name='John同学'}
Gson 解析结果: User{id=1, name='John同学'}
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "removed" (class com.example.test.User), not marked as ignorable (2 known properties: "id", "name")

上述代码中,我们在 Json 串中添加了一个 User 类中没有的属性,即 removed。FastJson 和 Gson 均会将该属性忽略,而 JackJson 则抛出了异常,该异常提示 "removed 为不能识别的属性"。当然,我们也可以通过配置 ObjectMapper 来忽略该异常:

// JackJson 反序列化
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
User user3 = objectMapper.readValue(json, User.class);
System.out.println("JackJson 解析结果: " + user3);

测试结果:

FastJson 解析结果: User{id=1, name='John同学'}
Gson 解析结果: User{id=1, name='John同学'}
JackJson 解析结果: User{id=1, name='John同学'}

虽然 FastJson 和 JackJson 在反序列化时均会依赖 setter 方法,但二者之间也存在一些区别。如果我们在实体类中未添加某个属性的 setter 方法,那么 FastJson 将不会为该属性赋值,而 JackJson 则会进一步查找同名的属性,接着完成赋值操作。下面我们注释掉 User 类中的 setName 方法:

//    public void setName(String name) {
//        this.name = name;
//    }

再次测试反序列化操作:

FastJson 解析结果: User{id=1, name='null'}
Gson 解析结果: User{id=1, name='John同学'}
JackJson 解析结果: User{id=1, name='John同学'}
相关文章
|
3月前
|
机器学习/深度学习 负载均衡 网络架构
Mixture of Experts架构的简要解析
Mixture of Experts(MoE)架构起源于1991年,其核心思想是通过多个专门化的“专家”网络处理输入的不同部分,并由门控网络动态组合输出。这种架构实现了稀疏激活,仅激活部分专家,从而在模型规模与计算成本之间取得平衡。MoE的关键在于门控机制的设计,如线性门控、噪声Top-K门控等,确保模型能根据输入特征自适应选择专家。
463 8
|
算法 安全 Go
Python与Go语言中的哈希算法实现及对比分析
Python与Go语言中的哈希算法实现及对比分析
283 0
|
域名解析 缓存 网络协议
【域名解析 DNS 专栏】DNS 域名解析基础:从入门到精通
【5月更文挑战第21天】DNS是互联网的&quot;导航员&quot;,将域名转换为IP地址。Python示例展示了如何解析域名。DNS服务器层级结构包括根、顶级和权威服务器,协同完成高效解析。DNS缓存加速访问,但可能导致旧信息留存。DNS安全问题如DNS欺骗可借助DNSSEC等技术防范。理解DNS对网络从业者和用户都至关重要。
356 3
【域名解析 DNS 专栏】DNS 域名解析基础:从入门到精通
|
网络协议 中间件 Linux
SOME/IP概述2【SOME/IP的主要中间件功能+SOME/IP报文PDU的封装】
SOME/IP概述2【SOME/IP的主要中间件功能+SOME/IP报文PDU的封装】
SOME/IP概述2【SOME/IP的主要中间件功能+SOME/IP报文PDU的封装】
|
Python
【Python】已解决:(pandas读取DataFrame列报错)raise KeyError(key) from err KeyError: (‘name‘, ‘age‘)
【Python】已解决:(pandas读取DataFrame列报错)raise KeyError(key) from err KeyError: (‘name‘, ‘age‘)
1862 0
|
弹性计算 Ubuntu Linux
【3秒极速开服】Palworld/幻兽帕鲁服务器全自动部署极简教程(新手推荐)
本文将为您提供极简部署幻兽帕鲁专属服务器(Dedicated Server)的指引,「仅需轻点三次鼠标,3秒轻松开服」,和自己的朋友一起开心“抓帕鲁”。在帕鲁的世界中,与神奇的生物共度悠闲时光是一种无与伦比的乐趣。然而,有时官方服务器的不稳定性可能会给游戏体验带来延迟和卡顿。为了告别这些问题,部署自己的幻兽帕鲁服务器成为了一个不错的选择。通过搭建专属的游戏服务器(Dedicated Server),和小伙伴们获得一个专属的服务空间,获得顺畅流畅的游戏体验。
2387 1
|
JSON fastjson Java
FastJson使用技巧
FastJson使用技巧
|
数据库 测试技术 Java
阿里技术专家详解DDD系列 第二弹 - 应用架构
应用架构,指软件系统中固定不变的代码结构、设计模式、规范和组件间的通信方式。在应用开发中架构之所以是最重要的第一步,因为一个好的架构能让系统安全、稳定、快速迭代。但是今天我们在做业务研发时,更多会关注一些宏观的架构,而忽略了应用内部的架构设计,希望能通过案例分析和重构,推演出一套高质量的DDD架构。
58627 24
阿里技术专家详解DDD系列 第二弹 - 应用架构
|
XML JSON C++
C++的Json解析库:jsoncpp和boost .
JSON(JavaScript Object Notation)跟xml一样也是一种数据交换格式,了解json请参考其官网http://json.org/,本文不再对json做介绍,将重点介绍c++的json解析库的使用方法。
3179 0