1. 概述
FastJson 是一个轻量级的 Java 库,用于高效地将 JSON 字符串转换为 Java 对象,反之亦然。
本文将深入探讨 FastJson 库的一些具体实用应用。
2. Maven 配置
要开始使用 FastJson,首先需要将其添加到 pom.xml
文件中:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.13</version>
</dependency>
顺便提一下,这是 Maven 中央仓库中最新的版本。
3. 将 Java 对象转换为 JSON 格式
让我们定义一个名为 Person 的 Java 实体类:
public class Person {
@JSONField(name = "AGE")
private int age;
@JSONField(name = "FULL NAME")
private String fullName;
@JSONField(name = "DATE OF BIRTH")
private Date dateOfBirth;
public Person(int age, String fullName, Date dateOfBirth) {
super();
this.age = age;
this.fullName= fullName;
this.dateOfBirth = dateOfBirth;
}
// standard getters & setters
}
我们可以使用 JSON.toJSONString()
将 Java 对象转换为 JSON 字符串:
private List<Person> listOfPersons = new ArrayList<Person>();
@Before
public void setUp() {
listOfPersons.add(new Person(15, "John Doe", new Date()));
listOfPersons.add(new Person(20, "Janette Doe", new Date()));
}
@Test
public void whenJavaList_thanConvertToJsonCorrect() {
String jsonOutput= JSON.toJSONString(listOfPersons);
}
转换后的结果如下:
[
{
"AGE":15,
"DATE OF BIRTH":1468962431394,
"FULL NAME":"John Doe"
},
{
"AGE":20,
"DATE OF BIRTH":1468962431394,
"FULL NAME":"Janette Doe"
}
]
我们还可以进一步定制输出,控制诸如 排序、日期 格式化 或 序列化 标志等。
例如,更新实体类并添加更多字段:
@JSONField(name="AGE", serialize=false)
private int age;
@JSONField(name="LAST NAME", ordinal = 2)
private String lastName;
@JSONField(name="FIRST NAME", ordinal = 1)
private String firstName;
@JSONField(name="DATE OF BIRTH", format="dd/MM/yyyy", ordinal = 3)
private Date dateOfBirth;
以下是与 @JSONField
注解一起使用的最基础参数列表,以自定义转换过程:
- 参数
format
用于正确格式化 date 属性。 - 默认情况下,FastJson 库会完全序列化 Java 对象,但我们可以使用参数
serialize
忽略特定字段的序列化。 - 参数
ordinal
用于指定字段的顺序。
新的输出如下:
[
{
"FIRST NAME":"Doe",
"LAST NAME":"Jhon",
"DATE OF BIRTH":"19/07/2016"
},
{
"FIRST NAME":"Doe",
"LAST NAME":"Janette",
"DATE OF BIRTH":"19/07/2016"
}
]
FastJson 还支持非常有趣的 BeanToArray 序列化功能:
String jsonOutput= JSON.toJSONString(listOfPersons, SerializerFeature.BeanToArray);
在这种情况下,输出将如下所示:
[
[
15,
1469003271063,
"John Doe"
],
[
20,
1469003271063,
"Janette Doe"
]
]
4. 创建 JSON 对象
像其他 JSON 库一样,从头创建 JSON 对象相当直接,只需组合 JSONObject
和 JSONArray
对象即可:
@Test
public void whenGenerateJson_thanGenerationCorrect() throws ParseException {
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < 2; i++) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("AGE", 10);
jsonObject.put("FULL NAME", "Doe " + i);
jsonObject.put("DATE OF BIRTH", "2016/12/12 12:12:12");
jsonArray.add(jsonObject);
}
String jsonOutput = jsonArray.toJSONString();
}
输出如下:
[
{
"AGE":"10",
"DATE OF BIRTH":"2016/12/12 12:12:12",
"FULL NAME":"Doe 0"
},
{
"AGE":"10",
"DATE OF BIRTH":"2016/12/12 12:12:12",
"FULL NAME":"Doe 1"
}
]
5. 将 JSON 字符串解析为 Java 对象
现在我们知道如何从头创建 JSON 对象,并知道如何将 Java 对象转换为其 JSON 表达形式,接下来我们将关注如何解析 JSON 表达形式:
@Test
public void whenJson_thanConvertToObjectCorrect() {
Person person = new Person(20, "John", "Doe", new Date());
String jsonObject = JSON.toJSONString(person);
Person newPerson = JSON.parseObject(jsonObject, Person.class);
assertEquals(newPerson.getAge(), 0); // if we set serialize to false
assertEquals(newPerson.getFullName(), listOfPersons.get(0).getFullName());
}
我们可以使用 JSON.parseObject()
从 JSON 字符串获取 Java 对象。
请注意,如果你已经声明了带有参数的构造函数,那么必须提供一个无参或默认构造函数,否则会抛出 com.alibaba.fastjson.JSONException
异常。
这个简单测试的输出如下:
Person [age=20, fullName=John Doe, dateOfBirth=Wed Jul 20 08:51:12 WEST 2016]
通过在 @JSONField
注解中使用 deserialize
选项,我们可以忽略特定字段的反序列化,此时,忽略的字段将自动应用默认值:
@JSONField(name = "DATE OF BIRTH", deserialize=false)
private Date dateOfBirth;
创建的新对象如下:
Person [age=20, fullName=John Doe, dateOfBirth=null]
6. 使用 ContextValueFilter
配置 JSON 转换
在某些场景下,我们可能需要对从 Java 对象到 JSON 格式的转换过程有更多控制。
在这种情况下,我们可以使用 ContextValueFilter
对象对转换流程应用额外过滤和自定义处理:
@Test
public void givenContextFilter_whenJavaObject_thanJsonCorrect() {
ContextValueFilter valueFilter = new ContextValueFilter () {
public Object process(
BeanContext context, Object object, String name, Object value) {
if (name.equals("DATE OF BIRTH")) {
return "NOT TO DISCLOSE";
}
if (value.equals("John")) {
return ((String) value).toUpperCase();
} else {
return null;
}
}
};
String jsonOutput = JSON.toJSONString(listOfPersons, valueFilter);
}
在这个例子中,我们隐藏了 DATE OF BIRTH 字段,强制设置了一个常数值,并忽略了所有不是 John 或 Doe 的字段:
[
{
"FULL NAME":"JOHN DOE",
"DATE OF BIRTH":"NOT TO DISCLOSE"
}
]
如你所见,这是一个基本示例,但在更复杂的情况下,你可以使用相同的概念——在实际项目中结合 FastJson 提供的强大而轻量级工具集。
7. 使用 NameFilter
和 SerializeConfig
FastJson 提供了一套工具,用于处理任意对象(我们没有源代码)时的 JSON 操作进行自定义。
假设我们有一个编译过的 Person Java 实体类,最初如本文章所述声明,我们需要对字段名称和基本格式进行一些增强:
@Test
public void givenSerializeConfig_whenJavaObject_thanJsonCorrect() {
NameFilter formatName = new NameFilter() {
public String process(Object object, String name, Object value) {
return name.toLowerCase().replace(" ", "_");
}
};
SerializeConfig.getGlobalInstance().addFilter(Person.class, formatName);
String jsonOutput =
JSON.toJSONStringWithDateFormat(listOfPersons, "yyyy-MM-dd");
}
我们使用 NameFilter
匿名类声明了 formatName
过滤器,该过滤器用于处理字段名称。新创建的过滤器关联到 Person
类,并添加到全局实例中——这基本上是 SerializeConfig
类的一个静态属性。
现在我们可以像前面文章中展示的那样轻松地将对象转换为 JSON 格式。
请注意,我们使用 toJSONStringWithDateFormat()
而不是 toJSONString()
,以便快速应用相同的日期字段格式规则。
输出如下:
[
{
"full_name":"John Doe",
"date_of_birth":"2016-07-21"
},
{
"full_name":"Janette Doe",
"date_of_birth":"2016-07-21"
}
]
可以看到,字段名称已更改,日期值已正确格式化。
结合 SerializeFilter
和 ContextValueFilter
可以全面控制任意复杂 Java 对象的转换过程。
8. 结论
本文展示了如何使用 FastJson 将 Java 对象转换为 JSON 字符串以及反过来操作。我们还演示了如何使用 FastJson 的核心功能来定制 JSON 输出。
如你所见,库提供了相对简单易用但功能强大的 API。JSON.toJSONString
和 JSON.parseObject
即可满足大多数需求——如果还不够,你可以在 提供的 GitHub 项目 中查看本文中的示例。