About Abhijeet Sutar

Abhijeet (ajduke) is self-taught, self-organized software developer. His current go to language is Java and also he is exploring other languages such as Scala, Ruby.

Using Google GSON : Extra Goodies : Part II

We continue with Using GSON from last article, also in case you missed the first article in series here is link. So, here we go with another installment in series.

Versioning Support

If you want to maintain multiple versions of an object for JSON conversion, Google GSON library has nice @Since annotation for it. This annotation can be applied to fields and classes.

For example, suppose you are maintaining the multiple versions of the your REST API and you are using JSON as end response payload. In next iteration of your API you are added some of fields for particular JSON entity and you don’t want to send the newly added fields to previous API version then @Since annotation comes into picture. Lets see in following listing, how we use this feature.

To make use of this annotation, you must configure the Gson instance to specific version using GsonBuilder, of course.

public class Example33 {
  public static void main(String[] args) {
    Gson gson = new GsonBuilder().setVersion(2.0).create();
    String json = gson.toJson(new ExampleClass());
    System.out.println("Output for version 2.0...");
    System.out.println(json);
    
    gson= new GsonBuilder().setVersion(1.0).create();
    json = gson.toJson(new ExampleClass());
    System.out.println("\nOutput for version 1.0...");
    System.out.println(json);
    
    gson= new Gson();
    json = gson.toJson(new ExampleClass());
    System.out.println("\nOutput for No version set...");
    System.out.println(json);
  }
}

class ExampleClass{
  String field=  "field";
  // this is in version 1.0
  @Since(1.0) String newField1 = "field 1";
  // following will be included in the version 1.1
  @Since(2.0) String newField2 = "field 2";
}

Output of above as:

Output for version 2.0...
{"field":"field","newField1":"field 1","newField2":"field 2"}

Output for version 1.0...
{"field":"field","newField1":"field 1"}

Output for No version set...
{"field":"field","newField1":"field 1","newField2":"field 2"}

If you are not specifying any version it will include the all the fields regardless of its version.

Disable HTML Escaping

By default, during conversion any html characters contained, will be converted to their corresponding Unicode i.e. <  to \u003c, > to \u003e , & to \u0026and so on

For passing the html characters as is, you need to configure the gson instance to with use of GsonBuilder#disableHtmlEscaping() method.

Following listing shows the usage:

public class Example34 {
  public static void main(String[] args) {
    String str ="<myval>";
    Gson gson = new Gson();
    System.out.println("Normal behaviour...");
    System.out.println(gson.toJson(str));
    
    System.out.println("\nDisabled html escaping...");
    gson = new GsonBuilder().disableHtmlEscaping().create();
    System.out.println(gson.toJson(str));
  }
}

Output  as follows:

Normal behaviour...
"\u003cmyval\u003e"

Disabled html escaping...
"<myval>"

Exclude the fields from Json Output

For this, Google GSON has 4 ways to deal,

  1. fields with transient and static modifier
  2. exclude with fields with specific modifiers
  3. Using Expose annotation
  4. User defined exclusion strategies

