0

How to make get with body using rest template?

Based on question from: POST request via RestTemplate in JSON, I tried make GET with body via HttpEntity (just check if it is possible), but it failed receiving:

Required request body is missing

For HttpMethod.POST: localhost:8080/test/post body is added correctly, but for HttpMethod.GET localhost:8080/test/get it is not mapped. My code is, as below:

@RestController
@SpringBootApplication
public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

  private final RestTemplate restTemplate = new RestTemplate();

  @GetMapping("/test/{api}")
  public SomeObject test(@PathVariable("api") String api) {
    String input = "{\"value\":\"ok\"}";

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<String> entity = new HttpEntity<>(input, headers);

    HttpMethod method = "get".equals(api) ? HttpMethod.GET : HttpMethod.POST;
    String url = "http://localhost:8080/" + api;
    return restTemplate.exchange(url, method, entity, SomeObject.class).getBody();
  }

  @GetMapping("/get")
  public SomeObject getTestApi(@RequestBody(required = false) SomeObject someObject) {
    return new SomeObject() {{ setValue(someObject != null ? "ok" : "error"); }};
  }

  @PostMapping("/post")
  public SomeObject postTestApi(@RequestBody(required = false) SomeObject someObject) {
    return new SomeObject() {{ setValue(someObject != null ? "ok" : "error"); }};
  }

  @Data
  public static class SomeObject {
    private String value;
  }

}

Here is the repo with full example: https://gitlab.com/bartekwichowski/git-with-body

I wonder, what is wrong with code? Also accorging to: HTTP GET with request body GET with body is possible, but just not good practice.

Bartek
  • 1,609
  • 2
  • 21
  • 35

2 Answers2

0

i had the same issue with RestTemplate and GET.

Tried to switch to Unirest but that also did not allow to use body with GET method.

Changing GET to POST is successful.

Making a call from postman after deploying in Liberty works fine and body did get accepted and expected response is generated.

i believe its something with the embedded tomcat server used.

boyang
  • 11
  • 3
0

I found this can't remeber where. Not a good practice, but if in your enviroment you have no other chance:

private static final class HttpComponentsClientHttpRequestWithBodyFactory extends HttpComponentsClientHttpRequestFactory {
    @Override
    protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
        if (httpMethod == HttpMethod.GET) {
            return new HttpGetRequestWithEntity(uri);
        }
        return super.createHttpUriRequest(httpMethod, uri);
    }
}

private static final class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
    public HttpGetRequestWithEntity(final URI uri) {
        super.setURI(uri);
    }

    @Override
    public String getMethod() {
        return HttpMethod.GET.name();
    }
}

and when you get your restTemplate object

restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestWithBodyFactory());
demian
  • 502
  • 5
  • 12
  • My guess is from here: https://mekaso.rocks/get-requests-with-a-request-body-spring-resttemplate-vs-apache-httpclient – Ken May 27 '21 at 21:00