Spring Boot RestTemplate: test GET request with JSON body is not working
I’m building a test for a Spring GET controller. The endpoint accepts a JSON body to avoid a list of parameters (i.e. query parameters).
When I try to build the test in Spring I get this error:
HttpMessageNotReadableException: Required request body is missing
This example code should give you an idea of the original issue:
The exchange
method throws an error and return 400 BAD_REQUEST
.
The GET Spring Boot mapping is nothing complicated:
This example simply accepts a JSON that contains 2 values and returns the result of a mathematical operation.
If I call the method from an external application
I receive an HTTP 200 answer with the correct answer.
Even more interesting if I change the @GetMapping
in @PostMapping
and in the test I call use HttpMethod.POST
in place of HttpMethod.GET
creating a POST request ... everything works correctly.
Origin of the issue
The problem is probably originated from the HTTP/1.1 specification that allows the servers to reject the payload in the GET request messages because it has no defined semantic.
In Spring when you use the RestTemplate
in your test a default HttpURLConnection
is prepared in SimpleClientHttpRequestFactory
and the GET
method set the doOutput
flag to false.
The doOutput
according to the Spring documentation:
A URL connection can be used for input and/or output. Set the doOutput flag to true if you intend to use the URL connection for output, false if not. The default is false.
This flag is used during the test by SimpleBufferingClientHttpRequest
that build the Http answer.
In it’s method executeInternal
The output of the connection is skipped and a 400 response code is returned directly (no-output scenario).
As a developer, if you have to test a GET message you can use an alternative to RestTemplate
(e.g. @MockMVC
a post will follow) or build your own RequestFactory
as shown in this post on StackOverflow