Spring Boot: integration of JSON binding libraries
Spring Boot provides direct support for 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 of course you can use it in several other contexts. In this article I am going to 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
In order 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 of it 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 very popular library for JSON binding and it is also the default one in Spring Boot. Support for Jackson is provided by the spring-boot-starter-json
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 dependency. This means that if you have either of these two web starters in your project, then you already have Jackson!
The spring-boot-starter-json
dependency brings the following things into your project:
- The Jackson library (it means the three main 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 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 in order to generate the JSON response exactly 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. It is less popular than Jackson due to many limitations. One important 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. It is sufficient to have the Gson library “in classpath” and Spring Boot automatically picks it up. 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
artifact).
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 in order to generate the JSON response exactly 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. You have to declare some dependencies in order to have the JSON-B API and an implementation “in classpath” so that Spring Boot can pick it up. We must also distinguish between Spring Boot 2.x and 3.x because there are some important differences about 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). 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 a bit easier to use because it implicitly depends on jakarta.json.bind-api
and jakarta.json-api
artifacts. Also the yasson
artifact is 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 then 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 easily 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 that there are many similarities. This is not accidental, since both types are the “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 in order to generate the JSON response exactly 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 about JSON-B implementation, artifact(s) and package. Unfortunately, this is mainly due to the fact that 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 |