Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a body to a GET request in JAX-RS

Tags:

java

rest

jax-rs

I'm trying to consume a REST API that requires a body with a GET request. But as a GET usually doesn't have a body, I can't find a way to attach a body in my request. I am also building the REST API, but the professor won't allow us to change the method to POST (he gave us a list of the endpoints we are to create, no more, no less).

I'm trying to do it like this:

Response r = target.request().method(method, Entity.text(body));

Where I set the method to GET and the body to my get body. However, using this approach I get an exception:

javax.ws.rs.ProcessingException: RESTEASY004565: A GET request cannot have a body.

Is there any way to do this with JAX-RS? We learned to use JAX-RS so I would prefer a solution using this, as I'm not sure my professor would allow us to use any other REST client. I'm currently using RESTEasy, provided by the WildFly server.

(This is not a duplicate of HTTP GET with request body because I'm asking on how to create a GET request with body in JAX-RS, not if it should be done.)

like image 768
Miguel Almeida Avatar asked Mar 17 '18 19:03

Miguel Almeida


People also ask

Can body be passed in GET request?

So, yes, you can send a body with GET, and no, it is never useful to do so. This is part of the layered design of HTTP/1.1 that will become clear again once the spec is partitioned (work in progress). Yes, you can send a request body with GET but it should not have any meaning.

What is request body in rest?

The request body is used to send and receive data via the REST API. If we are using POST/PUT API, then based on the REST API contract, we should send the whole resource information because these methods work on the whole resource.

Is it possible to make asynchronous requests in JAX-RS?

Out of the box, JAX-RS 2.1 supports a CompletionStage return type. This allows users to string together a chain of stages that can be completed asynchronously.


1 Answers

This depends on what is your JAX-RS implementation. This check can be disabled in Jersey 2.25 using SUPPRESS_HTTP_COMPLIANCE_VALIDATION property:

ClientConfig config = new ClientConfig();
config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
JerseyClient client = JerseyClientBuilder.createClient(config);
WebTarget target = client.target(URI.create("https://www.stackoverflow.com"));
Response response = target.request().method("GET", Entity.text("BODY HERE"));

Instead of exception you will get an INFO log

INFO: Detected non-empty entity on a HTTP GET request. The underlying HTTP transport connector may decide to change the request method to POST.

However in RESTEasy 3.5.0.Final there is a hardcoded check in both URLConnectionEngine and ApacheHttpClient4Engine:

if (request.getEntity() != null)
{
  if (request.getMethod().equals("GET")) throw new ProcessingException(Messages.MESSAGES.getRequestCannotHaveBody());

You would have to create your own implementation of the ClientHttpEngine to skip this. Then you need to supply it when building the client:

ClientHttpEngine engine = new MyEngine();
ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
like image 173
Karol Dowbecki Avatar answered Sep 27 '22 19:09

Karol Dowbecki