Course – LS (cat=JSON/Jackson)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

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

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

2. Maven Configuration

In order to start working with FastJson, we first need to add that to our 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.

3. Convert Java Objects to JSON Format

Let’s define the following 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:

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:

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

  • 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:

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

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

@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

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:

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

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.

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(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

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

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

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

[
    {
        "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.

7. Using NameFilter and SerializeConfig

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.

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:

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

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

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

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.

8. Conclusion

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.

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.

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

Course – LS (cat=JSON/Jackson)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.