In this article we will show you how to perform a POST request in Spring using RestTemplate. We will take you through a simple integration test example to be able to test a POST endpoint in a Spring Boot application.
Let’s start!
Setup
For the examples shown throughout this article, we will be using the same codebase we’ve shown in our previous Spring articles. You can see the latest version in our article “Exception Handling in Spring Rest Services in Java”.
In this article will look at our POST endpoint only, and write an integration test for it. Our POST endpoint looks like this:
@PostMapping(consumes = { MediaType.APPLICATION_JSON_VALUE })
ResponseEntity<String> createCustomer(@RequestBody Customer customer, UriComponentsBuilder uriBuilder) {
return repository.create(customer)
.onSuccessDo(e -> ResponseEntity
.created(uriBuilder
.path("/api/customers/{id})")
.buildAndExpand(e.entity().id())
.toUri()
).build()).response();
}
As you can see in this example, we are using a custom Either
monad to handle the responses, but for the purpose of this article you won’t have to worry about implementation details. Integration testing is a kind of black box test, we only care about the response, so the internals of the service should be completely opaque for the purposes of testing.
One more thing you’ll need in your application to be able to test it, is the Spring Boot test dependencies. You can import them by importing the Spring Boot starter test package in your build.gradle
file:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
You will also notice that we are not specifying the version in our dependency import, this is because we have previously defined the Spring Boot version in our plugins
section:
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.6'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
Now that we have the very basics of our Spring Boot application, we can now start with out test. If for any reason you need help to set up your initial application, you can check our article “How to Bootstrap a Spring Boot Application”.
Let’s start looking at our integration test then!
Test Post Request in Spring
There are different ways to test a POST request in Spring, depending on what your needs are. We will start by looking at postForEntity
method, let’s see how it works.
Using PostForEntity method
The postForEntity
method allows us to easily test a POST endpoint in our application by sending a simple POST request in Spring, although it has some limitations. Let’s see how it works:
package com.theboreddev.springbootjava;
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 org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class CustomerControllerIntegrationTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate template;
@Test
public void shouldReturn201ResponseIncludingLocationHeaderAndCreateCustomerInOurDatabase() {
final Customer newCustomer = new Customer(null, "Rowan Atkinson", 52);
final ResponseEntity<String> response = template.postForEntity(String.format("http://localhost:%d/api/customers", port), newCustomer, String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);
assertThat(response.getBody()).isNull();
assertThat(response.getHeaders().getLocation().toString()).isEqualTo(String.format("http://localhost:%d/api/customers/0", port));
}
}
You can see how we use postForEntity
method to send a new customer to the url POST /api/customers
. Once we receive the response, we check that the status code is 201 (CREATED), the body is empty (null) and the location header we receive is correct.
We mentioned before that postForEntity
has some limitations, one of them is the inability to include headers in our request. In cases where we need to pass headers in our integration test, we can use exchange
method present in TestRestTemplate
.
At the moment we support JSON format only, what if we wanted to support a different media type like XML? How would our POST request in Spring look like?

Using Exchange Method
To be able to understand how to use this method, we are going to change our example slightly. We are going to modify our POST endpoint so it can consume either JSON or XML.
To achieve this, we’ll just have to add XML to the consumes
argument in our PostMapping
annotation:
@PostMapping(consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
This means that, in order to test both JSON and XML responses, we’ll need to send a Content-Type
header in our test. Our existing test won’t need to change, as the default format will be JSON if we don’t specify a Content-Type
header in our test. Let’s see how can we send XML then!
@Test
public void shouldReturn201ResponseIncludingLocationHeaderAndCreateCustomerSentInXMLFormat() {
final HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_XML_VALUE);
final Customer newCustomer = new Customer(null, "Rowan Atkinson", 52);
final ResponseEntity<Customer> response = template.exchange(
String.format("http://localhost:%d/api/customers", port),
HttpMethod.POST,
new HttpEntity<>(newCustomer, headers),
Customer.class
);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);
assertThat(response.getBody()).isNull();
assertThat(response.getHeaders().getLocation().toString()).isEqualTo(String.format("http://localhost:%d/api/customers/0", port));
}
You can notice how now we’re using exchange
method in our test. To make it work it was very simple, we just need to send Content-Type: application/xml
and add the media type to our controller, as we saw earlier.
This is very straightforward, isn’t it?
If you are interested in learning Spring in depth, we highly recommend the following books:
Conclusion
in this article we’ve learned the two ways we have to write a simple integration test for a POST request in Spring Boot. We’ve also seen how to support two different content types in our endpoints in a very easy manner.
This is all from us today! We hope you’ve found this article useful and easy to read.
Looking forward to seeing you with us very soon again! Please follow us if you want to subscribe to more of our content!
Thanks for reading us!
You must log in to post a comment.