How to Accept and Produce JSON as a response in Spring Boot? Example Tutorial

Hello everyone, welcome to the blog post. In this short tutorial, we are going to take an in-depth look at how to consume and produce JSON responses using a widely appreciated Java framework i.e. Spring Boot. As we all know Spring Boot is a framework designed to build a secure web application, microservice, REST API, and production-ready spring application. Modern-day application deals in a large amount of data, which they share in JSON format. A JSON is a standard plain text-based representation of structured data. It is one of the popular formats for data transmission over the internet. Due to its user-friendly syntax and lightweight, it helps in the process faster. 


As we have discussed above, JSON is widely processed over the network for sharing data between two nodes (ends). Hence Web services and REST API prefer data communication either in JSON or XML-based format.

Let's see how can we let Spring Boot consumes JSON data as Input.

Let's understand with the help of a simple Restful web service that consumes the stadium’s detail in JSON as part of the HTTP-request body. Below is a complete java program that consumes the JSON data.


Application.java

package com.javarevisited.gettingstarted;



import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;



import java.io.IOException;



@SpringBootApplication

public class GettingStarted {

    public static void main(String[] args) throws IOException {

        SpringApplication.run(GettingStarted.class, args);

    }

}

 


Stadium.java

package com.javarevisited.gettingstarted.model;



import jakarta.persistence.Entity;

import jakarta.persistence.GeneratedValue;

import jakarta.persistence.GenerationType;

import jakarta.persistence.Id;

import jakarta.validation.constraints.Max;

import jakarta.validation.constraints.Min;

import jakarta.validation.constraints.NotNull;

import java.sql.Date;



public class Stadium {





@Id

    @GeneratedValue(strategy = GenerationType.AUTO)

    private int stadium_id;





    @NotNull(message = "Stadium name is required")

    private String name;



    @Min(message = "Stadium should meet the min capacity", value = 50)

    @Max(value = 100000, message = "Stadium should meet the max capacity")

    private String capacity;

   



@NotNull(message = "Stadium must belongs to a country")

    private String country;

   



private String constructedInYear;

    private Date lastRennovation;



    public int getStadium_id() {

        return stadium_id;

    }

    public void setStadium_id(int stadium_id) {

        this.stadium_id = stadium_id;

    }

   



public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }



    public String getCapacity() {

        return capacity;

    }



    public void setCapacity(String capacity) {

        this.capacity = capacity;

    }



    public String getCountry() {

        return country;

    }



    public void setCountry(String country) {

        this.country = country;

    }



    public String getConstructedInYear() {

        return constructedInYear;

    }



    public void setConstructedInYear(String constructedInYear) {

        this.constructedInYear = constructedInYear;

    }



    public Date getLastRennovation() {

        return lastRennovation;

    }



    public void setLastRennovation(Date lastRennovation) {

        this.lastRennovation = lastRennovation;

    }



    @Override

    public String toString() {

        return this.name + " stadium has a total capacity of "
  + this.capacity + " seats and was  constructed in year " 
+ this.constructedInYear + " and was last renovated on date                                       " + this.lastRennovation;

    }

}

 

The above code represents a stadium entity object.


StadiumRepo.java


package com.javarevisited.gettingstarted.repo;



import com.javarevisited.gettingstarted.model.Stadium;

import org.springframework.data.jpa.repository.JpaRepository;



import java.util.List;



public interface StadiumRepo extends JpaRepository<Stadium, Integer> {



}



StadiumController.java


package com.javarevisited.gettingstarted.controller;



import com.javarevisited.gettingstarted.model.Stadium;

import com.javarevisited.gettingstarted.repo.StadiumRepo;

import jakarta.persistence.EntityNotFoundException;

import jakarta.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.HttpStatus;

import org.springframework.http.MediaType;

import org.springframework.http.ResponseEntity;

import org.springframework.web.ErrorResponse;

import org.springframework.web.bind.MethodArgumentNotValidException;

import org.springframework.web.bind.annotation.*;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Optional;





@RestController

@RequestMapping("/api/v1/stadiums")

public class StadiumController {





@Autowired

StadiumRepo stadiumRepo;



 



@RequestMapping(value = "/", method = RequestMethod.GET)

public ResponseEntity<List<Stadium>> getAllStadiums(){

    return new ResponseEntity<>(stadiumRepo.findAll(), HttpStatus.OK);

}





   

    @PostMapping(

    value = "/",

    consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE},

    produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})

    public ResponseEntity<Stadium> postNewStadium(@Valid @RequestBody Stadium stadium){

        return new ResponseEntity<Stadium>(stadiumRepo.save(stadium), HttpStatus.OK);

    }

}


As you can see from the above rest controller, we have a POST request to /api/v1/stadiums/ that takes stadium details in JSON format as part of Request body


How to Accept and Produce JSON as a response in Spring Boot? Example Tutorial



Consuming JSON data

The above mention endpoint will consume APPLICATION_JSON_VALUE as the media type. Spring Boot supports various media types. Using it one can tweak their application input behavior. In order to reach the Spring Boot REST API directly, we have to provide a JSON-encoded object that has all the required arguments that match the Stadium entity.


consumes = {MediaType.APPLICATION_JSON_VALUE}
@RequestBody Stadium stadium


Below is the sample data we will send to our REST API.


{



"stadium_id": 5,



"name": "Pallekele International Cricket Stadium",



"capacity": "35000",



"country": "SriLanka",



"constructedInYear": "2005",



"lastRennovation": "2022-08-28"



}


Consuming JSON data is simple and straightforward using Spring Boot. Now let’s see how to return JSON response using Spring Boot.


Producing JSON data

It is to note here that, Spring Boot by default has Jackson dependency as part of spring-boot-starter-json. @RestController annotation on top of any Spring Boot class by default render JSON response as long as Jackson is residing in the classpath.


@RequestMapping(
value = "/",
method = RequestMethod.GET,
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}
)
public ResponseEntity<List<Stadium>> getAllStadiums(){
        return new ResponseEntity<>(stadiumRepo.findAll(), HttpStatus.OK);
}


In our case, a response will be serialized by the Jackson2 library first and then serves as a JSON object to the client.

Below is the response after making a GET request to


GET: http:{host_name}:{port_name}/api/v1/stadiums/


[

  {

    "stadium_id": 3,

    "name": "Lords Cricket Stadium",

    "capacity": "40000",

    "country": "England",

    "constructedInYear": "1890",

    "lastRennovation": "2013-02-17"

  },

  {

    "stadium_id": 5,

    "name": "Pallekele International Cricket Stadium",

    "capacity": "35000",

    "country": "SriLanka",

    "constructedInYear": "2005",

    "lastRennovation": "2022-08-28"

  }

]

Are you concerned about, how this conversion took place? without explicitly parsing the stadium’s POJO class into JSON. The answer to your question is there is no need to perform an explicit json conversion because you have annotated with @RestController. Just return a POJO, and the Jackson serializer will handle the JSON conversion by itself.

When used in conjunction with @Controller, it is the same as using ResponseBody.


We use @RestController in place of the standard @Controller, and @ResponseBody is automatically applied to all resources in that controller rather than having to place it on each controller function.


Modifying Jackson ObjectMapper

To handle request and response body conversion, Spring boot automatically configures mapping Jackson2HttpMessageConverter as one of the default converters. Using property files or unique bean definitions, we may alter the default conversion behavior. 


 Property Customization


spring.jackson.date-format= specify date format here, `yyyy-MM-dd HH:mm:ss`.



spring.jackson.default-property-inclusion= specify inclusion of properties here.



spring.jackson.deserialization.*= on/off features for deserialization.



spring.jackson.locale= Locale used for formatting.



spring.jackson.mapper.*= Jackson general purpose on/off features.



spring.jackson.parser.*= Jackson on/off features for parsers.



spring.jackson.property-naming-strategy= # PropertyNamingStrategy.



spring.jackson.time-zone= Specify time zone here.



spring.jackson.visibility.*= Put limit on methods (and fields) for auto-detected.


 


Customization using Bean

@Configuration
public class WebConfig
{
    @Bean
    public Jackson2ObjectMapperBuilder customJson() {
        return new Jackson2ObjectMapperBuilder()
            .indentOutput(true)
            .serializationInclusion(JsonInclude.Include.NON_NULL)
            .propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
    }
}


 Conclusion

That's all about how to accept and produ e JSON response in Spring Boot application. With this, we reach the end of our short article. Here we have learned, how Spring Boot consumes and produces JSON data and the underlying mechanism behind this conversion. In addition to it, the article put some light on how to customize the default behavior of Jackson2ObjectMapper.


Other Spring MVC articles and Tutorials you may like
Thanks a lot for reading this article so far. If you like this Java and Spring Boot tutorial then please share them with your friends and colleagues. If you have any questions or feedback then please drop a note. 

1 comment:

Feel free to comment, ask questions if you have any doubt.