Read response body in JAX-RS client from a post request
Asked Answered
M

7

102

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?

Metrology answered 6/8, 2013 at 17:24 Comment(1)
We had to change it to: String output = response.readEntity(String.class); To make it work. Thanks a lot!Metrology
B
219

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);
Belding answered 6/8, 2013 at 17:26 Comment(4)
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);Endoderm
This does not work for jaxrs-ri-2.16, here you get org.glassfish.jersey.client.HttpUrlConnector$2@1255b1d1 as output.Vedavedalia
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.Unkenned
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.Turpentine
V
23

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

String output = response.readEntity(String.class)

this delivers the content as expected.

Vedavedalia answered 27/2, 2015 at 10:9 Comment(3)
Jersey developers drive me crazy. Every version methods naming and/or the whole workflow changes drastically. It's like playing Miner game. Find all mines from scratch.Bevash
Don't you like Agility? :)Reef
@Reef I think he likes backward compatibility :)Spang
G
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();
Gingerly answered 5/8, 2016 at 21:22 Comment(2)
getEntity won't automatically read any backing InputStream, so be careful.Sibeal
this solves it when Respose is hand-created in unit testsSogdian
P
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!

Posterior answered 20/10, 2017 at 14:40 Comment(1)
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.Thesda
D
1

Kotlin

The same version of the answer using Kotlin

(response.entity as InputStream).bufferedReader().use { it.readText() }
Dugas answered 25/4, 2023 at 5:4 Comment(0)
H
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

Hallo answered 1/4, 2019 at 14:48 Comment(0)
H
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

Hallo answered 1/4, 2019 at 17:31 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.