Fastjson Introduction

Fastjson is a Java library that can convert Java objects into JSON format, and of course it can also convert JSON strings into Java objects.

Fastjson can operate on any Java object, even pre-existing objects without source code.

Fastjson source code address:https://github.com/alibaba/fastjson

Fastjson Chinese Wiki:https://github.com/alibaba/fastjson/wiki/Quick-Start-CN


Fastjson Features

  • Provides parsing tools for both server-side and Android clients, with good performance.
  • Provides toJSONString() and parseObject() methods to convert between Java objects and JSON. Calling the toJSONString method converts an object into a JSON string, while the parseObject method does the reverse, converting a JSON string into an object.
  • Allows conversion of pre-existing immutable objects (only class, no source code).
  • Extensive support for Java generics.
  • Allows custom representation of objects and custom serialization classes.
  • Supports arbitrarily complex objects (with deep inheritance hierarchies and extensive use of generic types).


Download and Usage

You can download it directly from the Maven Central Repository:

https://repo1.maven.org/maven2/com/alibaba/fastjson/

Or configure the Maven dependency:

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

wherex.x.xis the version number. Use a specific version as needed, and the latest version is recommended.


Convert Java Objects to JSON Format

Define the following Person JavaBean:

Example

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
}

You can use JSON.toJSONString() to convert a Java object into a JSON object:

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

The output is:

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

We can also customize the output and control field ordering, date display format, serialization flags, etc.

Next, let's update the bean and add a few fields:

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

In the above code, we listed the basic parameter categories and used the @JSONField annotation to implement custom conversion:

  • format The parameter is used to formatdatethe property.
  • By default, the FastJson library can serialize Java bean entities, but we can useserialize to specify fields not to be serialized.
  • Useordinal the parameter to specify the order of fields.

Thus, the output above becomes:

[
    {
        "FIRST NAME":"Doe",
        "LAST NAME":"Jhon",
        "DATE OF BIRTH":"19/07/2016"
    },
    {
        "FIRST NAME":"Doe",
        "LAST NAME":"Janette",
        "DATE OF BIRTH":"19/07/2016"
    }
]

@JSONField

The target objects of @JSONField:

  • 1. Field
  • 2. Setter and Getter methods

Note:When FastJson performs operations, it does so based on getter and setter methods, not based on fields.

Note:If a property is private, it must have a set method; otherwise, deserialization is impossible.

span style="color: #000000; font-weight: bold;">package com.alibaba.fastjson.annotation;

public @interface JSONField {
    // Configure the order of serialization and deserialization; supported only after version 1.1.42
    int ordinal() default 0;

     // Specify the name of the field
    String name() default "";

    // Specify the format of the field; useful for date formats
    String format() default "";

    // Whether to serialize
    boolean serialize() default true;

    // Whether to deserialize
    boolean deserialize() default true;
}

2. JSONField Configuration Methods

FieldInfo can be configured on getter/setter methods or fields. For example:

2.1 Configured on getter/setter

public class A {
      private int id;
 
      @JSONField(name="ID")
      public int getId() {return id;}
      @JSONField(name="ID")
      public void setId(int value) {this.id = id;}
}

2.2 Configured on field

 public class A {
      @JSONField(name="ID")
      private int id;
 
      public int getId() {return id;}
      public void setId(int value) {this.id = id;}
 }

3. Using format to Configure Date Formatting

span style="color: #000000; font-weight: bold;">public class A {
      // Configure date serialization and deserialization to use the yyyyMMdd date format
      @JSONField(format="yyyyMMdd")
      public Date date;
 }

4. Using serialize/deserialize to Specify Non-Serialization of Fields

span style="color: #000000; font-weight: bold;">public class A {
      @JSONField(serialize=false)
      public Date date;
 }

 public class A {
      @JSONField(deserialize=false)
      public Date date;
 }

5. Using ordinal to Specify Field Order

By default, fastjson serializes a Java bean based on the alphabetical order of fieldName. You can specify the field order with ordinal. This feature requires version 1.1.42 or higher.

span style="color: #000000; font-weight: bold;">public static class VO {
    @JSONField(ordinal = 3)
    private int f0;

    @JSONField(ordinal = 2)
    private int f1;

    @JSONField(ordinal = 1)
    private int f2;
}


FastJson also supports BeanToArray serialization:

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

The output is:

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

Creating JSON Objects

Creating JSON objects is very simple. Just use JSONObject (the JSON object provided by fastJson) and JSONArray (the JSON array object provided by fastJson).

We can treat JSONObject as a Map<String,Object>, except that JSONObject provides richer and more convenient methods for manipulating object properties. Let's take a look at the source code.

Similarly, we can treat JSONArray as a List<Object>, and can regard JSONArray as a collection of JSONObject objects.

In addition, since JSONObject and JSONArray inherit from JSON, both can also be used directly to convert between JSON format strings and JSON objects or JavaBeans. However, to avoid confusion, we still use JSON.

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

The output is:

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

Converting JSON Strings to Java Objects

Now that we have learned how to create JSON objects and convert Java objects to JSON strings, we need to understand how to parse 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 serialization to false
    assertEquals(newPerson.getFullName(), listOfPersons.get(0).getFullName());
}

We can use JSON.parseObject() to convert JSON strings into Java objects.

Note: when deserializing into an object, a default no-argument constructor must be present; otherwise, an exception will be thrown:

com.alibaba.fastjson.JSONException: default constructor not found.

The following is a simple example test:

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

@JSONField deserializeOptional parameters can specify fields not to be deserialized.

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

The output is:

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

Using ContextValueFilter to Configure JSON Conversion

In some scenarios, when filtering values, you need to obtain information about the owning JavaBean, including its type, fields, methods, etc. In fastjson-1.2.9, ContextValueFilter is provided, similar to the ValueFilter provided in previous versions, but with an additional BeanContext parameter available.

@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 the above example, we hid the DATE OF BIRTH field and filtered out fields whose names do not contain John:

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

Using NameFilter and SerializeConfig

NameFilter: Modify the Key during serialization.

SerializeConfig: Internally it is a map container whose main function is to configure and record the serialization class corresponding to each Java type.

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

In the example, we declared the formatName filter using the NameFilter anonymous class to handle field names. The newly created filter is associated with the Person class, then added to the global instance, which is a static property in the SerializeConfig class.

Now we can easily convert objects to JSON format.

Note that we use toJSONStringWithDateFormat() instead of toJSONString(), which can format dates more quickly.

Output result:

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