Skip to content

Json ​

概述 ​

Tio-Boot 的 JSON 模块以抽象类 Json 为核心,方便扩展第三方实现。Tio-Boot 官方提供了五种 Json 实现,分别是 TioJson、FastJson2、Jackson、Gson 和 MixedJson,这些实现均继承自抽象类 Json。

抽象类 Json 的核心方法如下:

java
public abstract class Json {
    public abstract String toJson(Object object);
    public abstract <T> T parse(String jsonString, Class<T> type);
}

如上所示,Json 抽象类定义了两个核心方法:toJson(...) 将任意 Java 对象转换为 JSON 字符串,parse(...) 将 JSON 字符串反序列化为指定类型的对象。

JSON 实现 ​

Tio-Boot 官方默认提供了五种 Json 实现,每种实现都有其独特的特性和适用场景。

1. TioJson ​

TioJson 是 Tio-Boot 内置的 JSON 实现,位于 tio-utils 模块中。它主要用于将 Java 对象序列化为 JSON 字符串,不支持反序列化。

特点:

  • 体积小,输出速度快。
  • 仅支持序列化,不支持反序列化。

使用示例:

java
TioJson.getJson().toJson(object);

2. FastJson2 ​

FastJson2 是基于第三方库 FastJSON2 进行的二次封装。该实现依赖于模型和 Java Bean 的 getter 方法进行转换。

特点:

  • 支持丰富的 JSON 转换功能。
  • 可按照 FastJSON 官方文档配置各种转换参数。

依赖配置:

xml
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>${fastjson.version}</version>
</dependency>

3. Jackson ​

Jackson 实现是基于第三方库 Jackson 进行的二次封装,与 FastJson2 类似。

特点:

  • 功能强大,支持复杂的 JSON 操作。
  • 广泛应用于各种 Java 项目中。

依赖配置:

xml
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.0</version>
</dependency>

4. Gson ​

Gson 实现是基于第三方库 Gson 进行的二次封装,与 FastJson2 和 Jackson 类似。

特点:

  • 简洁易用,适合快速开发。
  • 支持多种自定义序列化和反序列化策略。

依赖配置:

xml
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

5. MixedJson ​

MixedJson 是对 TioJson 和 FastJson2 的再一次封装。在序列化时使用 TioJson,反序列化时使用 FastJson2。

特点:

  • 结合了 TioJson 和 FastJson2 的优势。
  • 提供更灵活的 JSON 转换能力。

依赖配置:

xml
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>${fastjson.version}</version>
</dependency>

配置 ​

Tio-Boot 默认使用 MixedJson,序列化委托 TioJson,反序列化委托 FastJson2。可通过 tio.json.provider 选择 fastjson、jackson 或 gson,也可在启动时设置自定义工厂。

默认配置 ​

未指定 provider 时使用 MixedJsonFactory。tio.json.skipNull=true 可让当前工厂的默认输出跳过 null 字段;也可以仅在某个调用点使用 JsonUtils.toSkipNullJson。

自定义配置 ​

可以通过 JsonManager 来设置默认的 JsonFactory,以切换到其他 JSON 实现。

示例:切换到 FastJson2

java
import nexus.io.tio.utils.json.FastJson2Factory;
import nexus.io.tio.utils.json.JsonManager;

JsonManager.me().setDefaultJsonFactory(new FastJson2Factory());

自定义实现:

假设用户扩展了 MyJson 和 MyJsonFactory,可以通过以下方式切换到自定义实现:

java
import nexus.io.tio.utils.json.IJsonFactory;
import nexus.io.tio.utils.json.JsonManager;

public class JsonFactoryConfig {
  public void configure(IJsonFactory factory) {
    JsonManager.me().setDefaultJsonFactory(factory);
  }
}

使用 MixedJsonFactory:

java
import nexus.io.tio.utils.json.JsonManager;
import nexus.io.tio.utils.json.MixedJsonFactory;

JsonManager.me().setDefaultJsonFactory(new MixedJsonFactory());

日期格式配置 ​

可以自定义 Date 类型在序列化后的格式:

java
import nexus.io.tio.utils.json.JsonManager;

JsonManager.me().setDefaultDatePattern("yyyy-MM-dd");

配置示例 ​

以下是一个使用 Jackson 作为默认 JSON 实现的配置示例:

java
import nexus.io.annotation.AConfiguration;
import nexus.io.annotation.Initialization;
import nexus.io.tio.utils.json.JacksonFactory;
import nexus.io.tio.utils.json.JsonManager;

@AConfiguration
public class JsonConfig {

    @Initialization
    public void config() {
        JsonManager.me().setDefaultJsonFactory(new JacksonFactory());
    }
}

JSON 转换用法 ​

Tio-Boot 中的 JSON 转换主要有两类用法:使用配置的 JSON 转换器和指定某个实现进行转换。

1. 使用配置的 JSON 转换器 ​

可以通过 Json 类直接进行 JSON 转换:

java
Json.getJson().toJson(object);
Json.getJson().parse(jsonString, type);

2. 使用 JsonUtils 工具类 ​

Tio-Boot 提供了 JsonUtils 工具类,简化 JSON 转换操作:

java
import nexus.io.tio.utils.json.JsonUtils;

JsonUtils.toJson(object);
JsonUtils.parse(jsonString, type);

3. 使用指定的 JSON 实现 ​

可以临时指定使用某个 JSON 实现进行转换,而不依赖全局配置。例如,临时使用 FastJson2 进行转换:

java
import nexus.io.tio.utils.json.FastJson2;

FastJson2.getJson().toJson(object);
FastJson2.getJson().parse(jsonString, type);

这种用法可以在需要时绕过全局配置,使用特定的 JSON 实现。

