97

Having some sort of proxy between a mobile app and a web-service, we are puzzled by the response when issuing a post request. We receive response with status 200: OK. But we can not find/extract the JSON response body.

    Client client = ClientBuilder.newClient();
    WebTarget webTarget = client.target(WEBSERVICE_BASE_LOCATION + "mobileDevices?operatorCode=KPNSCP");
    String jsonString = "{\"osVersion\":\"4.1\",\"apiLevel\":16,\"devicePlatform\":\"ANDROID\"}";
    Builder builder = webTarget.request();
    Response response = builder.post(Entity.json(jsonString));

We are using JAX-RS. Can someone please provide some hints to extract the JSON body (String) from the server response?

Jens Piegsa
  • 7,399
  • 5
  • 58
  • 106
user2657714
  • 1,134
  • 1
  • 8
  • 7

7 Answers7

215

Try this:

String output = response.getEntity(String.class);

EDIT

Thanks to @Martin Spamer to mention that it will work for Jersey 1.x jars only. For Jersey 2.x use

String output = response.readEntity(String.class);
Moha the almighty camel
  • 4,327
  • 4
  • 30
  • 53
Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
  • 50
    This will only work with Jax 1.x, from Jersey: 2.x onward which the OP is using (We can tell from his use of ClientBuilder.newClient();). The response is `response.readEntity(String.class);` – Martin Spamer Jun 18 '14 at 15:04
  • 3
    This does not work for jaxrs-ri-2.16, here you get ```org.glassfish.jersey.client.HttpUrlConnector$2@1255b1d1``` as output. – col.panic Feb 27 '15 at 10:04
  • thanks, I got stuck into this for long time as I was using getEntity() to read response message body. getEntity() works only with Jersey 1.x and Jersey 2.0 has support for response.readEntity() to get response message body. – spectre007 May 22 '16 at 05:17
  • Note that if you get a `com.owlike.genson.stream.JsonStreamException: Readen value can not be converted to String`, you'll need to read the response stream manually to get the JSON String. That happened for me with Jersey 1.19. – dvlcube Mar 03 '20 at 04:46
22

I just found a solution for jaxrs-ri-2.16 - simply use

String output = response.readEntity(String.class)

this delivers the content as expected.

col.panic
  • 2,944
  • 4
  • 25
  • 31
16

For my use case, none of the previous answers worked because I was writing a server-side unit test which was failing due the following error message as described in the Unable to Mock Glassfish Jersey Client Response Object question:

java.lang.IllegalStateException: Method not supported on an outbound message.
at org.glassfish.jersey.message.internal.OutboundJaxrsResponse.readEntity(OutboundJaxrsResponse.java:145)
at ...

This exception occurred on the following line of code:

String actJsonBody = actResponse.readEntity(String.class);

The fix was to turn the problem line of code into:

String actJsonBody = (String) actResponse.getEntity();
Community
  • 1
  • 1
entpnerd
  • 10,049
  • 8
  • 47
  • 68
4

I also had the same issue, trying to run a unit test calling code that uses readEntity. Can't use getEntity in production code because that just returns a ByteInputStream and not the content of the body and there is no way I am adding production code that is hit only in unit tests.

My solution was to create a response and then use a Mockito spy to mock out the readEntity method:

Response error = Response.serverError().build();
Response mockResponse = spy(error);
doReturn("{jsonbody}").when(mockResponse).readEntity(String.class);

Note that you can't use the when(mockResponse.readEntity(String.class) option because that throws the same IllegalStateException.

Hope this helps!

Cheefachi
  • 105
  • 7
  • 3
    Thank you! You're probably the first person to actually understand the OP's question. For all you other first-responders out there: no one cares how smart you are. They want to fix their problem. They're not interested in why jersey doesn't let you call readResponse in a unit test. – John Calcote May 04 '19 at 04:26
1

Kotlin

The same version of the answer using Kotlin

(response.entity as InputStream).bufferedReader().use { it.readText() }
James Roland
  • 8,183
  • 4
  • 30
  • 16
0

Acording with the documentation, the method getEntity in Jax rs 2.0 return a InputStream. If you need to convert to InputStream to String with JSON format, you need to cast the two formats. For example in my case, I implemented the next method:

    private String processResponse(Response response) {
    if (response.getEntity() != null) {
        try {
            InputStream salida = (InputStream) response.getEntity();
            StringWriter writer = new StringWriter();
            IOUtils.copy(salida, writer, "UTF-8");
            return writer.toString();
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
    }
    return null;
}

why I implemented this method. Because a read in differets blogs that many developers they have the same problem whit the version in jaxrs using the next methods

String output = response.readEntity(String.class)

and

String output = response.getEntity(String.class)

The first works using jersey-client from com.sun.jersey library and the second found using the jersey-client from org.glassfish.jersey.core.

This is the error that was being presented to me: org.glassfish.jersey.client.internal.HttpUrlConnector$2 cannot be cast to java.lang.String

I use the following maven dependency:

<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>

What I do not know is why the readEntity method does not work.I hope you can use the solution.

Carlos Cepeda

0

Realizing the revision of the code I found the cause of why the reading method did not work for me. The problem was that one of the dependencies that my project used jersey 1.x. Update the version, adjust the client and it works.

I use the following maven dependency:

<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>

Regards

Carlos Cepeda