/
Faster XML Jackson usage in Portal Code and replacing it with Gson

Faster XML Jackson usage in Portal Code and replacing it with Gson

Areas where Jackson is Used:

  1.     Direct usage of Jackson by Portal code

  2.     Indirect dependency through other packages

  3.     Frameworks configured with Jackson like Spring Boot



Modules with direct dependency on Jackson package:



Portal-SDK:



  1. epsdk-fw

  2. epsdk-analytics

  3. epsdk-app-common

  4. epsdk-app-os

  5. epsdk-core

  6. epsdk-domain

  7. epsdk-music

  8. epsdk-workflow

  9. epsdk-aaf

Portal:

  1. Portal-BE-Common:

  2. Portal-BE-OS:

  3. Portal-widget-ms:

Packages used that have dependency on Jackson:

Portal-SDK:

  1. org.elasticsearch:elasticsearch:jar – Not using this package anywhere in the code and can be removed, as confirmed by Sunder.

  2. org.onap.portal.sdk:epsdk-music:jar



Portal:



  1. com.orbitz.consul:consul-client:jar - Excluded the jacskon dependency for this package and ran the build. The build is successful, however this needs to tested with real time scenarios.

  2. org.elasticsearch:elasticsearch:jar - Not using this package anywhere in the code and can be removed, as confirmed by Sunder

  3. Spring Boot


Code Analysis:

  1. Portal-SDK:   Approximately 60+ files that inculde fatserxml jackson excluding test files.

  2. Portal: Approximately 60+ files that inculde fatserxml jackson excluding test files



Using Gson In our Code:

Gson Maven Dependency:



            <dependency>

                        <groupId>com.google.code.gson</groupId>

                        <artifactId>gson</artifactId>

                        <version>${gson.version}</version>

            </dependency>



POC- Replacing Jackson with Gson in our code:

  • Gson FromJson method as replacement for Jackson readValue method-Replaced Jackson methods with Gson methods in saveRoleFunction() method of RoleFunctionListController class as below,



                  Replaced this,

                                  public void saveRoleFunction() {

                                              String data = roleFunc;

                                              RoleFunction availableRoleFunction = mapper.readValue(data, RoleFunction.class);

                                              System.out.println("mapper.readVlaue:"+availableRoleFunction);   

                                   }

              With this,

                                  public void saveRoleFunction() {

                                              String data = roleFunc;

                                              RoleFunction roleFunctonAvailable = gson.fromJson(data, RoleFunction.class);

                                              System.out.println("gson:fromJson:"+roleFunctonAvailable);    

                                  }



               Output for both methods, gson.fromJson() and mapper.readValue, is same.



  • Gson toJson method as replacement for Jackson writeValueAsString method-Replaced Jackson methods with Gson methods in buildJsonResponse() method of JsonMessage class as below,



              Replaced this,

                              public static String buildJsonResponse(boolean success, String msg) {

                                           String json = null;

                                           json = new ObjectMapper().writeValueAsString(response);

                                          System.out.println("mapper.WriteValueAsString:"+json);

                                           return json;

                            }



             With this,

                           public static String buildJsonResponse(boolean success, String msg) {

                                        String jsonFromGson = null;

                                         jsonFromGson = new Gson().toJson(response);

                                         System.out.println("Gson().toJson:"+jsonFromGson);

                                         return jsonFromGson;

                          }



            Output for both methods, gson.fromJson() and mapper.readValue, is same



Replacing spring Boot Jackson dependencies with Gson:

         https://www.callicoder.com/configuring-spring-boot-to-use-gson-instead-of-jackson/

Jackson Methods used in our code and their equivalents in Gson:

            Below are few of the methods and their usages in Gson that can be used as replacements for Jackson,

Jackson Method

Jackson Class

Usage

GSON Equivalent Method

GSON Equivalent Class

Usage

Jackson Method

Jackson Class

Usage

GSON Equivalent Method

GSON Equivalent Class

Usage

readValue

jackson.databind.ObjectMapper

<ObjectType> obj = mapper.readValue(JsonString, ClassType);

fromJson

com.google.gson.Gson;

<ObjectType> obj = gson.fromJson(data, RoleFunction.class);

writeValueAsString

jackson.databind.ObjectMapper

String json = new ObjectMapper().writeValueAsString(Object);

toJson

com.google.gson.Gson;

String resultJson = new Gson().toJson(Object);

configure

jackson.databind.ObjectMapper

objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
objectMapper.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)

Use GsonBuilder to construct a Gson instance when you need to set configuration options other than the default

com.google.gson.GsonBuilder

Gson gson = new GsonBuilder()
     .serializeNulls()
     .setDateFormat(DateFormat.LONG)
     .create();

readTree

jackson.databind.ObjectMapper

JsonNode root = mapper.readTree(request.getReader());

parse

com.google.gson.JsonParser

JsonElement rootNode = parser.parse(jsonString);

NA

jackson.databind.JsonNode;

Base class for all JSON nodes, which form the basis of JSON

NA

import com.google.gson.JsonElement;

class representing an element of Json. It could either be a JsonObject, a JsonArray, a JsonPrimitive or a JsonNull

NA

jackson.core.type.TypeReference

TypeReference<List<Type>> typeRef = new TypeReference<List<Type>>() {};
      List<Type> listObj = mapper.readValue(requestBody, typeRef);

NA

import com.google.gson.reflect.TypeToken;

listObj = gson.fromJson(jsonString, new TypeToken<Hashtable<String, Type>>() {}.getType());

NA

import com.fasterxml.jackson.databind.type.TypeFactory;



NA





NA

jackson.annotation.JsonIgnoreProperties;

JsonIgnoreProperties(ignoreUnknown = true)

NA

com.google.gson.annotations.Expose

GSON @Expose annotation using GsonBuilder.excludeFieldsWithoutExposeAnnotation().

NA

jackson.annotation.JsonRootName;

JsonRootName(value="abc")
public class ClassName {}

NA

javax.xml.bind.annotation.XmlElement

XmlRootElement
public class ClassName {}



References:
https://www.baeldung.com/jackson-vs-gson
http://websystique.com/java/json/gson-json-annotations-example/
https://www.tutorialspoint.com/gson/gson_tree_model.htm
https://google.github.io/gson/apidocs/index.html?com/google/gson/class-use/JsonElement.html
https://www.baeldung.com/gson-deserialization-guide
http://websystique.com/java/json/gson-tree-model-example/