Jackson vs Gson: Edge Cases in JSON Parsing for Java Apps
Jackson and Gson are popular JSON parsers for Java, but they handle edge cases like null values, type mismatches, and custom serialization differently.
Join the DZone community and get the full member experience.
Join For FreeJSON (Javascript Object Notation) is a collection of key-value pairs that can be easily parsed and generated by applications. It is a subset of JavaScript Programming Language Standard ECMA-262. The parsing of JSON is required in most applications, such as restful APIs or applications that need data serialization.
In the Java ecosystem, the two most popular libraries for handling JSON data are Jackson and Gson. Both are used widely and offer unique advantages. This article uses edge-case examples to explore the features of both libraries on different parameters.
Brief Overview of Jackson and Gson
Jackson
Jackson was developed by FasterXML and is used in enterprise applications and frameworks such as Spring Boot. It offers parsing, serialization, and deserialization of JSON data. The following features make this library popular among developers:
- Jackson is the default JSON processing library in Spring Boot, which eliminates manual configuration in most cases.
- It facilitates JSON deserialization into generic types using TypeReference or JavaType.
- It provides different annotations to customize serialization and deserialization behavior. For example,
@JsonProperty(name)
makes the mapping between the incoming key and the actual Java POJO field seamless. - It provides extensive and robust support for bidirectional Databinding (JSON to POJO and vice versa), streaming API (API reads JSON into POJO), and Tree model parsing (an in-memory map of JSON objects).
- The Jackson library offers high performance due to minimizing memory overhead and optimizing serialization/deserialization (from JSON to POJO and vice versa).
- Jackson supports additional modules such as XML, YAML processing, and Kotlin, scala-specific enhancements.
- Annotations such as
@JsonTypeInfo
and@JsonSubTypes
handle polymorphic types. - It handles missing or additional fields in JSON data due to its backward and forward compatibility.
- Jackson provides support for immutable objects and classes with constructors, including those using builder patterns.
- The
ObjectMapper
class is thread-safe and, therefore, enables efficient use in multithreaded applications.
Gson
Gson was developed by Google and designed for converting JSON to Java objects (POJO) and vice versa. It is simple and ideal to use for smaller applications that need quick implementations. The open-source library offers the following key features:
- Gson has minimal external dependencies; therefore, it is easy to integrate.
- It supports nested objects and complex data types such as lists, maps, and custom classes.
- It can deserialize JSON into generic collections like
List<T>
,Map<K,V>
using TypeToken. - Gson Library’s JsonSerializer and JsonDeserializer interfaces allow customized implementation.
- The null values are excluded in the JSON output by default, and if required, null values can be included in the output.
- Annotations
@SerializedName
maps JSON keys to Java fields with different names. - The Gson objects are thread-safe and, therefore, can be used in multithreaded applications.
- Class GsonBuilder can apply custom naming policies for fields. For example,
FieldNamingPolicy.IDENTITY
is the default policy, meaning the field name is unchanged.
Edge Cases Considered in This Comparison
Feature | Jackson | GSON |
---|---|---|
Extra Fields |
Ignored by default, configurable. |
Ignored by default. |
Null values |
Supports @JsonInclude. |
Requires .serializeNulls(). |
Circular References |
Supported using @JsonIdentityInfo. |
Not supported directly. |
Data Handling |
Supports Java 8 Date API with modules. |
Requires custom-type adapters. |
Polymorphism |
Built-in with @JsonTypeInfo. |
Needs custom deserialization logic. |
The input JSON considered for comparison with Jackson and Gson libraries is present on GitHub.
The model class representation of JSON is on GitHub.
Jackson Implementation
The above JSON is converted to a Java object using the Jackson libraries below:
<!-- Jackson START-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.18.2</version>
</dependency>
<!-- Jackson END-->
JSON Parsing main class using Jackson library:
public class JacksonJsonMain {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
//Jackson Support for LocalDate using jackson-datatype-jsr310
mapper.registerModule(new JavaTimeModule());
//Configuration to ignore extra fields
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// Deserialize the JSON
EmployeeModelData employeeModelData = mapper.readValue(json, EmployeeModelData.class);
Employee employee=employeeModelData.getEmployee();
// display Json fields
System.out.println("Jackson Library parsing output");
System.out.println("Employee Name: " + employee.getName());
System.out.println("Department Name: " + employee.getDepartment().getName());
System.out.println("Skills: " + employee.getSkills());
System.out.println("Team Members Count: " + employeeModelData.getTeamMembers().size());
}
}
The output of the above class is as follows:
Gson Implementation
The Gson dependency used to convert the above JSON to a Java object is below:
<!--GSON START -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<!--GSON END -->
JSON parsing using GSON library main class:
public class GsonJsonMain {
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // Register LocalDate adapter
.serializeNulls() // Handle null values
.setPrettyPrinting() // Pretty print JSON
.create();
// Deserialize the JSON
EmployeeModelData data = gson.fromJson(json, EmployeeModelData.class);
// Print Employee information
System.out.println("GSON Library parsing output");
System.out.println("Employee Name: " + data.getEmployee().getName());
System.out.println("Department Name: " + data.getEmployee().getDepartment().getName());
System.out.println("Skills: " + data.getEmployee().getSkills());
System.out.println("Team Members Count: " + data.getTeamMembers().size());
}
}
The output of the above main class is as follows:
Which One Should I Choose?
Jackson offers high performance; therefore, it must be used when projects involve complex data structures or large datasets, whereas Gson must be used when there are smaller datasets and the data structure is simple.
Conclusion
Both libraries can handle the above dataset effectively and are excellent while processing JSON parsing in JAVA. The comparison mentioned above helps one to choose the right library based on project requirements.
The code snippets mentioned above are available in the GitHub repository.
A detailed comparison between Jackson and Gson is available on Baeldung. The Jackson official Documentation offers in-depth information on Jackson’s features and configuration. Similarly, Gson Official documentation provides a detailed implementation guide.
Opinions expressed by DZone contributors are their own.
Comments