Merge pull request #10232 from adinarolea/feature/BAEL-4687-customize-jackson-json-mapper

Feature/bael 4687 customize jackson json mapper
This commit is contained in:
Jonathan Cook 2020-12-22 08:18:13 +01:00 committed by GitHub
commit f8853469cb
18 changed files with 286 additions and 0 deletions

View File

@ -69,6 +69,7 @@
<module>spring-boot-vue</module>
<module>spring-boot-xml</module>
<module>spring-boot-actuator</module>
<module>spring-boot-data-2</module>
</modules>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.baeldung.spring-boot-modules</groupId>
<artifactId>spring-boot-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-data-2</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,13 @@
package com.baeldung.boot.jackson.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = "com.baeldung.boot.jackson.controller")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,13 @@
package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class CoffeeConstants {
public static final String DATETIME_FORMAT = "dd-MM-yyyy HH:mm";
public static final LocalDateTime FIXED_DATE = LocalDateTime.now();
public static LocalDateTimeSerializer LOCAL_DATETIME_SERIALIZER = new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATETIME_FORMAT));
}

View File

@ -0,0 +1,18 @@
package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
@Configuration
public class CoffeeCustomizerConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> builder.serializationInclusion(JsonInclude.Include.NON_NULL)
.serializers(LOCAL_DATETIME_SERIALIZER);
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
@Configuration
public class CoffeeHttpConverterConfiguration {
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.serializers(LOCAL_DATETIME_SERIALIZER)
.serializationInclusion(JsonInclude.Include.NON_NULL);
return new MappingJackson2HttpMessageConverter(builder.build());
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
@Configuration
public class CoffeeJacksonBuilderConfig {
@Bean
@Primary
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
return new Jackson2ObjectMapperBuilder()
.serializers(LOCAL_DATETIME_SERIALIZER)
.serializationInclusion(JsonInclude.Include.NON_NULL);
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
@Configuration
public class CoffeeObjectMapperConfig {
@Bean
@Primary
public ObjectMapper objectMapper() {
JavaTimeModule module = new JavaTimeModule();
module.addSerializer(LOCAL_DATETIME_SERIALIZER);
return new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL)
.registerModule(module);
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
@Configuration
@PropertySource("classpath:coffee.properties")
public class CoffeeRegisterModuleConfig {
@Bean
public Module javaTimeModule() {
JavaTimeModule module = new JavaTimeModule();
module.addSerializer(LOCAL_DATETIME_SERIALIZER);
return module;
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.boot.jackson.controller;
import com.baeldung.boot.jackson.model.Coffee;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE;
@RestController
public class CoffeeController {
@GetMapping("/coffee")
public Coffee getCoffee(
@RequestParam(required = false) String brand,
@RequestParam(required = false) String name) {
return new Coffee().setBrand(brand)
.setDate(FIXED_DATE)
.setName(name);
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.boot.jackson.model;
import java.time.LocalDateTime;
public class Coffee {
private String name;
private String brand;
private LocalDateTime date;
public String getName() {
return name;
}
public Coffee setName(String name) {
this.name = name;
return this;
}
public String getBrand() {
return brand;
}
public Coffee setBrand(String brand) {
this.brand = brand;
return this;
}
public LocalDateTime getDate() {
return date;
}
public Coffee setDate(LocalDateTime date) {
this.date = date;
return this;
}
}

View File

@ -0,0 +1 @@
spring.jackson.default-property-inclusion=non_null

View File

@ -0,0 +1,33 @@
package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeConstants;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import java.time.format.DateTimeFormatter;
import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public abstract class AbstractCoffeeIntegrationTest {
@Autowired
protected TestRestTemplate restTemplate;
@Test
public void whenGetCoffee_thenSerializedWithDateAndNonNull() {
String formattedDate = DateTimeFormatter.ofPattern(CoffeeConstants.DATETIME_FORMAT)
.format(FIXED_DATE);
String brand = "Lavazza";
String url = "/coffee?brand=" + brand;
String response = restTemplate.getForObject(url, String.class);
assertThat(response).isEqualTo(
"{\"brand\":\"" + brand + "\",\"date\":\"" + formattedDate + "\"}");
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeCustomizerConfig;
import org.springframework.context.annotation.Import;
@Import(CoffeeCustomizerConfig.class)
public class CoffeeCustomizerIntegrationTest extends AbstractCoffeeIntegrationTest {
}

View File

@ -0,0 +1,8 @@
package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeHttpConverterConfiguration;
import org.springframework.context.annotation.Import;
@Import(CoffeeHttpConverterConfiguration.class)
public class CoffeeHttpConverterIntegrationTest extends AbstractCoffeeIntegrationTest {
}

View File

@ -0,0 +1,8 @@
package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeJacksonBuilderConfig;
import org.springframework.context.annotation.Import;
@Import(CoffeeJacksonBuilderConfig.class)
public class CoffeeJacksonBuilderIntegrationTest extends AbstractCoffeeIntegrationTest {
}

View File

@ -0,0 +1,8 @@
package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeObjectMapperConfig;
import org.springframework.context.annotation.Import;
@Import(CoffeeObjectMapperConfig.class)
public class CoffeeObjectMapperIntegrationTest extends AbstractCoffeeIntegrationTest {
}

View File

@ -0,0 +1,8 @@
package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeRegisterModuleConfig;
import org.springframework.context.annotation.Import;
@Import(CoffeeRegisterModuleConfig.class)
public class CoffeeRegisterModuleIntegrationTest extends AbstractCoffeeIntegrationTest {
}