Unable to read application/json message in Response output
Asked Answered
B

4

11

I'm testing REST API and while I make GET call to retrieve resources, it's resulting into 500 Internal Server Error and in output it's returning message which has media type application/json:

[
  {
    "messageType": "Some error type",
    "messageText": "Some message text",
    "moreInfo": "Some info"
  }
]

Please make note that in above output, Json is inside []

I want to read value of messageText from above output response. I tried with -

JsonObject jsonObject = response.readEntity(JsonObject.class);

but it results in following error:

java.lang.IllegalStateException: Entity input stream has already been closed.
    at org.glassfish.jersey.message.internal.EntityInputStream.ensureNotClosed(EntityInputStream.java:225)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:830)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:783)
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
    at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:111)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:399)
    at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:108)

Could you please help me how can I read the message in output? I'm using Jersy library.

Bubbler answered 28/9, 2015 at 12:52 Comment(3)
Can you please provide some additional code. As the message suggests, it seems that the input stream has already been closed at some previous point and it cannot be read from any more.Disembodied
@peeskillet, I'm automating this test not checking manually. I can see this manually in POSTMAN google chrome plugin for REST API testing.Bubbler
Hard to tell without something reproducible. I would check out Jersey Test Framework. Putting something reproducible all into one class is the best MCVE you can make when dealing with Jersey. I highly recommend doing this for better help. You might even figure out the problem yourself while breaking it down.Encompass
S
20

According to javaDoc, a call to readEntity closes the response entity, so when you make another readEntity call you get IllegalStateException.

Unless the supplied entity type is an input stream, this method automatically closes the an unconsumed original response entity data stream if open.

In my case, having the expression response.readEntity(String.class) in the Expressions pane in the Debug perspective caused this exception when I ran the code in Debug mode. The evaluation of the expression consumed the entity and caused it to close.

Samadhi answered 25/8, 2016 at 17:11 Comment(4)
Scratched my head for a while on this one :DElongate
You can use response.bufferEntity() if you want to call readEntity(...) multiple timesDorkus
I am using bufferEntity() but still facing this issue. #45586165Barnsley
doing response.bufferEntity() before the readEntity() worked well!Ectropion
A
3

I solved this by first doing the readEntity to a String entity and then using the Jackson ObjectMapper to actually deserialize to the target class.

Problematic code:

Transactions transObj = response.readEntity(Transactions.class);

Solution:

String stringEntity = response.readEntity(String.class);
Transactions transObj  = objectMapper.readValue(stringEntity, Transactions.class);

It seems this problem arises when the JSON string in the response entity stream is very long or complex possibly requiring multiple interactions thereon. 'Deserializing' to a string seems to only require a single bite. Once you have the string (and Jackson or GSON) de-serialization to target entity takes place without touching the response.

Anchorage answered 20/8, 2018 at 7:42 Comment(1)
Thanks a lot! Debugging 3h without any trace till i read your post. Anyone having UnsupportedOperationException by reading javax.ws.rs.core.response doing this: var entity = response.readEntity(JsonObject.class); This is what has helped me: String entityString = response.readEntity(String.class); JsonReader jsonReader = Json.createReader(new StringReader(entityString)); JsonObject entity = jsonReader.readObject();Laminar
A
2

Actually it is a issue with how are we defining the reference of Response object . Solution is weird

Not Working one :

Response response;
if (condition) {
    response = 
} else {
    response = 
}
String resp = response.readEntity(String.class);
    if (response.getStatus() == 200) {}

Working One

Response response = null;
if (condition) {
    response = 
} else {
    response = 
}
String resp = response.readEntity(String.class);
if (response.getStatus() == 200) {}

So basically if we wont assign anything to response initially , Stream will be closed

Advisee answered 6/3, 2020 at 14:33 Comment(0)
T
0

When you get your error 500 you probably get another exception in the console/log. You should start checking that and then trying to resolve this one. If you don't find anything in the log, could you please post more code?

Terpstra answered 28/9, 2015 at 13:4 Comment(2)
I'm automating this test not checking manually. I can see this manually in POSTMAN - google chrome plugin for REST API testing.Bubbler
Ok, sorry I didn't get it. Actually as you said, the problem is probably because the JSON you are receiving is not actual JSON as it doesn't start with {. Which server are you using?Terpstra

© 2022 - 2024 — McMap. All rights reserved.