4. 单次调用保留 Long 数值类型 ​

为前端展示 ID 时,默认的 TioJson、MixedJson 和 FastJson2 可按全局 Long 策略输出字符串,避免 JavaScript 数值精度损失。对 JSON Schema、计数或第三方协议报文,可以在本次调用中明确保留 Long 为 JSON number,同时沿用项目选择的 JSON 实现。

方法Long 输出null 字段
JsonUtils.toJson(object)沿用当前实现的默认策略沿用当前工厂
JsonUtils.toSkipNullJson(object)沿用当前实现的默认策略跳过
JsonUtils.toJsonWithLongAsNumber(object)JSON number沿用当前工厂
JsonUtils.toSkipNullJsonWithLongAsNumber(object)JSON number跳过

新方法分别委托 Json.getJson().toJson(object, false) 和 Json.getSkipNullJson().toJson(object, false)。TioJson、MixedJson、FastJson2、Jackson、GsonJson 均支持该重载;调用不会切换全局工厂,也不会修改全局 Long 策略,可与普通序列化并发使用。原本的 String 仍输出字符串,数组中的 null 仍保留。

java
import com.jfinal.kit.Kv;
import nexus.io.tio.utils.json.JsonUtils;

public class NumericSchemaExample {
  public static void main(String[] args) {
    Kv schema = Kv.create()
        .set("type", "integer")
        .set("maximum", 9007199254740991L)
        .set("label", "9007199254740991")
        .set("description", null);

    String json = JsonUtils.toSkipNullJsonWithLongAsNumber(schema);
    System.out.println(json);
  }
}

输出中的 maximum 没有引号,label 保留引号,description 被省略:

json
{"type":"integer","maximum":9007199254740991,"label":"9007199254740991"}

字段顺序由所选实现决定。toJsonWithLongAsNumber 沿用工厂的 null 设置:如果已启用 tio.json.skipNull,该方法也会跳过 null 字段。

自定义 Json 实现可覆写 toJson(Object object, boolean longToString),false 表示数值,true 表示字符串。未实现该重载的自定义 provider 会明确抛出 UnsupportedOperationException,便于调用方适配;原有 toJson(Object) 调用保持兼容。不要在单个请求中临时修改再恢复 Json.setLongToString,避免影响其他线程。

TioJson 详解 ​

Tio-Boot 默认使用的 JSON 转换器是 MixedJson,其中:

  • 序列化(Object 转 JSON)使用 TioJson。
  • 反序列化(JSON 转 Object)使用 FastJson2。

这样设计的好处是 TioJson 更轻量,序列化速度更快,而 FastJson2 提供了强大的反序列化能力。

1. 使用 TioJson ​

序列化示例:

java
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import com.jfinal.kit.Kv;
import nexus.io.tio.utils.json.TioJson;

public class WebsiteButtonServiceTest {

    @Test
    public void test() {
        Kv kv = Kv.by("name", "01")
                 .set("link", null)
                 .set("title", "I am the fan marketing team");
        List<Kv> kvList = new ArrayList<>();
        kvList.add(kv);
        TioJson tioJson = new TioJson();
        String json = tioJson.toJson(kvList);
        System.out.println(json);
    }
}

输出结果:

json
[{ "name": "01", "link": null, "title": "I am the fan marketing team" }]

2. 常见参数设置 ​

2.1 跳过空值字段 (SkipNullValueField) ​

默认情况下,SkipNullValueField 的值为 false。如果字段的值为 null,则会输出 "字段名":null。例如:

json
[{ "name": "01", "link": null, "title": "I am the fan marketing team" }]

为了减少前后端的通讯量,可以将 SkipNullValueField 设置为 true,此时值为 null 的字段将被跳过:

java
TioJson.setSkipNullValueField(true);

修改后的输出结果:

json
[{ "name": "01", "title": "I am the fan marketing team" }]

2.2 自定义时间戳格式 (TimestampPattern) ​

TioJson 默认将 java.sql.Timestamp 输出为毫秒时间戳格式。例如:

java
package com.sejie.admin.services;

import java.sql.Timestamp;

import org.junit.Test;

import com.jfinal.kit.Kv;
import nexus.io.tio.utils.json.JsonUtils;

public class TimestampFormatTest {
    @Test
    public void testWithDate() {
        long currentTimeSecond = System.currentTimeMillis();
        Timestamp timestamp = new Timestamp(currentTimeSecond);

        Kv kv = Kv.by("date", timestamp);
        String json = JsonUtils.toJson(kv);
        System.out.println(json);
    }
}

输出结果:

json
{ "date": 1720423322746 }

可以自定义时间戳的输出格式,例如:

java
import nexus.io.tio.utils.json.Json;

Json.setTimestampPattern("yyyy-MM-dd HH:mm:ss");

修改后的输出结果:

json
{ "date": "2024-07-08 16:30:35" }

依赖管理 ​

在使用不同的 JSON 实现时,需要添加相应的依赖。以下是各实现的依赖配置示例:

TioJson ​

无需额外依赖,TioJson 是 Tio-Boot 内置的实现。

FastJson2 ​

xml
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>${fastjson.version}</version>
</dependency>

Jackson ​

xml
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.0</version>
</dependency>

Gson ​

xml
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

MixedJson ​

需要同时添加 TioJson 和 FastJson2 的依赖。由于 TioJson 内置,只需添加 FastJson2 依赖:

xml
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>${fastjson.version}</version>
</dependency>

通过以上配置和使用指南,开发者可以根据项目需求灵活选择和配置 Tio-Boot 的 JSON 实现,充分发挥其在序列化和反序列化过程中的优势。

MIT Licensed