Spring boot supports the development of RESTful APIs by providing good support. Spring boot’ s web dependency adds Jackson libraries by default. We can easily customize the response JSON fields according to our requirements.

In this article, we will learn how to override the default JSON response fields by using custom configurations.

We will create a simple DTO class with few fields containing different data types like LocalDate, etc. We will expose a REST endpoint to retrieve the DTO object in the JSON form.

In the first part of the article, we will use the default Jackson properties and check how the response fields are retrieved. In the later part of the article, we will customize the response according to our requirements.

Alright!! Let’s begin!! ๐Ÿ™‚

Create REST service with spring boot

We are going to create a simple spring boot application with spring-boot-starter-web and lombok(to avoid boilerplate code) dependencies.

Create the DTO class

A DTO class is a simple java POJO class with getter and setter methods. We will create a simple EmployeeDTO.java class with few fields as shown below.

This DTO class contains fields of different type like String, Date of type java.util library and LocalDate, LocalDateTime, etc.

We have used the Lombok library to avoid extra boilerplate codes to generate getter, setter, and other methods.

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class EmployeeDTO {
	
	private Integer id;
	private String empName;
	private Date date;
	private LocalDate joinDate;
	private LocalDateTime joinDateTime;
}

Create a controller class

Create a RESTful controller class called EmployeeController.java with an HTTP GET endpoint exposed at “/get-json” as shown below.

The getObject() method defined below, when invoked, returns a new EmployeeDTO object.

@RestController
public class EmployeeController {

	@GetMapping("/get-json")
	public ResponseEntity<EmployeeDTO> getObject() {
		EmployeeDTO dto = new EmployeeDTO(1, "Arun", new Date() ,LocalDate.now(), LocalDateTime.now());
		return new ResponseEntity<>(dto, HttpStatus.OK);
	}
}

Retrieve the EmployeeDTO

Since we haven’t made any changes in default Jackson configuration, we will get the below JSON response.

default_json_response

Customizing the JSON response

Suppose we have a requirement to change the JSON response, with all field names should be followed underscores, instead of camel cases. Also, date fields should have a certain date format.

This can be achieved by creating a configuration class, implementing the WebMvcConfigurer interface and overriding the configureMessageConverters() method. This will override the default message converter behavior of the current application.

We also need to use the @EnableWebMvc annotation on our configuration class.

Create a CustomJsonConfig.java configuration class and implement the WebMvcConfigurer interface. Annotate the class with @EnableWebMvc and @Configuration annotations.

The below code shows the complete code of the configuration class.

@Configuration
@EnableWebMvc
public class CustomJsonConfig implements WebMvcConfigurer {

	@Value("${dateformat.type}")
	private String test;

	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

		ObjectMapper mapper = new Jackson2ObjectMapperBuilder()
				.propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
				.simpleDateFormat(test.equalsIgnoreCase("A") ? "MM/dd/yyyy" : "MM-dd-yyyy")
				.serializers(
						new LocalDateSerializer(test.equalsIgnoreCase("A") ? DateTimeFormatter.ofPattern("yyyy/MM/dd")
								: DateTimeFormatter.ofPattern("dd-MM-yyyy")),
						new LocalDateTimeSerializer(
								test.equalsIgnoreCase("A") ? DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")
										: DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")))
				.deserializers(
						new LocalDateDeserializer(test.equalsIgnoreCase("A") ? DateTimeFormatter.ofPattern("yyyy/MM/dd")
								: DateTimeFormatter.ofPattern("dd-MM-yyyy")),
						new LocalDateTimeDeserializer(
								test.equalsIgnoreCase("A") ? DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")
										: DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")))
				.build();

		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper);
		converters.add(converter);
	}
}

Also, add the following property into the application.properties file.

dateformat.type=A

In the above code, we have set the property naming strategy to SNAKE_CASE, which converts the camel-case DTO field names into underscore separated names.

We can also see a SPEL(Spring Expression Language) expression, which reads “dateformat.type” property and sets it to the field called test.

We are setting the date-time format dynamically based on the value of the custom property dateformat.type.

If the property value is A, the java.util.Date field is set with date format “MM/dd/yyyy” and date format will be “MM-dd-yyyy” for any other values.

Similarly, we have configured different LocalDate and LocalDateTime formats based on the value of dateformat.type property dynamically.

Below is the customized JSON output with dateformat.type property value as “A“.

customized json format 1

With other value:

customized json format 2

Congratulations!! ๐Ÿ™‚ We have learned how to customize RESTful service response JSON by overriding the default message converter properties.

Conclusion

In this article, we learned how to customize the JSON response of spring boot RESTful web service applications.

We also learned how to dynamically set the JSON properties by customizing the date format of the response JSON based on the configuration property value.

The sample code is available on Github. Happy coding ๐Ÿ™‚ ๐Ÿ™‚

You may also interested in