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:

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

Similar Posts