FastJson2
FASTJSON v2是FASTJSON项目的重要升级,目标是为下一个十年提供一个高性能的JSON库。通过同一套API,
支持JSON/JSONB两种协议,JSONPath是一等公民。 支持全量解析和部分解析。 支持Java服务端、客户端Android、大数据场景。 支持Kotlin 支持 JSON Schema https://github.com/alibaba/fastjson2/wiki/json_schema_cn 支持Android (2.0.10.android) 支持Graal Native-Image (2.0.10.graal)
使用Fastjson2
创建实体类
UserInfoEntity
package local.ateng.java.fastjson2.entity;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 用户信息实体类
* 用于表示系统中的用户信息。
*
* @author 孔余
* @since 2024-01-10 15:51
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserInfoEntity {
/**
* 用户ID
*/
private Long id;
/**
* 用户姓名
*/
private String name;
/**
* 用户年龄
* 注意:这里使用Integer类型,表示年龄是一个整数值。
*/
private Integer age;
/**
* 分数
*/
private Double score;
/**
* 用户生日
* 注意:这里使用Date类型,表示用户的生日。
*/
private Date birthday;
/**
* 用户所在省份
*/
private String province;
/**
* 用户所在城市
*/
private String city;
/**
* 创建时间
* 自定义时间格式
*/
@JSONField(format = "yyyy-MM-dd HH:mm:ss.SSS")
private LocalDateTime createAt;
}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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
测试数据准备
添加依赖
<!-- JavaFaker: 用于生成虚假数据的Java库 -->
<dependency>
<groupId>com.github.javafaker</groupId>
<artifactId>javafaker</artifactId>
<version>1.0.2</version>
</dependency>2
3
4
5
6
创建数据类
package local.ateng.java.fastjson2.init;
import com.github.javafaker.Faker;
import local.ateng.java.fastjson2.entity.UserInfoEntity;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* 初始化数据
*
* @author 孔余
* @email 2385569970@qq.com
* @since 2025-01-09
*/
@Getter
public class InitData {
List<UserInfoEntity> list;
List<UserInfoEntity> list2;
public InitData() {
//生成测试数据
// 创建一个Java Faker实例,指定Locale为中文
Faker faker = new Faker(new Locale("zh-CN"));
// 创建一个包含不少于100条JSON数据的列表
List<UserInfoEntity> userList = new ArrayList();
for (int i = 1; i <= 3000; i++) {
UserInfoEntity user = new UserInfoEntity();
user.setId((long) i);
user.setName(faker.name().fullName());
user.setBirthday(faker.date().birthday());
user.setAge(faker.number().numberBetween(0, 100));
user.setProvince(faker.address().state());
user.setCity(faker.address().cityName());
user.setScore(faker.number().randomDouble(3, 1, 100));
userList.add(user);
}
list = userList;
for (int i = 1; i <= 3000; i++) {
UserInfoEntity user = new UserInfoEntity();
user.setId((long) i);
user.setName(faker.name().fullName());
user.setBirthday(faker.date().birthday());
user.setAge(faker.number().numberBetween(0, 100));
user.setProvince(faker.address().state());
user.setCity(faker.address().cityName());
user.setScore(faker.number().randomDouble(3, 1, 100));
userList.add(user);
}
list2 = userList;
}
}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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
创建测试类
在 test 包下创建测试类
package local.ateng.java.fastjson2;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import local.ateng.java.fastjson2.entity.UserInfoEntity;
import local.ateng.java.fastjson2.init.InitData;
import org.junit.jupiter.api.Test;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
public class JSONObjectTests {
List<UserInfoEntity> list;
List<UserInfoEntity> list2;
public JSONObjectTests() {
InitData initData = new InitData();
list = initData.getList();
list2 = initData.getList2();
}
}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
使用JSONObject
反序列化部分
字符串转换为JSONObject
// 字符串转换为JSONObject
@Test
void testDeSerializer1() {
String str = "{\"id\":12345,\"name\":\"John Doe\",\"age\":25,\"score\":85.5,\"birthday\":\"1997-03-15\",\"province\":\"Example Province\",\"city\":\"Example City\"}";
JSONObject jsonObject = JSONObject.parseObject(str);
System.out.println(jsonObject);
// {"id":12345,"name":"John Doe","age":25,"score":85.5,"birthday":"1997-03-15","province":"Example Province","city":"Example City"}
}2
3
4
5
6
7
8
字符串转换为java对象
// 字符串转换为java对象
@Test
void testDeSerializer2() {
String str = "{\"id\":null,\"name\":\"John Doe\",\"age\":25,\"score\":0.0,\"birthday\":\"2024-01-18 15:05:10.102\",\"province\":\"\",\"city\":\"Example City\"}";
UserInfoEntity user = JSONObject.parseObject(str, UserInfoEntity.class);
System.out.println(user);
// UserInfoEntity(id=null, name=John Doe, age=25, score=0.0, birthday=Thu Jan 18 15:05:10 CST 2024, province=, city=Example City, createAt=null)
}2
3
4
5
6
7
8
JSONObject转换为java对象
// JSONObject转换为java对象
@Test
void testDeSerializer3() {
JSONObject jsonObject = JSONObject.of(
"name", "John Doe",
"age", 25,
"birthday", "2024-01-18 15:05:10.102",
"city", "Example City",
"province", "Example province",
"score", 85.5
);
UserInfoEntity user = jsonObject.toJavaObject(UserInfoEntity.class);
System.out.println(user);
// UserInfoEntity(id=null, name=John Doe, age=25, score=85.5, num=null, birthday=Thu Jan 18 15:05:10 CST 2024, province=Example province, city=Example City, createAt=null, list=null, user=null, children=null)
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
容忍松散 JSON 格式
// 容忍松散 JSON 格式
@Test
void testDeSerializer4() {
String str = "{\n" +
" // id\n" +
" \"id\": 12345,\n" +
" name: \"John Doe\", // 姓名\n" +
" /* 年龄 */\n" +
" \"age\": 25,\n" +
" \"score\": 85.5,\n" +
" 'birthday': \"1997-03-15\",\n" +
" \"province\": \"Example Province\",\n" +
" \"city\": \"Example City\",\n" +
" other: 1\n" +
"}";
JSONObject user = JSONObject.parse(
str,
JSONReader.Feature.SupportSmartMatch, // 默认下是camel case精确匹配,打开这个后,能够智能识别camel/upper/pascal/snake/Kebab五中case
JSONReader.Feature.AllowUnQuotedFieldNames, // 允许字段名不带引号
JSONReader.Feature.IgnoreNoneSerializable, // 忽略无法序列化的字段
JSONReader.Feature.IgnoreAutoTypeNotMatch // 防止类型不匹配时报错(更安全)
);
System.out.println(user);
// {"birthday":"1997-03-15","score":85.5,"other":1,"province":"Example Province","city":"Example City","name":"John Doe","id":12345,"age":25}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
序列化部分
这些还可以放在类或者字段上 类:@JSONType(serializeFeatures = {JSONWriter.Feature.WriteNulls}) 字段:@JSONField(serialzeFeatures = {SerializerFeature.WriteMapNullValue})
输出空字段
// 输出空字段
@Test
void testSerializer1() {
TestSerializerEntity1 user = new TestSerializerEntity1();
user.setId(1L);
String str = JSONObject.toJSONString(user,
// 序列化输出空值字段
JSONWriter.Feature.WriteNulls
);
System.out.println(str);
// {"age":null,"birthday":null,"datetime":null,"entity":null,"id":1,"list":null,"map":null,"name":null,"num":null,"score":null,"status":null}
}
@Data
public static class TestSerializerEntity1 {
private Long id;
private String name;
private Integer age;
private Double score;
private BigDecimal num;
private Boolean status;
private Date birthday;
private LocalDateTime datetime;
private List<String> list;
private TestSerializerEntity1 entity;
private Map<String, String> map;
}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
基于字段反序列化
基于字段反序列化,如果不配置,会默认基于public的field和getter方法序列化。配置后,会基于非static的field(包括private)做反序列化。在fieldbase配置下会更安全
// 基于字段反序列化
@Test
void testSerializer11() {
TestSerializerEntity11 user = new TestSerializerEntity11();
user.setId(1L);
user.setABBCCdd("阿腾");
user.setName("Ateng");
String str = JSONObject.toJSONString(user,
// 基于字段反序列化
JSONWriter.Feature.FieldBased
);
System.out.println(str);
// {"aBBCCdd":"阿腾","id":1,"name":"Ateng"}
String str2 = JSONObject.toJSONString(user);
System.out.println(str2);
// {"ABBCCdd":"阿腾","id":1,"name":"Ateng"}
}
@Data
public static class TestSerializerEntity11 {
private Long id;
private String name;
private String aBBCCdd;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
输出缺省值
// 输出缺省值
@Test
void testSerializer12() {
TestSerializerEntity1 user = new TestSerializerEntity1();
user.setId(1L);
String str = JSONObject.toJSONString(user,
// 将空置输出为缺省值,Number类型的null都输出为0,String类型的null输出为"",数组和Collection类型的输出为[]
JSONWriter.Feature.NullAsDefaultValue
);
System.out.println(str);
// {"age":0,"birthday":null,"id":1,"list":[],"name":"","num":0,"score":0,"status":false}
}2
3
4
5
6
7
8
9
10
11
12
格式化
// 格式化
@Test
void testSerializer2() {
UserInfoEntity user = UserInfoEntity.builder()
.name("John Doe")
.age(25)
.score(85.5)
.birthday(new Date())
.province(null)
.city("Example City")
.build();
// JSONWriter.Feature.PrettyFormat -> 格式化输出
String str = JSONObject.toJSONString(user, JSONWriter.Feature.PrettyFormat);
System.out.println(str);
/*
{
"age":25,
"birthday":"2025-11-05 17:25:58.053",
"city":"Example City",
"name":"John Doe",
"score":85.5
}
*/
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
防止循环引用导致 "$ref"
// 防止循环引用导致 "$ref"
@Test
void testSerializer3() {
// 创建两个相互引用的对象
UserInfoEntity user1 = UserInfoEntity.builder()
.name("John Doe")
.age(25)
.score(85.5)
.birthday(new Date())
.province(null)
.city("Example City")
.build();
UserInfoEntity user2 = UserInfoEntity.builder()
.name("John Doe")
.age(25)
.score(85.5)
.birthday(new Date())
.province(null)
.city("Example City")
.build();
// 相互引用,形成循环
user1.setUser(user2);
user2.setUser(user1);
// 打开循环引用检测
String json2 = JSONObject.toJSONString(user1, JSONWriter.Feature.ReferenceDetection);
System.out.println("打开循环引用检测:");
System.out.println(json2);
// {"age":25,"birthday":"2025-11-05 17:27:45.362","city":"Example City","name":"John Doe","score":85.5,"user":{"age":25,"birthday":"2025-11-05 17:27:45.362","city":"Example City","name":"John Doe","score":85.5,"user":{"$ref":"$"}}}
// 默认情况下(关闭循环引用检测)
String json1 = JSONObject.toJSONString(user1);
System.out.println("默认序列化:");
System.out.println(json1);
}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
34
35
36
37
保证 BigDecimal 精度
// 保证 BigDecimal 精度(金融系统常用)
@Test
void testSerializer4() {
UserInfoEntity user = UserInfoEntity.builder()
.name("John Doe")
.age(25)
.score(85.5)
.birthday(new Date())
.province(null)
.num(new BigDecimal("1E+20"))
.city("Example City")
.build();
String str = JSONObject.toJSONString(user, JSONWriter.Feature.WriteBigDecimalAsPlain);
System.out.println(str);
// 输出:{"age":25,"birthday":"2025-11-05 17:29:39.404","city":"Example City","name":"John Doe","num":100000000000000000000,"score":85.5}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
把 Long 类型转为字符串
// 把 Long 类型转为字符串,避免前端精度丢失
@Test
void testSerializer44() {
UserSerializer44 user = new UserSerializer44();
user.setId(9223372036854775807L);
user.setNum(new BigDecimal("1E+20"));
String str = JSONObject.toJSONString(user, JSONWriter.Feature.WriteLongAsString);
System.out.println(str);
// 输出:{"id":"9223372036854775807","num":1E+20}
}
@Data
public static class UserSerializer44 {
private Long id;
private BigDecimal num;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
浏览器安全输出(防止前端注入)
// 浏览器安全输出(防止前端注入)
@Test
void testSerializer5() {
UserInfoEntity user = UserInfoEntity.builder()
.id(9223372036854775807L)
.name("John Doe")
.age(25)
.score(85.5)
.birthday(new Date())
.province(null)
.city("Example City <script>alert('XSS')</script>")
.build();
String str = JSONObject.toJSONString(user, JSONWriter.Feature.BrowserCompatible, JSONWriter.Feature.BrowserSecure);
System.out.println(str);
// 输出:{"age":25,"birthday":"2025-11-05 17:36:45.81","city":"Example City \u003Cscript\u003Ealert\u0028'XSS'\u0029\u003C/script\u003E","id":"9223372036854775807","name":"John Doe","score":85.5}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
输出类型信息(反序列化时保留类型)
// 输出类型信息(反序列化时保留类型)
@Test
void testSerializer6() {
UserInfoEntity user = UserInfoEntity.builder()
.name("John Doe")
.age(25)
.score(85.5)
.birthday(new Date())
.province(null)
.city("Example City ")
.build();
String str = JSONObject.toJSONString(user, JSONWriter.Feature.WriteClassName);
System.out.println(str);
// 输出:{"@type":"local.ateng.java.fastjson2.entity.UserInfoEntity","age":25,"birthday":"2025-11-05 17:37:54.721","city":"Example City ","name":"John Doe","score":85.5}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
枚举字段 序列化和反序列化
/**
* 枚举字段 序列化和反序列化
*/
@Test
void testEnum() {
// 序列化
userEnumEntity user = new userEnumEntity();
user.setId(1L);
user.setUserEnum(UserEnum.ENABLE);
String str = JSONObject.toJSONString(user);
System.out.println(str);
// {"id":1,"userEnum":"开启"}
// 反序列化
String str2 = "{\"id\":1,\"userEnum\":1}";
userEnumEntity user2 = JSONObject.parseObject(str2, userEnumEntity.class);
System.out.println(user2);
// JSONObjectTests.userEnumEntity(id=1, userEnum=ENABLE)
}
@Data
public static class userEnumEntity {
private Long id;
private UserEnum userEnum;
}
public enum UserEnum {
ENABLE(1, "开启"),
DISABLE(2, "关闭");
private Integer code;
private String name;
UserEnum(int code, String name) {
this.code = code;
this.name = name;
}
public Integer getCode() {
return code;
}
@JSONField
public String getName() {
return this.name;
}
@JSONCreator
public static UserEnum fromCode(Integer code) {
if (code == null) {
return null;
}
for (UserEnum e : values()) {
if (e.code.equals(code)) {
return e;
}
}
return null;
}
}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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
字段注解部分
指定默认值,在序列化时生效,反序列化不生效
/**
* 指定默认值,在反序列化时生效,序列化不生效
*/
@Test
void testField0() {
// 序列化
User0 user = new User0();
user.setId(1L);
String str = JSONObject.toJSONString(user);
System.out.println(str);
// {"id":1}
// 反序列化
String str2 = "{\"id\":1}";
User0 user2 = JSONObject.parseObject(str2, User0.class);
System.out.println(user2);
// JSONObjectTests.User0(id=1, name=阿腾, age=25)
}
@Data
public static class User0 {
private Long id;
@JSONField(defaultValue = "阿腾")
private String name;
@JSONField(defaultValue = "25")
private Integer age;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
禁用序列化/反序列化字段
/**
* 禁用序列化/反序列化字段
*/
@Test
void testField00() {
// 序列化
User00 user = new User00();
user.setId(1L);
user.setName("阿腾");
user.setAge(25);
String str = JSONObject.toJSONString(user);
System.out.println(str);
// {"id":1,"name":"阿腾"}
// 反序列化
String str2 = "{\"age\":\"25\",\"id\":1,\"name\":\"阿腾\"}";
User00 user2 = JSONObject.parseObject(str2, User00.class);
System.out.println(user2);
// JSONObjectTests.User00(id=1, name=阿腾, age=null)
}
@Data
public static class User00 {
private Long id;
private String name;
@JSONField(serialize = false, deserialize = false)
private Integer age;
}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
指定 JSON 字段名
/**
* 指定 JSON 字段名
* 🔹 序列化结果字段名变为 "user_name"
* 🔹 反序列化时会自动匹配 "user_name"
*/
@Test
void testField1() {
// 序列化
User1 user = new User1();
user.setName("John Doe");
String str = JSONObject.toJSONString(user);
System.out.println(str);
// {"user_name":"John Doe"}
// 反序列化
String str2 = "{\"user_name\":\"John Doe\"}";
User1 user2 = JSONObject.parseObject(str2, User1.class);
System.out.println(user2);
// JSONObjectTests.User1(name=John Doe)
}
@Data
public static class User1 {
@JSONField(name = "user_name")
private String name;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
日期格式化
/**
* 日期格式化
* 🔹 控制日期序列化输出格式
* 🔹 反序列化时也会自动识别同格式字符串
* 🔹 优先级高于 JSON.DEFFAULT_DATE_FORMAT
*/
@Test
void testField2() {
// 序列化
User2 user = new User2();
user.setBirthday(new Date());
user.setDateTime(LocalDateTime.now());
String str = JSONObject.toJSONString(user);
System.out.println(str);
// {"birthday":"2025年11月06 09:14:43","dateTime":"2025年11月06日 09时14分43秒"}
// 反序列化
String str2 = "{\"birthday\":\"2025年11月04 16:24:35\",\"dateTime\":\"2025年11月04日 16时24分35秒\"}";
User2 user2 = JSONObject.parseObject(str2, User2.class);
System.out.println(user2);
// JSONObjectTests.User2(birthday=Tue Nov 04 16:24:35 CST 2025, dateTime=2025-11-04T16:24:35)
}
@Data
public static class User2 {
@JSONField(format = "yyyy年MM月dd HH:mm:ss")
private Date birthday;
@JSONField(format = "yyyy年MM月dd日 HH时mm分ss秒")
private LocalDateTime dateTime;
}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
小数(如 BigDecimal、Double、Float)字段格式化
/**
* 小数(如 BigDecimal、Double、Float)字段格式化
*/
@Test
void testField3() {
// 序列化
User3 user = new User3();
user.setScore(new BigDecimal("1234.5678"));
user.setScore1(1234.5678);
user.setScore2(1234.0);
user.setScore3(0.1267);
user.setScore4(85.0);
user.setScore5(9999999.99);
String str = JSONObject.toJSONString(user);
System.out.println(str);
// {"score":1234.6,"score1":1234.5678,"score2":1234.00,"score3":12.67%,"score4":85,"score5":9,999,999.99}
// 反序列化
// 无,格式化后的 12.67% 9,999,999.99 数据无法转换成数字类型
}
@Data
public static class User3 {
/** 保留两位小数(常用于金额、分数等) */
@JSONField(format = "#0.0")
private BigDecimal score;
/** 默认输出,不指定 format */
private Double score1;
/** 保留两位小数(常用于金额、分数等) */
@JSONField(format = "#0.00")
private Double score2;
/** 百分比格式(乘100并附加%符号) */
@JSONField(format = "0.##%")
private Double score3;
/** 没有小数(取整显示) */
@JSONField(format = "#")
private Double score4;
/** 千分位 + 两位小数(财务场景常用) */
@JSONField(format = "#,##0.00")
private Double score5;
}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
34
35
36
37
38
39
40
41
42
43
44
45
字段排序
字段注解排序
// 字段排序
@Test
void testField4() {
UserField4 user = new UserField4();
user.setId1(9223372036854775807L);
user.setId2(9223372036854775807L);
user.setId3(9223372036854775807L);
String str = JSONObject.toJSONString(user);
System.out.println(str);
// 输出:{"id3":9223372036854775807,"id2":9223372036854775807,"id1":9223372036854775807}
}
@Data
public static class UserField4 {
@JSONField(ordinal = 3)
private Long id1;
@JSONField(ordinal = 2)
private Long id2;
@JSONField(ordinal = 1)
private Long id3;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
类注解排序
@Test
void testField5() {
UserField5 user = new UserField5();
user.setId1(9223372036854775807L);
user.setId2(9223372036854775807L);
user.setId3(9223372036854775807L);
user.setId4(9223372036854775807L);
user.setId5(9223372036854775807L);
String str = JSONObject.toJSONString(user);
System.out.println(str);
// 输出:{"id5":9223372036854775807,"id3":9223372036854775807,"id1":9223372036854775807,"id2":9223372036854775807,"id4":9223372036854775807}
}
@Data
@JSONType(orders = {"id5", "id3", "id1"})
public static class UserField5 {
private Long id1;
private Long id2;
private Long id3;
private Long id4;
private Long id5;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
自定义序列化器/反序列化器
数值格式化
/**
* 数值格式化
*/
@Test
void testCustom1() {
// 序列化
Custom1 user = new Custom1();
user.setScore1(66.666);
user.setScore2(new BigDecimal("12345.67890"));
String str = JSONObject.toJSONString(user);
System.out.println(str);
// {"score1":66.67,"score2":"¥12,345.68"}
// 反序列化
String str2 = "{\"score1\":66.67,\"score2\":\"¥12,345.68\"}";
Custom1 user2 = JSONObject.parseObject(str2, Custom1.class);
System.out.println(user2);
// JSONObjectTests.Custom1(score1=66.67, score2=12345.68)
}
@Data
public static class Custom1 {
/** 保留两位小数(常用于金额、分数等) */
@JSONField(format = "#0.00")
private Double score1;
/** 保留两位小数(常用于金额、分数等) */
@JSONField(serializeUsing = CurrencySerializer.class, deserializeUsing = CurrencyDeserializer.class)
private BigDecimal score2;
}
/** 金额格式化:#,##0.00 带千分位 */
public static class CurrencySerializer implements ObjectWriter<BigDecimal> {
private static final DecimalFormat FORMAT = new DecimalFormat("#,##0.00");
@Override
public void write(JSONWriter jsonWriter, Object value, Object fieldName, Type fieldType, long features) {
// 检查是否为 null
if (value == null) {
jsonWriter.writeString("¥0.00");
return;
}
// 如果不是 BigDecimal 类型,直接返回 "¥0.00" 作为默认值
if (!(value instanceof BigDecimal)) {
jsonWriter.writeString("¥0.00");
return;
}
// 类型转换安全地进行
BigDecimal val = (BigDecimal) value;
// 格式化并写入数据
jsonWriter.writeString("¥" + FORMAT.format(val)); // 写入格式化后的字符串
}
}
/** 金额反序列化(去掉¥和,) */
public static class CurrencyDeserializer implements ObjectReader<BigDecimal> {
@Override
public BigDecimal readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
String val = jsonReader.readString();
if (val == null) return BigDecimal.ZERO;
String cleaned = val.replace("¥", "").replace(",", "").trim();
try {
return new BigDecimal(cleaned);
} catch (Exception e) {
return BigDecimal.ZERO;
}
}
}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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
数据脱敏
/**
* 数据脱敏
*/
@Test
void testCustom2() {
// 序列化
Custom2 user = new Custom2();
user.setId(1L);
user.setMobile("17623062936");
String str = JSONObject.toJSONString(user);
System.out.println(str);
// {"id":1,"mobile":"176****2936"}
// 反序列化
// 无
}
@Data
public static class Custom2 {
private Long id ;
/** 手机号脱敏 */
@JSONField(serializeUsing = SensitiveSerializer.class)
private String mobile;
}
/** 脱敏序列化器 */
public static class SensitiveSerializer implements ObjectWriter<String> {
@Override
public void write(JSONWriter jsonWriter, Object value, Object fieldName, Type fieldType, long features) {
if (value == null) {
jsonWriter.writeNull();
return;
}
String strValue = value.toString();
// 简单示例:手机号脱敏
if (strValue.matches("\\d{11}")) {
strValue = strValue.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
}
jsonWriter.writeString(strValue);
}
}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
34
35
36
37
38
序列化过滤器
使用 PropertyPreFilter 过滤字段
PropertyPreFilter 可以根据字段的名称来决定是否序列化该字段。
/**
* PropertyPreFilter: 根据字段名过滤字段
* PropertyPreFilter 可以根据字段的名称来决定是否序列化该字段。
*/
@Test
void testFilter0() {
// 序列化
FilterEntity0 user = new FilterEntity0();
user.setId(1L);
user.setName("阿腾");
user.setAge(25);
// 使用 PropertyFilter 过滤掉 "age" 字段
String str = JSON.toJSONString(user, Filter0());
System.out.println(str);
// 输出: {"id":1,"name":"阿腾"}
}
// 实体类定义
@Data
public static class FilterEntity0 {
private Long id;
private String name;
private Integer age;
}
// 定义一个 PropertyFilter,过滤掉 "age" 字段
public static PropertyPreFilter Filter0() {
return (writer, source, name) -> !"age".equals(name);
}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
使用 ValueFilter 修改字段的值
ValueFilter 可以在序列化时修改字段的值。例如,将 null 值替换为其他值,或者对某个字段进行格式化。
/**
* ValueFilter: 修改字段的值
* ValueFilter 可以在序列化时修改字段的值。例如,将 null 值替换为其他值,或者对某个字段进行格式化。
*/
@Test
void testFilter1() {
// 序列化
FilterEntity1 user = new FilterEntity1();
user.setId(1L);
user.setName("阿腾");
user.setAge(null); // Age 为 null
// 使用 ValueFilter 将 null 值替换为默认值
// JSONWriter.Feature.WriteNulls 特性需要加上,否则为null的值就不会走Filter
String str = JSON.toJSONString(user, Filter1(), JSONWriter.Feature.WriteNulls);
System.out.println(str);
// 输出: {"age":"未知","id":1,"name":"阿腾"}
}
// 实体类定义
@Data
public static class FilterEntity1 {
private Long id;
private String name;
private Integer age;
}
// 定义一个 ValueFilter,修改字段的值
public static ValueFilter Filter1() {
return (object, name, value) -> {
if (value == null) {
if ("age".equals(name)) {
return "未知"; // 如果 age 字段为 null,替换为 "未知"
}
}
return value;
};
}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
34
35
36
使用 ContextValueFilter 修改字段
ContextValueFilter: 基于上下文修改字段的值
ContextValueFilter 与 ValueFilter 类似,但它能通过 context 获取序列化上下文信息,
如字段的 Field 对象,从而访问注解或类型信息,实现更灵活的序列化控制。
/**
* ContextValueFilter: 基于上下文修改字段的值
* ContextValueFilter 与 ValueFilter 类似,但它能通过 context 获取序列化上下文信息,
* 如字段的 Field 对象,从而访问注解或类型信息,实现更灵活的序列化控制。
*
* 下面的示例通过自定义 @DefaultValue 注解,
* 在序列化时如果字段值为 null,就自动替换为注解中指定的默认值。
*/
@Test
void testFilter3() {
// 序列化
User user = new User();
user.setId(1L);
user.setName(null); // 没有设置名称
user.setAge(null); // 没有设置年龄
// 使用 ContextValueFilter 序列化
// JSONWriter.Feature.WriteNulls 特性需要加上,否则为null的值就不会走Filter
String json = JSON.toJSONString(user, defaultValueFilter(), JSONWriter.Feature.WriteNulls);
System.out.println(json);
// 输出: {"age":18,"id":1,"name":"未知用户"}
}
/**
* 定义 ContextValueFilter:
* 可通过 context(包含字段元信息)访问注解,实现动态默认值替换
*/
public static ContextValueFilter defaultValueFilter() {
return (context, object, name, value) -> {
if (value == null) {
try {
// 从当前字段读取 @DefaultValue 注解
DefaultValue annotation = context.getField().getAnnotation(DefaultValue.class);
if (annotation != null) {
return annotation.value(); // 使用注解中的默认值
}
} catch (Exception ignored) {
}
}
return value;
};
}
// 自定义注解,用于定义默认值
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultValue {
String value();
}
@Data
public static class User {
private Long id;
@DefaultValue("未知用户")
private String name;
@DefaultValue("18")
private Integer age;
}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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
使用 NameFilter 修改字段名
NameFilter 可以在序列化时修改字段的名称(例如,改变驼峰命名风格为下划线命名风格)。
/**
* NameFilter: 修改字段的名称
* NameFilter 可以在序列化时修改字段的名称(例如,改变驼峰命名风格为下划线命名风格)。
*/
@Test
void testFilter2() {
// 序列化
FilterEntity2 user = new FilterEntity2();
user.setId(1L);
user.setUserName("阿腾");
user.setAge(25);
// 使用 NameFilter 将字段名从 "userName" 改为 "user_name"
String str = JSON.toJSONString(user, Filter2());
System.out.println(str);
// 输出: {"age":25,"id":1,"user_name":"阿腾"}
}
// 实体类定义
@Data
public static class FilterEntity2 {
private Long id;
private String userName;
private Integer age;
}
// 定义一个 NameFilter,修改字段名
public static NameFilter Filter2() {
return (object, name, value) -> {
if ("userName".equals(name)) {
return "user_name"; // 将 "userName" 字段改为 "user_name"
}
return name;
};
}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
AutoType
基本使用
/**
* 示例1:基本使用
*/
@Test
void testAutoType1() {
// 序列化
AutoType1 entity = new AutoType1(1L, "ateng");
String str = JSONObject.toJSONString(entity, JSONWriter.Feature.WriteClassName);
System.out.println(str);
// {"@type":"local.ateng.java.fastjson2.JSONObjectTests$AutoType1","id":1L,"name":"ateng"}
// 反序列化
/*
注意开启了AutoType,反序列化时@type字段需要在首位,否则反序列化会报错:
java.lang.ClassCastException: class com.alibaba.fastjson2.JSONObject cannot be cast to
class local.ateng.java.fastjson2.JSONObjectTests$AutoType1 (com.alibaba.fastjson2.JSONObject
and local.ateng.java.fastjson2.JSONObjectTests$AutoType1 are in unnamed module of loader 'app')
*/
String str2 = "{\"id\":1L,\"@type\":\"local.ateng.java.fastjson2.JSONObjectTests$AutoType1\",\"name\":\"ateng\"}";
AutoType1 entity2 = (AutoType1) JSON.parseObject(str2, Object.class, JSONReader.Feature.SupportAutoType);
// 开启 AutoType ,可以将有@type字段的JSON字符串直接强转类型
System.out.println(entity2.getClass());
// class local.ateng.java.fastjson2.JSONObjectTests$AutoType1
System.out.println(entity2);
// JSONObjectTests.AutoType1(id=1, name=ateng)
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class AutoType1 {
private Long id;
private String name;
}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
运行特定类(安全防护)
/**
* 示例2:运行特定类(安全防护)
*/
@Test
void testAutoType2() {
String json = "{\"@type\":\"local.ateng.java.fastjson2.JSONObjectTests$AutoType1\",\"id\":1,\"name\":\"ateng\"}";
JSONReader.AutoTypeBeforeHandler autoedTypeFilter = JSONReader.autoTypeFilter(
// 按需加上需要支持自动类型的类名前缀,范围越小越安全
"local.ateng.java."
);
/*
如果带有 @type 字段的数据反序列化时,其类型不在 autoedTypeFilter 范围内会抛出异常
java.lang.ClassCastException: class com.alibaba.fastjson2.JSONObject cannot be cast to class
local.ateng.java.fastjson2.JSONObjectTests$AutoType1 (com.alibaba.fastjson2.JSONObject and
local.ateng.java.fastjson2.JSONObjectTests$AutoType1 are in unnamed module of loader 'app')
*/
AutoType1 result = (AutoType1) JSON.parseObject(json, Object.class, autoedTypeFilter);
System.out.println(result.getClass());
// class local.ateng.java.fastjson2.JSONObjectTests$AutoType1
System.out.println(result);
// JSONObjectTests.AutoType1(id=1, name=ateng)
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
集合类型中使用 AutoType
/**
* 示例3:集合类型中使用 AutoType
* List/Map 中带有 @type 的对象也能正确反序列化。
*/
@Test
void testAutoType3() {
// 序列化
List<AutoType1> list = new ArrayList<>();
list.add(new AutoType1(1L, "ateng"));
list.add(new AutoType1(2L, "blair"));
String json = JSON.toJSONString(list, JSONWriter.Feature.WriteClassName);
System.out.println(json);
// [{"@type":"local.ateng.java.fastjson2.JSONObjectTests$AutoType1","id":1,"name":"ateng"},{"@type":"local.ateng.java.fastjson2.JSONObjectTests$AutoType1","id":2,"name":"blair"}]
// 反序列化
JSONReader.AutoTypeBeforeHandler autoedTypeFilter = JSONReader.autoTypeFilter(
// 按需加上需要支持自动类型的类名前缀,范围越小越安全
"local.ateng.java."
);
String str = "[{\"@type\":\"local.ateng.java.fastjson2.JSONObjectTests$AutoType1\",\"id\":1,\"name\":\"ateng\"},{\"@type\":\"local.ateng.java.fastjson2.JSONObjectTests$AutoType1\",\"id\":2,\"name\":\"blair\"}]";
List<AutoType1> parsed = (List<AutoType1>) JSON.parseObject(str, Object.class, autoedTypeFilter);
System.out.println(parsed.getClass());
// 这里是 JSONArray,JSONArray 实现了 java.util.List 接口,强转后也可以正常使用
// class com.alibaba.fastjson.JSONArray
System.out.println(parsed.get(0).getClass());
// class local.ateng.java.fastjson2.JSONObjectTests$AutoType1
System.out.println(parsed);
// [{"id":1,"name":"ateng"},{"id":2,"name":"blair"}]
System.out.println(parsed.get(0).getName());
// ateng
}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
其他部分
java对象转JSONObject
// java对象转JSONObject
@Test
void test05() {
UserInfoEntity user = UserInfoEntity.builder()
.name("John Doe")
.age(25)
.score(85.5)
.birthday(new Date())
.province("")
.city("Example City")
.build();
String str = JSONObject.toJSONString(user);
JSONObject jsonObject = JSONObject.parseObject(str);
System.out.println(jsonObject);
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
使用JSONArray
将字符串转换为JSONArray
// 将字符串转换为JSONArray
@Test
void test01() {
String str = "[{\"age\":87,\" \":\"1979-04-15 03:44:31.797\",\"city\":\"东莞\",\"id\":994,\"name\":\"贺熠彤\",\"province\":\"四川省\",\"score\":65.833},{\"age\":90,\"birthday\":\"1999-12-07 12:45:15.226\",\"city\":\"东莞\",\"id\":1023,\"name\":\"沈伟宸\",\"province\":\"山西省\",\"score\":57.183},{\"age\":57,\"birthday\":\"1987-05-08 04:42:58.07\",\"city\":\"东莞\",\"id\":1213,\"name\":\"戴弘文\",\"province\":\"四川省\",\"score\":53.744},{\"age\":87,\"birthday\":\"1982-12-20 23:35:45.202\",\"city\":\"东莞\",\"id\":1221,\"name\":\"钱振家\",\"province\":\"宁夏\",\"score\":67.445},{\"age\":68,\"birthday\":\"2000-03-17 11:49:20.09\",\"city\":\"东莞\",\"id\":1828,\"name\":\"顾智辉\",\"province\":\"湖南省\",\"score\":44.626},{\"age\":66,\"birthday\":\"1997-10-19 06:26:17.117\",\"city\":\"东莞\",\"id\":2035,\"name\":\"董擎宇\",\"province\":\"河南省\",\"score\":27.493},{\"age\":90,\"birthday\":\"1967-02-21 04:33:24.239\",\"city\":\"东莞\",\"id\":170,\"name\":\"谭思聪\",\"province\":\"澳门\",\"score\":27.498},{\"age\":92,\"birthday\":\"1988-09-02 06:51:55.229\",\"city\":\"东莞\",\"id\":822,\"name\":\"蒋聪健\",\"province\":\"宁夏\",\"score\":38.001},{\"age\":65,\"birthday\":\"2005-10-20 09:59:55.274\",\"city\":\"东莞\",\"id\":1816,\"name\":\"丁天磊\",\"province\":\"宁夏\",\"score\":47.401},{\"age\":58,\"birthday\":\"1990-08-08 13:11:58.805\",\"city\":\"东莞\",\"id\":1845,\"name\":\"钟志泽\",\"province\":\"黑龙江省\",\"score\":16.65},{\"age\":75,\"birthday\":\"1996-09-04 15:02:12.485\",\"city\":\"东莞\",\"id\":2283,\"name\":\"韦鹏煊\",\"province\":\"上海市\",\"score\":75.307},{\"age\":66,\"birthday\":\"1978-01-25 22:22:42.441\",\"city\":\"东莞\",\"id\":2563,\"name\":\"曹明杰\",\"province\":\"广东省\",\"score\":89.582}]";
JSONArray jsonArray = JSONArray.parse(str);
System.out.println(jsonArray);
}2
3
4
5
6
7
将字符串转换为java对象列表
// 将字符串转换为java对象列表
@Test
void test02() {
String str = "[{\"age\":87,\"birthday\":\"1979-04-15 03:44:31.797\",\"city\":\"东莞\",\"id\":994,\"name\":\"贺熠彤\",\"province\":\"四川省\",\"score\":65.833},{\"age\":90,\"birthday\":\"1999-12-07 12:45:15.226\",\"city\":\"东莞\",\"id\":1023,\"name\":\"沈伟宸\",\"province\":\"山西省\",\"score\":57.183},{\"age\":57,\"birthday\":\"1987-05-08 04:42:58.07\",\"city\":\"东莞\",\"id\":1213,\"name\":\"戴弘文\",\"province\":\"四川省\",\"score\":53.744},{\"age\":87,\"birthday\":\"1982-12-20 23:35:45.202\",\"city\":\"东莞\",\"id\":1221,\"name\":\"钱振家\",\"province\":\"宁夏\",\"score\":67.445},{\"age\":68,\"birthday\":\"2000-03-17 11:49:20.09\",\"city\":\"东莞\",\"id\":1828,\"name\":\"顾智辉\",\"province\":\"湖南省\",\"score\":44.626},{\"age\":66,\"birthday\":\"1997-10-19 06:26:17.117\",\"city\":\"东莞\",\"id\":2035,\"name\":\"董擎宇\",\"province\":\"河南省\",\"score\":27.493},{\"age\":90,\"birthday\":\"1967-02-21 04:33:24.239\",\"city\":\"东莞\",\"id\":170,\"name\":\"谭思聪\",\"province\":\"澳门\",\"score\":27.498},{\"age\":92,\"birthday\":\"1988-09-02 06:51:55.229\",\"city\":\"东莞\",\"id\":822,\"name\":\"蒋聪健\",\"province\":\"宁夏\",\"score\":38.001},{\"age\":65,\"birthday\":\"2005-10-20 09:59:55.274\",\"city\":\"东莞\",\"id\":1816,\"name\":\"丁天磊\",\"province\":\"宁夏\",\"score\":47.401},{\"age\":58,\"birthday\":\"1990-08-08 13:11:58.805\",\"city\":\"东莞\",\"id\":1845,\"name\":\"钟志泽\",\"province\":\"黑龙江省\",\"score\":16.65},{\"age\":75,\"birthday\":\"1996-09-04 15:02:12.485\",\"city\":\"东莞\",\"id\":2283,\"name\":\"韦鹏煊\",\"province\":\"上海市\",\"score\":75.307},{\"age\":66,\"birthday\":\"1978-01-25 22:22:42.441\",\"city\":\"东莞\",\"id\":2563,\"name\":\"曹明杰\",\"province\":\"广东省\",\"score\":89.582}]";
List<UserInfoEntity> userList = JSONArray.parseArray(str, UserInfoEntity.class);
System.out.println(userList);
}2
3
4
5
6
7
将java对象列表转换为字符串
// 将java对象列表转换为字符串
@Test
void test03() {
String str = JSONArray.toJSONString(list);
System.out.println(str);
}2
3
4
5
6
循环 增强 for 循环
// 循环 增强 for 循环
@Test
void test04() {
String str = "[{\"age\":87,\"birthday\":\"1979-04-15 03:44:31.797\",\"city\":\"东莞\",\"id\":994,\"name\":\"贺熠彤\",\"province\":\"四川省\",\"score\":65.833},{\"age\":90,\"birthday\":\"1999-12-07 12:45:15.226\",\"city\":\"东莞\",\"id\":1023,\"name\":\"沈伟宸\",\"province\":\"山西省\",\"score\":57.183},{\"age\":57,\"birthday\":\"1987-05-08 04:42:58.07\",\"city\":\"东莞\",\"id\":1213,\"name\":\"戴弘文\",\"province\":\"四川省\",\"score\":53.744},{\"age\":87,\"birthday\":\"1982-12-20 23:35:45.202\",\"city\":\"东莞\",\"id\":1221,\"name\":\"钱振家\",\"province\":\"宁夏\",\"score\":67.445},{\"age\":68,\"birthday\":\"2000-03-17 11:49:20.09\",\"city\":\"东莞\",\"id\":1828,\"name\":\"顾智辉\",\"province\":\"湖南省\",\"score\":44.626},{\"age\":66,\"birthday\":\"1997-10-19 06:26:17.117\",\"city\":\"东莞\",\"id\":2035,\"name\":\"董擎宇\",\"province\":\"河南省\",\"score\":27.493},{\"age\":90,\"birthday\":\"1967-02-21 04:33:24.239\",\"city\":\"东莞\",\"id\":170,\"name\":\"谭思聪\",\"province\":\"澳门\",\"score\":27.498},{\"age\":92,\"birthday\":\"1988-09-02 06:51:55.229\",\"city\":\"东莞\",\"id\":822,\"name\":\"蒋聪健\",\"province\":\"宁夏\",\"score\":38.001},{\"age\":65,\"birthday\":\"2005-10-20 09:59:55.274\",\"city\":\"东莞\",\"id\":1816,\"name\":\"丁天磊\",\"province\":\"宁夏\",\"score\":47.401},{\"age\":58,\"birthday\":\"1990-08-08 13:11:58.805\",\"city\":\"东莞\",\"id\":1845,\"name\":\"钟志泽\",\"province\":\"黑龙江省\",\"score\":16.65},{\"age\":75,\"birthday\":\"1996-09-04 15:02:12.485\",\"city\":\"东莞\",\"id\":2283,\"name\":\"韦鹏煊\",\"province\":\"上海市\",\"score\":75.307},{\"age\":66,\"birthday\":\"1978-01-25 22:22:42.441\",\"city\":\"东莞\",\"id\":2563,\"name\":\"曹明杰\",\"province\":\"广东省\",\"score\":89.582}]";
JSONArray jsonArray = JSONArray.parse(str);
for (Object obj : jsonArray) {
JSONObject jsonObject = (JSONObject) obj;
System.out.println("Name: " + jsonObject.getString("name") + ", Age: " + jsonObject.getIntValue("age"));
}
}2
3
4
5
6
7
8
9
10
循环 Java 8 的 Stream API
// 循环 Java 8 的 Stream API
@Test
void test05() {
String str = "[{\"age\":87,\"birthday\":\"1979-04-15 03:44:31.797\",\"city\":\"东莞\",\"id\":994,\"name\":\"贺熠彤\",\"province\":\"四川省\",\"score\":65.833},{\"age\":90,\"birthday\":\"1999-12-07 12:45:15.226\",\"city\":\"东莞\",\"id\":1023,\"name\":\"沈伟宸\",\"province\":\"山西省\",\"score\":57.183},{\"age\":57,\"birthday\":\"1987-05-08 04:42:58.07\",\"city\":\"东莞\",\"id\":1213,\"name\":\"戴弘文\",\"province\":\"四川省\",\"score\":53.744},{\"age\":87,\"birthday\":\"1982-12-20 23:35:45.202\",\"city\":\"东莞\",\"id\":1221,\"name\":\"钱振家\",\"province\":\"宁夏\",\"score\":67.445},{\"age\":68,\"birthday\":\"2000-03-17 11:49:20.09\",\"city\":\"东莞\",\"id\":1828,\"name\":\"顾智辉\",\"province\":\"湖南省\",\"score\":44.626},{\"age\":66,\"birthday\":\"1997-10-19 06:26:17.117\",\"city\":\"东莞\",\"id\":2035,\"name\":\"董擎宇\",\"province\":\"河南省\",\"score\":27.493},{\"age\":90,\"birthday\":\"1967-02-21 04:33:24.239\",\"city\":\"东莞\",\"id\":170,\"name\":\"谭思聪\",\"province\":\"澳门\",\"score\":27.498},{\"age\":92,\"birthday\":\"1988-09-02 06:51:55.229\",\"city\":\"东莞\",\"id\":822,\"name\":\"蒋聪健\",\"province\":\"宁夏\",\"score\":38.001},{\"age\":65,\"birthday\":\"2005-10-20 09:59:55.274\",\"city\":\"东莞\",\"id\":1816,\"name\":\"丁天磊\",\"province\":\"宁夏\",\"score\":47.401},{\"age\":58,\"birthday\":\"1990-08-08 13:11:58.805\",\"city\":\"东莞\",\"id\":1845,\"name\":\"钟志泽\",\"province\":\"黑龙江省\",\"score\":16.65},{\"age\":75,\"birthday\":\"1996-09-04 15:02:12.485\",\"city\":\"东莞\",\"id\":2283,\"name\":\"韦鹏煊\",\"province\":\"上海市\",\"score\":75.307},{\"age\":66,\"birthday\":\"1978-01-25 22:22:42.441\",\"city\":\"东莞\",\"id\":2563,\"name\":\"曹明杰\",\"province\":\"广东省\",\"score\":89.582}]";
JSONArray jsonArray = JSONArray.parse(str);
IntStream.range(0, jsonArray.size())
.mapToObj(jsonArray::getJSONObject)
.forEach(jsonObject ->
System.out.println("Name: " + jsonObject.getString("name") + ", Age: " + jsonObject.getIntValue("age"))
);
}2
3
4
5
6
7
8
9
10
11
使用JSONPath
读取集合多个元素的某个属性
// 读取集合多个元素的某个属性
@Test
void test01() {
JSONArray stringList = (JSONArray) JSONPath.eval(list, "$[*].name");
System.out.println(stringList);
// ["段哲瀚","汪昊然","万修杰", ... ]
}2
3
4
5
6
7
读取集合多个元素的某个属性
// 读取集合多个元素的某个属性
@Test
void test01_2() {
String json = "{\"students\":[{\"name\":\"John\"},{\"name\":\"Alice\"}]}";
JSONArray names = (JSONArray) JSONPath.eval(json, "$.students[*].name");
System.out.println(names);
// ["John","Alice"]
}
@Test
void test01_2_1() {
String json = "{\"张三\":[{\"name\":\"John\"},{\"name\":\"Alice\"}]}";
JSONArray names = (JSONArray) JSONPath.eval(json, "$.张三[*].name");
System.out.println(names);
// ["John","Alice"]
}
@Test
void test01_3() {
// 递归查询
String json = "{\"students\":[{\"name\":\"John\"},{\"name\":\"Alice\"}]}";
JSONArray names = (JSONArray) JSONPath.eval(json, "$.students..name");
System.out.println(names);
// ["John","Alice"]
}
@Test
void test01_04() {
String jsonString = "{\"students\":[{\"name\":\"John\",\"age\":25,\"gender\":\"Male\"},{\"name\":\"Alice\",\"age\":30,\"gender\":\"Female\"},{\"name\":\"Bob\",\"age\":28,\"gender\":\"Male\"}]}";
// 使用 JSONPath.eval 获取多条件筛选的结果
JSONArray result = (JSONArray) JSONPath.eval(jsonString, "$.students[?(@.age >= 25 && @.age <= 30 && @.gender == 'Male')].name");
System.out.println(result);
// ["John","Bob"]
}
@Test
void test01_05() {
String jsonString = "{\"students\":[{\"name\":\"John\",\"age\":25,\"gender\":\"Male\"},{\"name\":\"Alice\",\"age\":30,\"gender\":\"Female\"},{\"name\":\"Bob\",\"age\":28,\"gender\":\"Male\"}]}";
// 使用 JSONPath.eval 获取1条件筛选的结果
JSONObject result = (JSONObject) JSONPath.eval(jsonString, "$.students[?(@.age >= 25 && @.age <= 30 && @.gender == 'Male')][0]");
System.out.println(result);
// {"name":"John","age":25,"gender":"Male"}
}
@Test
void test01_06() {
String jsonString = "[{\"name\":\"高新区管委会\",\"congestionIndex\":1.2,\"realSpeed\":\"60.918\",\"yoy\":0.0,\"mom\":0.0,\"status\":\"畅通\"},{\"name\":\"保税区-B区\",\"congestionIndex\":1.2,\"realSpeed\":\"39.3355\",\"yoy\":-0.1,\"mom\":0.0,\"status\":\"畅通\"},{\"name\":\"康居西城\",\"congestionIndex\":1.3,\"realSpeed\":\"29.8503\",\"yoy\":0.0,\"mom\":0.0,\"status\":\"畅通\"},{\"name\":\"白市驿\",\"congestionIndex\":1.1,\"realSpeed\":\"45.5646\",\"yoy\":-0.1,\"mom\":0.0,\"status\":\"畅通\"},{\"name\":\"金凤\",\"congestionIndex\":1.2,\"realSpeed\":\"44.2227\",\"yoy\":0.0,\"mom\":0.0,\"status\":\"畅通\"},{\"name\":\"保税区-A区\",\"congestionIndex\":1.4,\"realSpeed\":\"30.8192\",\"yoy\":0.0,\"mom\":0.0,\"status\":\"畅通\"},{\"name\":\"高新天街\",\"congestionIndex\":1.4,\"realSpeed\":\"19.2326\",\"yoy\":0.1,\"mom\":0.0,\"status\":\"畅通\"},{\"name\":\"熙街\",\"congestionIndex\":1.6,\"realSpeed\":\"23.2695\",\"yoy\":0.0,\"mom\":0.0,\"status\":\"缓行\"}]";
// 使用 JSONPath.eval 获取多条件筛选的结果
JSONArray congestionIndexList1 = (JSONArray) JSONPath.eval(jsonString, "$[?(@.name == '高新区管委会')].congestionIndex");
System.out.println(congestionIndexList1);
// [1.2]
System.out.println(congestionIndexList1.getFirst().getClass());
// class java.math.BigDecimal
}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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
返回集合中多个元素
// 返回集合中多个元素
@Test
void test02() {
JSONArray objectList = (JSONArray) JSONPath.eval(list, "[1,5]"); // 返回下标为1和5的元素
List<UserInfoEntity> userList = objectList.toJavaList(UserInfoEntity.class);
System.out.println(userList);
// [UserInfoEntity(id=2, name=宋鹏, age=86, score=48.951, num=null, bi ...
}2
3
4
5
6
7
8
按范围返回集合的子集
// 按范围返回集合的子集
@Test
void test03() {
JSONArray objectList = (JSONArray) JSONPath.eval(list, "[1:5]"); // 返回下标从1到5的元素
List<UserInfoEntity> userList = objectList.toJavaList(UserInfoEntity.class);
System.out.println(userList);
// [UserInfoEntity(id=2, name=林浩, age=95, score=69.378, num=null, ...
}2
3
4
5
6
7
8
通过条件过滤,返回集合的子集
// 通过条件过滤,返回集合的子集
@Test
void test04() {
JSONArray objectList = (JSONArray) JSONPath.eval(list,"$[?(@.id in (88,99))]"); // 返回下标从1到5的元素
List<UserInfoEntity> userList = objectList.toJavaList(UserInfoEntity.class);
System.out.println(userList);
// [UserInfoEntity(id=88, name=方越彬, age=63, score=63.994, num=null,
}
@Test
void test04_2() {
JSONArray objectList = (JSONArray) JSONPath.eval(list, "$[?(@.age = 88)]"); // 返回列表对象的age=88的数据
List<UserInfoEntity> userList = objectList.toJavaList(UserInfoEntity.class);
System.out.println(userList);
// [UserInfoEntity(id=28, name=邵浩然, age=88, score=24.06, num=null, birthday=Tue Jun ...
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
多条件筛选,返回集合的子集
// 多条件筛选,返回集合的子集
@Test
void test04_3() {
JSONArray objectList = (JSONArray) JSONPath.eval(list, "$[?(@.age == 88 || @.age == 95)]"); // 返回列表对象的age=88或者=95的数据
List<UserInfoEntity> userList = objectList.toJavaList(UserInfoEntity.class);
System.out.println(userList);
// [UserInfoEntity(id=11, name=朱烨磊, age=88, score=66.78, ...
}
@Test
void test04_4() {
JSONArray objectList = (JSONArray) JSONPath.eval(list, "$[?(@.age > 50 && @.age < 95 && @.city='东莞')]");
List<UserInfoEntity> userList = objectList.toJavaList(UserInfoEntity.class);
System.out.println(userList);
// [UserInfoEntity(id=64, name=崔志泽, age=70, score=64.082, num=null ...
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
通过条件过滤,获取数组长度
// 通过条件过滤,获取数组长度
@Test
void test04_5() {
Integer length = (Integer) JSONPath.eval(list, "$[?(@.age = 88)].length()"); // 返回列表对象的age=88的数据的长度
System.out.println(length);
}2
3
4
5
6
全局配置
在 Springboot 中配置了Fastjson2 的全局配置,那么在使用 JSONObject、JSONArray、JSON 这些时就会生效
package local.ateng.java.fastjson2.config;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
/**
* 全局配置fastjson2
*
* @author 孔余
* @since 2025-11-06
*/
@Configuration
public class FastJsonConfig {
@EventListener
public void run(ApplicationReadyEvent event) {
JSON.configReaderDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
JSON.configWriterDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
JSON.config(
// 序列化输出空值字段
JSONWriter.Feature.WriteNulls,
// 将空置输出为缺省值,Number类型的null都输出为0,String类型的null输出为"",数组和Collection类型的输出为[]
JSONWriter.Feature.NullAsDefaultValue,
// 打开循环引用检测
JSONWriter.Feature.ReferenceDetection,
// 保证 BigDecimal 精度
JSONWriter.Feature.WriteBigDecimalAsPlain,
// 把 Long 类型转为字符串,避免前端精度丢失
JSONWriter.Feature.WriteLongAsString,
// 浏览器安全输出(防止前端注入)
JSONWriter.Feature.BrowserCompatible,
JSONWriter.Feature.BrowserSecure
);
JSON.config(
// 默认下是camel case精确匹配,打开这个后,能够智能识别camel/upper/pascal/snake/Kebab五中case
JSONReader.Feature.SupportSmartMatch,
// 允许字段名不带引号
JSONReader.Feature.AllowUnQuotedFieldNames,
// 忽略无法序列化的字段
JSONReader.Feature.IgnoreNoneSerializable,
// 防止类型不匹配时报错(更安全)
JSONReader.Feature.IgnoreAutoTypeNotMatch
);
}
}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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51