Lets see each of this in detail:

  1. fields with transient and static modifier

    This is default behavior, where you modify the field with transient  modifier it will not included as we saw in first article in series and of course, one with static modifier are also excluded as they are part of class and not the instance.

  2. exclude fields with specific modifiers

    You can configure gson instance, such that it will exclude the fields with modifiers you specified, e.g. you can exclude/ignore the fields which have protected or private modifier.

    To leverage this you need to use GsonBuilder#excludeFieldsWithModifiers()  as shown in following series of listing.

    class Developer {
    
      private String name;
      private String classz;
      List<String> languagesKnown;
      
      public Developer() {
        name = "ajduke";
        classz= "Developer";
        languagesKnown = new ArrayList<>();
        languagesKnown.add("Java");
        languagesKnown.add("Scala");
        languagesKnown.add("Ruby");
      }
    }

    For this example, we are not including the private fields. Although you can exclude fields with any modifiers (any modifiers that applies to fields)

    Gson gson = new Gson();
    
    System.out.println("Default behaviour ");
    GsonBuilder gsonBuilder = new GsonBuilder();
    Gson prettyGson = gsonBuilder.setPrettyPrinting().create();
    String json = prettyGson.toJson(new Developer());
    System.out.println(json);
    
    System.out.println("Ignoring/excluding fields ");
    
    GsonBuilder excludeFieldsWithModifiers = gsonBuilder
        	.excludeFieldsWithModifiers(Modifier.PRIVATE);
    
    Gson create = excludeFieldsWithModifiers.create();
    String json2 = create.toJson(new Developer());
    System.out.println(json2);
    

    In following output, you can see private fields are excluded as per our program, Although you can ignore fields which can have protected, synchronized etc.

    Default behaviour 
    {
      "name": "ajduke",
      "classz": "Developer",
      "languagesKnown": [
        "Java",
        "Scala",
        "Ruby"
      ]
    }
    
    Ignoring/excluding fields 
    {
      "languagesKnown": [
        "Java",
        "Scala",
        "Ruby"
      ]
    }
    
  3. Using Expose annotation

    Gson also provides an annotation which you can mark for the fields, thus those fields will be excluded from serialized output..

    For using this we need to following two

    1. configure gson instance as follows
      Gson gson= GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
    2. and mark the fields with @Expose annotations, which are to be included in final json output. So, one which are not marked will be excluded

    Following listing shows the detailed usage

    class Developer {
      // this field will be included
      @Expose
      private String name;
      private  String classz;
      List<String> languagesKnown;
      
      public Developer() {
        name = "ajduke";
        languagesKnown = new ArrayList<>();
        languagesKnown.add("Java");
        languagesKnown.add("Scala");
        languagesKnown.add("Ruby");
      }
    }
    
    
    
    public class GsonEx {
      public static void main(String[] args) throws IOException {
        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        String json = gson.toJson(new Developer());
        System.out.println(json);
      }
    }
    

    Ouput as follows:

    {"name":"ajduke"}
  4. User defined exclusion strategy

    Google Gson library provides very granular level of exclusions of fields based on type of field and field attributes.

    For this you need to implement the ExclusionStrategy interface by implementing the two of its methods such as shouldSkipClass() and shouldSkipField(). Former can implemented such that it will skip fields based on type of it and later can implemented based on field attribute such its modifier, its annotation etc

    and now after implementation ExclusionStrategy interface, you need to pass it to GsonBuilder#setExclusionStrategies() method for configuring the gson instance.

    Following is minimal implementation of use of Exclusion strategy, in which we exclude the fields are having type as String, List and also field which are having annotation as Deprecated

    Note the following implementation of ExclusionStrategy

    class ExclusionStrategyImpl implements ExclusionStrategy {
      private final Class<?> classTypeToSkip;
    
      public ExclusionStrategyImpl(Class<?> classTypeToSkip) {
        this.classTypeToSkip = classTypeToSkip;
      }
    
      @Override
      public boolean shouldSkipClass(Class<?> claz) {
        return classTypeToSkip == claz;
      }
    
      @Override
      public boolean shouldSkipField(FieldAttributes fa) {
        return fa.getAnnotation(Deprecated.class) !=null;
      }
    }

    Our custom Developer class for showing example:

    class Developer {
      @Deprecated
      private int count = 45;
      private String name;
      private  String classz;
      List<String> languagesKnown;
      
      public Developer() {
        name = "ajduke";
        classz = Developer.class.getCanonicalName();
        languagesKnown = new ArrayList<>();
        languagesKnown.add("Java");
        languagesKnown.add("Scala");
        languagesKnown.add("Ruby");
      }
    }
    public class Ex35 {
    
      public static void main(String[] args) {
        Gson gson = null;
        Developer developer = new Developer();
        String json = null;
        gson = new Gson();
        json = gson.toJson(developer);
        System.out.println("Default behaviuor....");
        System.out.println(json);
        
        // exclude field having String
        gson = new GsonBuilder().setExclusionStrategies(
        new ExclusionStrategyImpl(List.class)).create();
        json = gson.toJson(developer);
        System.out.println("\nExclude fields with type - List");
        System.out.println(json);
        
        // exclude field having List 
        gson = new GsonBuilder().setExclusionStrategies(
        new ExclusionStrategyImpl(String.class)).create();
        json = gson.toJson(developer);
        System.out.println("\nExclude fields with type - String");
        System.out.println(json);
      }
    }

    Output of above as follows:

    Default behaviuor....
    {"count":45,"name":"ajduke","classz":"in.ajduke.ap013.Developer","languagesKnown":["Java","Scala","Ruby"]}
    
    Exclude fields with type - List
    {"name":"ajduke","classz":"in.ajduke.ap013.Developer"}
    
    Exclude fields with type - String
    {"languagesKnown":[null,null,null]}

Custom field naming using field naming policy

As we saw in last article that Gson defaulted to include the output json field name same as that of class field name and also we can override this with use annotation @serilizedName.

In Gson there is more we can define the json field name to change to Uppercase, lowercase etc without use of any annotation.

For this you need to use GsonBuilder().setFieldNamingPolicy() method and passing the appropriate FieldNamePolicy

Following listing shows usage:

package in.ajduke.ap013;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Example34 {
  public static void main(String[] args) {
    
    Gson gson = new Gson();
    String json = gson.toJson(new JsonClass());
    System.out.println("Default behaviour....");
    System.out.println(json);
    
    gson = new GsonBuilder().setFieldNamingPolicy(
    FieldNamingPolicy.LOWER_CASE_WITH_DASHES).create();
    json = gson.toJson(new JsonClass());
    System.out.println("\nFields with lower case with dashes...");
    System.out.println(json);
    
    gson = new GsonBuilder().setFieldNamingPolicy(
    FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES).create();
    json = gson.toJson(new JsonClass());
    System.out.println("\nFields with upper case with spaces...");
    System.out.println(json);
    
  }
}

class JsonClass {
  String myField = "value1";
  String myAnotherField = "value2";
}
Default behaviour....
{"myField":"value1","myAnotherField":"value2"}

Fields with lower case and dashes...
{"my-field":"value1","my-another-field":"value2"}

Fields with lower case and dashes...
{"My Field":"value1","My Another Field":"value2"}

 

Reference: Using Google GSON : Extra Goodies : Part II from our JCG partner Abhijeet Sutar at the ajduke’s blog blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

One Response to "Using Google GSON : Extra Goodies : Part II"

  1. waqar says:

    How to remove fields having null or blank/empty values in json response on runtime? As there might be a case that one field might have a value and then it doesn’t , so I can’t use @Expose or any other of these. Kindly guide.

Leave a Reply


six × 7 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close