Spring Boot uses Jackson by default as the serialization/deserialization framework for Json. But for me, I prefer Google’s Gson, which is much more concise. This article will teach you how to use Gson instead of Jackson in your Spring Boot application.

maven

Spring Boot itself provides support for Gson, so you can import the Gson module directly without declaring a version number. If you are not using Jackson elsewhere, then you can exclude it from your project.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <!-- exclude jackson (Optional) -->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-json</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- Gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>

application.yml

Set the preference to use Gson (GsonHttpMessageConverter) as the serialization framework via the spring.mvc.converters.preferred-json-mapper configuration.

For Gson, spring also predefines a number of configuration properties that are available. You can check the official documentation for their specific functionality.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
spring:
  mvc:
    converters:
      # Preferred use of Gson
      preferred-json: gson

    # More configurations for Gson.
#   gson:
#     date-format: 
#     disable-html-escaping: 
#     disable-inner-class-serialization: 
#     enable-complex-map-key-serialization: 
#     exclude-fields-without-expose-annotation: 
#     field-naming-policy: 
#     generate-non-executable-json: 
#     lenient: 
#     long-serialization-policy: 
#     pretty-printing: 
#     serialize-nulls: 

Configuration

If you need to do more custom configuration of Gson (e.g. customize the serialization format of LocalDateTime), then this can be done through the configuration class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package io.springcloud.demo.configuration;

import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

import org.springframework.boot.autoconfigure.gson.GsonBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

/**
 * 
 * @author KevinBlandy
 *
 */

@Configuration
public class GsonConfiguration {

    /**
        * @param customizers    Configuration in application.yaml
        * @return
        */
    @Bean
    public GsonBuilder gsonBuilder(List<GsonBuilderCustomizer> customizers) {

        GsonBuilder builder = new GsonBuilder();
        // Enable the spring.gson.* configuration in the configuration file
        customizers.forEach((c) -> c.customize(builder));

        /**
        * Custom Gson configuration
        */
        builder.registerTypeHierarchyAdapter(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {

            DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

            @Override
            public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
                return new JsonPrimitive(DATE_TIME_FORMATTER.format(src));
            }
        });

        return builder;
    }
}

Exclude Jackson (Optional)

Exclude auto-configuration of jackson in SpringBootApplication.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package io.springcloud.demo;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;

@SpringBootApplication(exclude = { JacksonAutoConfiguration.class }) // Exclude the automatic configuration of JACKSON
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Testing

Controller

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package io.springcloud.demo.web.controller;

import java.time.LocalDateTime;
import java.util.Map;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping
    public Object test() {
        return Map.of("success", Boolean.TRUE, "datetime", LocalDateTime.now());
    }
}

Request this Controller and you will get the following response.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
GET /test HTTP/1.1
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 55d6b94c-c1bb-4de2-8a1d-54e0117237bd
Host: localhost
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
 
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 04 May 2022 09:56:51 GMT
Keep-Alive: timeout=60
Connection: keep-alive
 
{"datetime":"2022-05-04 17:56:51","success":true}

As you can see, Gson has formatted the LocalDateTime object according to the format we specified.

Get Gson object

You can get Gson objects from anywhere, via IOC injection.

1
2
@Autowired
private Gson gson;