Json 转换

概述

tio-boot 的 json 模块以抽象类 Json 为核心,方便扩展第三方实现,tio-boot 官方给出了 4 个 Json 实现,分别是 TioJson、FastJson、Jackson,Gson 这 4 个实现继承自抽象类 Json。

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

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

如上代码可以看出 Json 抽象就是 Object 与 json string 互转的两个方法,toJson(...)将任意 java 类型转成 json string,而 parse 将 json string 再反向转成范型指定的对象。

Json 配置

tio-boot 官方提供了 Json 抽象类的三个实现:TioJson、FastJson、Jackson,如果不进行配置,那么默认使用 TioJson 实现,指定为其它实现需要在 configConstant 进行如下配置:

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

上面配置将系统默认使用的 TioJson 切换到了 FastJson。还可以通过扩展 Json 抽象类以及 JsonFactory 来实现定制的 Json 实现。

假定用户扩展出了一个 MyJson 与 MyJsonFactory ,那么可以通过如下的方式切换到自己的实现上去:

JsonManager.me().setJsonFactory(new MyJsonFactory());

此外,tio-boot 官方还提供了 MixedJson、MixedJsonFactory 实现,这个实现让转 json string 时使用 TioJson,反向转成对象则使用 FastJson。 如果希望在非 web 下进行配置,需要使用 JsonManager,例如:

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

还可以配置 Date 类型转 json 后的格式:

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

注意,在使用 MixedJsonFactory、FastJsonFactory、JacksonFactory 时需要添加其依赖,具体依赖参考下一小节内容。

Json 的实现

官方默认给出了 5 种 json 实现:TioJson、FastJson、Jackson、MixedJson,Gson 可以满足绝大多数需求。

1、TioJson

TioJson 是 tio-boot 的 tio-utils 内置的 json 实现,只支持输出 json,不知解析 json

2、FastJson2

FastJson2 是对第三方的 fastjson2 进行的二次封装,该实现最重要的一点就是转换依赖于 Model、java bean 的 getter 方法。使用 fastjson 可以按照其官方文档去配置 fastjson 的各种转换参数。

使用 FastJson2 封装时,需要添加其依赖:

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

3、Jackson

该实现与 FastJson 类似,是对第三方的 jackson 的二次封装

使用 Jackson 封装时,需要添加其依赖:

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

4、Gson

该实现与 FastJson 类似,是对第三方的 Gson 的二次封装

使用 Gson 封装时,需要添加其依赖:

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

5、MixedJson

MixedJson 是对 TioJson、FastJson 的再一次封装,Object 转 json string 时使用 TioJson 的实现,而反向 json string 转 Object 使用 FastJson。

这个实现结合了 TioJson 与 FastJson 两者的优势。 前者不支持 json string 到 Object 的转换,后者不支持关联表 sql 查询动态字段的转换。

使用 MixedJson 封装时需要添加 FastJson 封装的依赖:

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

Json 转换用法

json 转换在 tio-boot 中的使用分为两类用法,第一类是使用配置的 json 转换,第二类是指定某个实现进行 json 转换。

使用 Json 类进行 json 转换

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

使用 JsonUtils 工具类进行转换

import com.litongjava.tio.utils.json.JsonUtils

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

使用指定的 json 实现转换

如果下代码将使用指定的 json 实现去转换:

// 临时指定使用 FastJson 实现
FastJson.getJson().toJson(...);
FastJson.getJson().parse(...);

上面这种用法可以临时摆脱配置的 json 实现,从而使用指定的 json 实现。

TioJson

使用 TioJson

Tio-boot 默认使用的 JSON 转换器是 MixedJson,解析和输出分别采用不同的实现:

  • 解析 JSON 默认使用的是 FastJson2
  • 输出 JSON 默认使用的是内置的 TioJson

这样做的好处是 TioJson 更小,输出速度更快。

TioJson.getJson().toJson(json)

使用 TioJson 示例

下面是一个简单的示例,展示了如何使用 TioJson 进行 JSON 转换:

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

import org.junit.Test;

import com.jfinal.kit.Kv;
import com.litongjava.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);
  }
}

TioJson 常见参数设置

SkipNullValueField-跳过空值字段

SkipNullValueField 的默认值为 false,如果字段的值为 null,默认会输出 字段名:null,示例如下:

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

如果想减少前后端的通讯量,可以将 SkipNullValueField 的值设置为 true,示例代码如下:

TioJson.setSkipNullValueField(true);

修改后的输出结果如下:

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

TimestampPattern-自定义时间戳格式化格式

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

package com.sejie.admin.services;

import java.sql.Timestamp;

import org.junit.Test;

import com.jfinal.kit.Kv;
import com.litongjava.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);
  }
}

输出结果:

{ "date": 1720423322746 }

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

import com.litongjava.tio.utils.json.Json;

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

修改后的输出结果如下:

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