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:

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