Spring Boot: integration of JSON binding libraries
Spring Boot directly supports three well-known JSON binding libraries: Jackson, Gson, and JSON-B (note that the latter is, more precisely, a specification). JSON binding is typically used in REST web services, but you can use it in several other contexts. In this article, I will explain how to integrate these libraries in Spring Boot (mainly 2.x and 3.x versions) with the help of some basic usage examples.
Premises
To show some concrete code, consider, for example, the following Spring controller:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/samples")
public class SampleController {
@GetMapping
public Person getPerson() {
return new Person("John", "Doe");
}
}
Person
is a simple JavaBean class with firstName
and lastName
fields plus standard getter/setter methods and an appropriate constructor. The source code of Person
is not shown here because you will see some slightly different versions in the following sections.
With the above controller and the Person
class, the goal is to generate a JSON response like this:
{"first-name":"John","last-name":"Doe"}
Spring Boot and Jackson
Jackson is a popular library for JSON binding and the default one in Spring Boot. Support for Jackson is provided by the spring-boot-starter-json
“starter” dependency.
In Spring Boot 2.x and 3.x, the “web” starters spring-boot-starter-web
and spring-boot-starter-webflux
already have spring-boot-starter-json
as a dependency. So if you have either of these web starters in your project, you already have Jackson!
The spring-boot-starter-json
dependency brings the following things into your project:
- The Jackson library (it means the three primary artifacts
jackson-databind
,jackson-annotations
, andjackson-core
) - The
jackson-datatype-jdk8
artifact to support JDK 8 data types: optional types (Optional
,OptionalInt
, etc.) and stream types (Stream
,IntStream
, etc.) - The
jackson-datatype-jsr310
artifact to support the Date/Time API datatypes (JSR-310 specification) introduced in JDK 8 (Instant
,LocalDate
,LocalTime
, etc.) - The
jackson-module-parameter-names
artifact to support introspection of method/constructor parameter names
Auto-configuration for Jackson
Furthermore, the Spring Boot auto-configuration creates an instance of the com.fasterxml.jackson.databind.ObjectMapper
class as a Spring “bean”. This means that you can easily inject the ObjectMapper
into your Spring beans (controllers, services, etc.) using, for example:
@Autowired
private ObjectMapper objectMapper;
Person class for Jackson
The following version of the Person
class uses the specific Jackson’s @JsonProperty
annotation to generate the same JSON response as shown above.
import com.fasterxml.jackson.annotation.JsonProperty;
public class Person {
@JsonProperty("first-name")
private String firstName;
@JsonProperty("last-name")
private String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// ... getter/setter methods omitted for brevity ...
}
Spring Boot and Gson
Gson is another known JSON binding library for Java. However, it is less popular than Jackson due to many limitations. One significant limitation is that Gson, by design, only considers object fields and not JavaBean properties (getSomething/setSomething methods). However, Gson is still a viable solution for JSON binding in Spring Boot applications.
In Spring Boot 2.x and 3.x, there is no specific “starter” dependency for Gson. Having Gson on the classpath is enough for Spring Boot to automatically consider it. You should also exclude the spring-boot-starter-json
dependency. Thus, the typical configuration in a Maven pom.xml
is the following:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <!-- or spring-boot-starter-webflux -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
Note that you do not need to specify the <version>
tag for the gson
artifact because the version is managed by Spring Boot (more precisely by the spring-boot-dependencies
POM).
Auto-configuration for Gson
When Spring Boot detects Gson, the auto-configuration creates an instance of the com.google.gson.Gson
class as a Spring “bean”. Similarly to Jackson’s ObjectMapper
, this means that the Gson
object can be injected into your Spring beans (controllers, services, etc.) using, for example:
@Autowired
private Gson gson;
Person class for Gson
The following version of the Person
class uses the specific Gson’s @SerializedName
annotation to generate the same JSON response as shown at the beginning of the article.
import com.google.gson.annotations.SerializedName;
public class Person {
@SerializedName("first-name")
private String firstName;
@SerializedName("last-name")
private String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// ... getter/setter methods omitted for brevity (they are NOT used by Gson) ...
}
Spring Boot and JSON-B
JSON-B is yet another option for JSON binding in Spring Boot. First of all, JSON-B is just only a specification for which there can be various implementations.
In Spring Boot 2.x and 3.x, there is no specific “starter” dependency for JSON-B. Therefore, you must declare some dependencies to have the JSON-B API and implementation on the classpath so Spring Boot can pick it up. We must also distinguish between Spring Boot 2.x and 3.x because there are critical differences in the preferred JSON-B implementation.
JSON-B in Spring Boot 2.x
In Spring Boot 2.x, the preferred and suggested JSON-B implementation is Apache Johnzon (as stated in Spring Boot reference documentation). The following is the set of Maven dependencies required to use JSON-B/Johnzon:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <!-- or spring-boot-starter-webflux -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
</dependency>
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.johnzon</groupId>
<artifactId>johnzon-jsonb</artifactId>
</dependency>
All these artifacts are managed by Spring Boot, so there is no need to specify the <version>
tag.
JSON-B in Spring Boot 3.x
In Spring Boot 3.x, the preferred and suggested JSON-B implementation is Eclipse Yasson (as stated in Spring Boot reference documentation). Therefore, the following is the set of Maven dependencies required to use JSON-B/Yasson:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <!-- or spring-boot-starter-webflux -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
</dependency>
Note that the Yasson artifact is easier to use because it implicitly depends on jakarta.json.bind-api
and jakarta.json-api
artifacts. The yasson
artifact version is also managed by Spring Boot, so there is no need to specify the <version>
tag.
Auto-configuration for JSON-B
When Spring Boot detects the presence of the JSON-B API, the auto-configuration looks for the implementation and obtains the object that implements the javax.json.bind.Jsonb
/jakarta.json.bind.Jsonb
interface, making it a Spring “bean”. Similarly to what you have previously seen for Jackson/Gson, this object can be quickly injected into your Spring beans (controllers, services, etc.) using, for example:
@Autowired
private Jsonb jsonb;
If you look at the javadoc documentation of Jsonb and Gson, you should notice many similarities. This is not accidental since both types are considered the main “entry point” for JSON binding.
Person class for JSON-B
The following version of the Person
class uses the specific JSON-B’s @JsonbProperty
annotation to generate the same JSON response as shown at the beginning of the article.
import javax.json.bind.annotation.JsonbProperty;
// Use: jakarta.json.bind.annotation.JsonbProperty in Spring Boot 3.x !!
public class Person {
@JsonbProperty("first-name")
private String firstName;
@JsonbProperty("last-name")
private String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// ... getter/setter methods omitted for brevity ...
}
Recap of JSON-B in Spring Boot 2.x/3.x
You have certainly noticed that there is quite a difference between Spring Boot 2.x and 3.x regarding JSON-B implementation, artifact(s), and package. Unfortunately, this is mainly because Spring Boot 3 is aligned to the Jakarta EE 9+ specification, which changed the Java Enterprise namespace from javax.*
to jakarta.*
.
The following table should clearly summarize the differences:
Spring Boot | Aligned to | Preferred JSON-B implementation |
JSON-B API artifact | JSON-B package |
---|---|---|---|---|
2.x | Java EE (7/8) | Apache Johnzon | javax.json.bind-api (also requires javax.json-api ) |
javax.json.bind |
3.x | Jakarta EE (9+) | Eclipse Yasson | jakarta.json.bind-api (also requires jakarta.json-api ) |
jakarta.json.bind |