A Guide to FastJson – FastJson指南

最后修改: 2016年 7月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

FastJson is a lightweight Java library used to effectively convert JSON strings to Java objects and vice versa.

FastJson是一个轻量级的Java库,用于有效地将JSON字符串转换成Java对象,反之亦然。

In this article we’re going to dive into several concrete and practical applications of the FastJson library.

在这篇文章中,我们将深入探讨FastJson库的几个具体和实际的应用。

2. Maven Configuration

2.Maven配置

In order to start working with FastJson, we first need to add that to our pom.xml:

为了开始使用FastJson,我们首先需要将其添加到我们的pom.xml

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.13</version>
</dependency>

And as a quick note – here’s the most updated version of the library on Maven Central.

顺便提一下–这里是Maven中心的最新版本,该库已更新。

3. Convert Java Objects to JSON Format

3.将Java对象转换为JSON格式

Let’s define the following Person Java bean:

让我们定义以下Person Java Bean。

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
}

We can use JSON.toJSONString() to convert a Java object to a JSON String:

我们可以使用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);
}

And here’s the result:

结果是这样的。

[  
    {  
        "AGE":15,
        "DATE OF BIRTH":1468962431394,
        "FULL NAME":"John Doe"
    },
    {  
        "AGE":20,
        "DATE OF BIRTH":1468962431394,
        "FULL NAME":"Janette Doe"
    }
]

We can also go further and start customizing the output and control things like ordering, date formatting, or serialization flags.

我们还可以更进一步,开始定制输出,并控制诸如排序、日期格式化序列化标志等事项。

For example – let’s update the bean and add a couple more fields:

例如–让我们更新Bean并增加几个字段。

@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;

Here’s a list of the most basic parameters that we can use alongside the @JSONField annotation, in order to customize the conversion process:

下面是一个最基本的参数列表,我们可以和@JSONField注解一起使用,以便定制转换过程。

  • The parameter format is used to properly format the date attribute
  • By default, the FastJson library serialize the Java bean entirely, but we can make use of the parameter serialize to ignore serialization for specific fields
  • The parameter ordinal is used to specify the fields order

And here’s the new output:

这里是新的输出。

[
    {
        "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 also supports a very interesting BeanToArray serialization feature:

FastJson还支持一个非常有趣的BeanToArray序列化功能。

String jsonOutput= JSON.toJSONString(listOfPersons, SerializerFeature.BeanToArray);

Here’s what the output will look like in this case:

下面是这种情况下的输出结果。

[
    [
        15,
        1469003271063,
        "John Doe"
    ],
    [
        20,
        1469003271063,
        "Janette Doe"
    ]
]

4. Create JSON Objects

4.创建JSON对象

Like other JSON libraries, creating a JSON object from scratch is pretty straightforward, it’s only a matter of combining JSONObject and JSONArray objects:

其他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();
}

And here’s what the output will look like here:

而这里的输出将是这样的。

[
   {
      "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. Parse JSON Strings into Java Objects

5.将JSON字符串解析为Java对象

Now that we know how to create a JSON object from scratch, and how to convert Java objects to their JSON representations, let’s put the focus on how to parse a JSON representation:

现在我们知道了如何从头开始创建一个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());
}

We can use JSON.parseObject() to get a Java object from a JSON String.

我们可以使用JSON.parseObject()来从JSON字符串中获得一个Java对象。

Note that you have to define a no-args or default constructor if you have already declared your own parametrized one, otherwise a com.alibaba.fastjson.JSONException will be thrown.

注意,如果你已经声明了你自己的参数化构造函数,你必须定义一个no-args或默认构造函数,否则将抛出com.alibaba.fastjson.JSONException

Here’s the output of this simple test:

下面是这个简单测试的输出。

Person [age=20, fullName=John Doe, dateOfBirth=Wed Jul 20 08:51:12 WEST 2016]

By using the option deserialize inside the @JSONField annotation, we can ignore deserialization for a specific field, in this case, the default value will apply automatically to the ignored field:

通过在@JSONField注解中使用选项deserialize,我们可以忽略某个特定字段的反序列化,在这种情况下,默认值将自动适用于被忽略的字段。

@JSONField(name = "DATE OF BIRTH", deserialize=false)
private Date dateOfBirth;

And here’s the newly created object:

这是新创建的对象。

Person [age=20, fullName=John Doe, dateOfBirth=null]

6. Configure JSON Conversion Using ContextValueFilter

6.使用ContextValueFilter配置JSON转换

In some scenarios, we may need to have more control over the conversion process from Java objects to JSON format.

在某些情况下,我们可能需要对从Java对象到JSON格式的转换过程有更多的控制

In this case we can make use of the ContextValueFilter object to apply additional filtering and custom processing to the conversion flow:

在这种情况下,我们可以利用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);
}

