抛弃 Fastjson 拥抱 Jackson

为何抛弃 Fastjson ?

  • 速度是较快一些,但 Jackson 相对稳定,我的程序也不差那 10-20 ms。
  • 序列化对象时为 null 的直接给我去掉了,我知道可以配置不过滤。
  • 配置 null 过滤,再去配置时间格式化过滤,其他的配置再去加。
  • 序列化对象之后,属性顺序乱序,也可以配置,但我想和上面的一起用的时候,要如何配置。
  • 一些日常的小 BUG,可以去看下 fastjson 1.x 版本的 issues ,基本没修复

后面开始记录 Jackson 一些常用方式,平替 Fastjson.

新建 ObjectMapper 转换器的工具类

新建 ObjUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class ObjUtil {
public static ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();

JavaTimeModule javaTimeModule = new JavaTimeModule();

javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));

javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));

objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}

上述代码是用于创建一个 Jackson ObjectMapper 对象,并注册了 JavaTimeModule 模块,以便在序列化和反序列化过程中支持 Java 8 的日期和时间类。

  1. 首先,代码创建了一个新的 ObjectMapper 对象,这是 Jackson 库中用于序列化和反序列化 JSON 数据的核心类。
  2. 接下来,创建了一个 JavaTimeModule 对象,这是 Jackson 库中的一个模块,专门用于处理 Java 8 的日期和时间类。
  3. 通过调用 javaTimeModule.addSerializer 方法,将不同类型的日期和时间类与相应的序列化器关联起来。序列化器将 Java 8 的日期和时间对象转换为特定的字符串格式。例如,LocalDateTime 类型被序列化为 “yyyy-MM-dd HH:mm:ss” 格式的字符串,LocalDate 类型被序列化为 “yyyy-MM-dd” 格式的字符串,LocalTime 类型被序列化为 “HH:mm:ss” 格式的字符串。
  4. 同样,通过调用 javaTimeModule.addDeserializer 方法,将不同类型的日期和时间类与相应的反序列化器关联起来。反序列化器将特定格式的字符串解析为相应的 Java 8 日期和时间对象。例如,LocalDateTime 类型被反序列化从 “yyyy-MM-dd HH:mm:ss” 格式的字符串解析,LocalDate 类型被反序列化从 “yyyy-MM-dd” 格式的字符串解析,LocalTime 类型被反序列化从 “HH:mm:ss” 格式的字符串解析。
  5. 最后,将创建的 JavaTimeModule 注册到 objectMapper 对象中,以便在序列化和反序列化过程中使用该模块的配置。

实体对象转换为 json

给出一个实体类 User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
@Data
@NoArgsConstructor
public class User {

private String name;

private Integer age;

private LocalDateTime brithday;

private String fullName;

}

下面来创建一个 User 实体插入测试值后进行序列化为字符串

1
2
3
4
5
6
7
8
9
10
public class UserTest {
public static void main(String[] args) throws JsonProcessingException {
User user = new User();
user.setBrithday(LocalDateTime.now());
user.setName("张三");
ObjectMapper objectMapper = ObjUtil.objectMapper();
String result = objectMapper.writeValueAsString(user);
System.out.println(result);
}
}

上述代码中通过 ObjUtil.objectMapper() 调用我们在工具类中定义好的转换器

输出:

1
{ "name": "张三", "age": null, "brithday": "2023-08-16 10:38:16", "fullName": null }

给 JSON 中增加一个属性并赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
public class UserTest {
public static void main(String[] args) throws JsonProcessingException {
User user = new User();
user.setBrithday(LocalDateTime.now());
user.setName("张三");
ObjectMapper objectMapper = ObjUtil.objectMapper();
String result = objectMapper.writeValueAsString(user);
System.out.println("User ==> " + result);
ObjectNode jsonNode = (ObjectNode) objectMapper.readTree(result);
jsonNode.put("remark", "精英");
System.out.println("jsonNode ==> " + objectMapper.writeValueAsString(jsonNode));
}
}

上述代码使用了一个已经创建好的 ObjectMapper 对象(通过 ObjUtil.objectMapper() 方法)来进行序列化和反序列化操作,并对 JSON 数据进行修改。

  1. ObjectMapper objectMapper = ObjUtil.objectMapper();: 首先,通过 ObjUtil.objectMapper() 方法获取一个预配置好的 ObjectMapper 对象。这个对象在之前的代码段中已经被配置为支持 Java 8 的日期和时间类的序列化和反序列化。
  2. String result = objectMapper.writeValueAsString(user);: 使用 ObjectMapper 对象将一个名为 user 的对象序列化为 JSON 字符串,并将结果存储在 result 变量中。
  3. System.out.println("User ==> " + result);: 打印刚刚序列化的 JSON 字符串表示的 user 对象。
  4. ObjectNode jsonNode = (ObjectNode) objectMapper.readTree(result);: 通过 ObjectMapper 对象的 readTree 方法,将之前序列化得到的 JSON 字符串解析为一个 JsonNode 对象,然后将其转换为 ObjectNode 类型。这使得你可以对 JSON 数据进行修改。
  5. jsonNode.put("remark", "精英");: 在解析得到的 jsonNode 对象中,添加一个名为 “remark” 的键值对,将值设置为 “精英”。
  6. System.out.println("jsonNode ==> " + objectMapper.writeValueAsString(jsonNode));: 将经过修改的 jsonNode 对象再次序列化为 JSON 字符串,并打印输出。

抛弃 Fastjson 拥抱 Jackson
https://cuifuan.github.io/2023/01/01/back-end/utils/use-jackson/
作者
cuifuan
发布于
2023年1月1日
许可协议