Introduction
With Spring, we map requests to request handlers via the @RequestMapping
annotation. Spring Boot introduced us to derived types of this annotation - @GetMapping
, @PostMapping
, @DeleteMapping
, etc.
These requests contain different types of information and data - and depending on what our endpoint does with the request, we may want to retrieve the body of a POST
request either for logging or further processing.
The @RequestBody
annotation allows us to retrieve the request's body. We can then return it as a String or deserialize it into a Plain Old Java Object (POJO).
Spring has built-in mechanisms for deserializing JSON and XML objects into POJOs, which makes this task a lot easier as well.
In this article, we'll get the body of a POST
HTTP request and pack it into a String, as well as deserialize it into a POJO.
Getting HTTP POST Body as a String
Let's start out with a @Controller
class to handle an incoming request:
@ResponseBody
@Controller
@RequestMapping("/response")
public class HomeController {}
What's worth noting here is that we've added the @ResponseBody
annotation to the @Controller
. This way, it won't render a template as the response body, but rather, will return a response body. Specifically, we'll pack it in a String and return that.
Spring Boot introduced us to another derived type - @RestController
which is just a combination of the previous two annotations. Let's use that instead for brevity:
@RestController
@RequestMapping("/response")
public class HomeController {}
Now, let's go ahead and define a request handler. Since we're handling a POST
request, we'll use the @PostMapping
annotation for it:
@RestController
@RequestMapping("/response")
public class HomeController {
@PostMapping("/postbody")
public String postBody(@RequestBody String fullName) {
return "Hello " + fullName;
}
}
To retrieve the body of the POST
request sent to the handler, we'll use the @RequestBody
annotation, and assign its value to a String. This takes the body of the request and neatly packs it into our fullName
String. We've then returned this name back, with a greeting message.
Let's test this controller out via curl
:
curl -X POST -H "Content-type: application/json" -d "John Smith" "http://localhost:8080/response/postbody"
This results in:
Hello John Smith
Deserialize HTTP POST into POJO
Now, typically, we won't be working with Strings, although they serve as a good example for learning. In most cases, we'll want to do some processing, or at the least, serialize the request into a POJO. Let's define a Person
POJO with a firstName
and lastName
:
public class Person {
private String firstName;
private String lastName;
// Constructor, getters and setters
}
We'll perform the same process as in the previous example - with the same controller. However, this time, we'll specify that the controller is accepting JSON and XML values and that it produces JSON or XML responses back.
We'll retrieve a POST
request body in JSON format, deserialize it into a POJO for further processing (saving into a database, for example) and return a JSON response.
Although Spring Boot can automatically match the JSON body to our POJO, given the variable names match, we'll explicitly set this option. We'll set the input and output formats using the consumes
and produces
flags in the @PostMapping
:
@RestController
@RequestMapping("/response")
public class HomeController {
@PostMapping(
value = "/postbody",
consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE},
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<Person> postBody(@RequestBody Person person) {
Person persistedPerson = personService.save(person);
return ResponseEntity
.created(URI
.create(String.format("/persons/%s", person.getFirstName())))
.body(persistedPerson);
}
}
Here, we're accepting JSON and XML, as well as producing it back. We've annotated the Person
instance as the @RequestBody
, which we'll also be expecting from the request. Then, we've used a PersonService
instance to save the person to a database, which also returns the persisted object for further processing.
For brevity's sake, we've omitted the PersonService
implementation as it's a standard service-layer implementation.
Finally, we've returned a ResponseEntity
object. It's just an extension of the HttpEntity
class that also has a status code. We've set the status code as CREATED
with a URI
location where the new created resource is located. Then, we've set the body of the ResponseEntity
as the persistentPerson
instance and built the response.
Let's test this controller out via curl
again:
curl -X POST -H "Content-type: application/json" -d "{\"firstName\" : \"John\", \"lastName\" : \"Smith\"}" "http://localhost:8080/response/postbody"
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
Here, we've made a POST
request with a JSON body, containing the first and last name of a person and sent it to our endpoint. Jackson kicks off the deserialization process and maps the incoming JSON to our POJO:
The endpoint, after saving the Person
entity, responds with:
{"firstName":"John","lastName":"Smith"}
Conclusion
In this tutorial, we've covered two ways to capture a POST
HTTP request's body in a Spring Boot controller.
Using the @RequestBody
annotation, we've mapped the body to a String and returned it. Afterwards, we've defined a POJO to deserialize incoming JSON contents into, processed it and finally returned a ResponseEntity
.