In this example, we hid the DATE OF BIRTH field, by forcing a constant value, we also ignored all fields that are not John or Doe:

在这个例子中,我们隐藏了DATE OF BIRTH字段,通过强制使用一个常量值,我们还忽略了所有不是JohnDoe:
的字段。

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

As you can see, this is a pretty basic example, but you can of course use the same concepts for more complex scenarios as well – combining these powerful and lightweight set of tools offered by FastJson in a real world project.

正如你所看到的,这是一个相当基本的例子,但你当然也可以将同样的概念用于更复杂的场景–将FastJson提供的这些强大而轻巧的工具集结合到实际项目中。

7. Using NameFilter and SerializeConfig

7、使用NameFilterSerializeConfig

FastJson offers a set of tools to customize you JSON operations when dealing with arbitrary object – objects we don’t have the source code of.

FastJson提供了一套工具,在处理任意对象–我们没有源代码的对象–时为你定制JSON操作。

Let’s imagine we have a compiled version of the Person Java bean, initially declared in this article, and we need to make some enhancement on fields naming and basic formatting:

让我们设想一下,我们有一个Person Java Bean的编译版本,最初是在本文中声明的,我们需要对字段命名和基本格式化进行一些改进。

@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");
}

We’ve declared the formatName filter using the NameFilter anonymous class to process fields names. The newly created filter is associated to the Person class, and then added to a global instance – which is basically a static attribute in the SerializeConfig class.

我们使用NameFilter匿名类声明了formatName过滤器来处理字段名。新创建的过滤器被关联到Person类,然后被添加到一个全局实例中–这基本上是SerializeConfig类的一个静态属性。

Now we can comfortably convert our object to JSON format as shown earlier in this article.

现在我们可以轻松地将我们的对象转换成JSON格式,如本文前面所示。

Note that we’ve used toJSONStringWithDateFormat() instead of toJSONString() to quickly apply the same formatting rule on date fields.

注意,我们使用了toJSONStringWithDateFormat()而不是toJSONString()来快速地在日期字段上应用相同的格式化规则。

And here’s the output:

下面是输出结果。

[  
    {  
        "full_name":"John Doe",
        "date_of_birth":"2016-07-21"
    },
    {  
        "full_name":"Janette Doe",
        "date_of_birth":"2016-07-21"
    }
]

As you can see – the fields names got changed, and the date value did got properly formatted.

正如你所看到的–字段名被改变了,而日期值确实被正确地格式化了。

Combining SerializeFilter with ContextValueFilter can give full control over the conversion process for arbitrary and complex Java objects.

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

8. Conclusion

8.结论

In this article we showed how to use FastJson to convert Java beans to JSON strings and how to go the other way around. We also showed how to use some of the core features of FastJson in order to customize the JSON output.

在这篇文章中,我们展示了如何使用FastJson将Java Bean转换为JSON字符串,以及如何反其道而行之。我们还展示了如何使用FastJson的一些核心功能,以便定制JSON输出。

As you can see, the library offers a relatively simple to use but still very powerful API. JSON.toJSONString and JSON.parseObject are all you need to use in order to meet most of your needs – if not all.

正如你所看到的,该库提供了一个相对简单的使用,但仍然非常强大的API。 JSON.toJSONStringJSON.parseObject是你需要使用的全部,以满足你的大多数需求 – 如果不是全部。

You can checkout the examples provided in this article in the linked GitHub project.

你可以在链接的GitHub项目中查看本文提供的例子。