Java – JSON serialization

JavaIn this article I’d like to present:

  • Example of Object serialization into JSON string
  • Deserialization of JSON string to the Object


I created a class called Person where I’d like to keep some data about a person. Some of the fields are auto-generated and I don’t want them in the exported JSON string. Therefore I have to mark the fields required to be in output JSON using i.e. my own annotations:

public class Person extends JSONModel {
//This field is NOT to be put in output JSON string  
  public int id;

//This is an own annotation declared in parent class
  @JSONField
  public String name;

  @JSONField
  public int age;
}

Here comes the important part – definition of the parent abstract class JSONModel.

  • It implements interface of org.json.JSONString and its method toJSONString()
  • It defines protected annotation JSONField which is used in child classes to mark fields required in JSON output string.
  • It implements method fromJSONString(String tree) for parsing and mapping given JSON string to the class instance.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONString;

public abstract class JSONModel implements JSONString{
  @Target(ElementType.FIELD)
  @Retention(RetentionPolicy.RUNTIME)
  protected @interface JSONField { }

  @Override
  public String toJSONString() {
    JSONObject model = new JSONObject();
//  Get all attributes of current class
    Field[] fields = this.getClass().getDeclaredFields();

    for (Field field : fields) {
//    Process only fields marked with the required annotation
      if (field.isAnnotationPresent(JSONField.class)) {
        try {
//        Add the attribute to JSON output
          model.put(field.getName(), field.get(this));
        } catch (IllegalArgumentException | IllegalAccessException | JSONException e) {
          e.printStackTrace();
        }
      }
    }

    return model.toString();
  }

  private void setProperty(Object clazz, String fieldName, Object columnValue) {
//  This method sets attribute of clazz (class instance) to given value 
    try {
      Field field = clazz.getClass().getDeclaredField(fieldName);		

//    This is necessary in case the class atttribute has private visibility
      field.setAccessible(true);
      field.set(clazz, columnValue);
    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
      e.printStackTrace();
    }	
  }	

  public void fromJSONString(String tree){
    JSONObject model;
    try {
//    Parse given JSON string
      model = new JSONObject(tree);
    } catch (JSONException e) {
      e.printStackTrace();
      System.err.println("Given JSON string cannot be parsed back to Object");
      return;
    }

//  Get all attributes of current class 
    Field[] fields = this.getClass().getDeclaredFields();
    for (Field field : fields) {
//    Process only fields marked with the required annotation
      if (field.isAnnotationPresent(JSONField.class)) {				
        try {
//        Set new value of the class instance attribute
          this.setProperty(this, field.getName(), model.get(field.getName()));
        } catch (JSONException e) {
	e.printStackTrace();
        }
      }
    }			
  }
}

We can make a simple test:

  1. Create 1st person with all attributes filled in
  2. Create 2nd person with all attributes filled in
  3. Create 3rd person from JSON string generated from 2nd person
public class Main {
  public static void main(String[] args) {
    Person p1 = new Person();
    p1.id  = 1;
    p1.name = "John";
    p1.age  = 30;

    Person p2 = new Person();
    p2.id  = 2;
    p2.name = "Mike";
    p2.age  = 47;
    String p2JSON = p2.toJSONString();

    Person p3 = new Person();
    p3.fromJSONString(p2JSON);

    System.out.println("P1: " + p1.toJSONString());
    System.out.println("P2: " + p2JSON);
    System.out.println("P3: " + p3.toJSONString());
  }
}

In output you can see that only attributes marked in class Person with annotation JSONField are present in the output JSON string. The 3rd person has been correctly created from given JSON string and its attributes were annotation JSONField is present were set.

P1: {"age":30,"name":"John"}
P2: {"age":47,"name":"Mike"}
P3: {"age":47,"name":"Mike"}

It is also important to say that this example operates with basic class attribute types only. If you’d like to have more complex objects serialized to/from JSON then you’d need to modify this example accordingly 😛

Leave a Reply