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 对象相当直接,只需组合 JSONObjectJSONArray 对象即可:

@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 字段,强制设置了一个常数值,并忽略了所有不是 JohnDoe 的字段:

[
    {
        "FULL NAME":"JOHN DOE",
        "DATE OF BIRTH":"NOT TO DISCLOSE"
    }
]

如你所见,这是一个基本示例,但在更复杂的情况下,你可以使用相同的概念——在实际项目中结合 FastJson 提供的强大而轻量级工具集。

7. 使用 NameFilterSerializeConfig

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"
    }
]

可以看到,字段名称已更改,日期值已正确格式化。

结合 SerializeFilterContextValueFilter 可以全面控制任意复杂 Java 对象的转换过程。

8. 结论

本文展示了如何使用 FastJson 将 Java 对象转换为 JSON 字符串以及反过来操作。我们还演示了如何使用 FastJson 的核心功能来定制 JSON 输出。

如你所见,库提供了相对简单易用但功能强大的 API。JSON.toJSONStringJSON.parseObject 即可满足大多数需求——如果还不够,你可以在 提供的 GitHub 项目 中查看本文中的示例。


» 下一篇: XMLUnit 2.x简介