8

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.

Alpha
  • 11,340
  • 19
  • 67
  • 116
  • 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. – Milan Sep 28 '15 at 13:00
  • @peeskillet, I'm automating this test not checking manually. I can see this manually in POSTMAN google chrome plugin for REST API testing. – Alpha Sep 28 '15 at 13:08
  • Hard to tell without something reproducible. I would check out [Jersey Test Framework](https://jersey.java.net/documentation/latest/test-framework.html). Putting something reproducible [all into one class](https://jersey.java.net/documentation/latest/test-framework.html#d0e17076) is the best [MCVE](http://stackoverflow.com/help/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. – Paul Samsotha Sep 28 '15 at 13:15

4 Answers4

17

I am writing automated tests for my Jersey services, which return XML objects, and I was getting this error occasionally too.

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.

Tamara Aviv
  • 825
  • 1
  • 11
  • 26
1

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.

1

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

dan1st
  • 6,537
  • 6
  • 18
  • 44
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?

Aurasphere
  • 3,490
  • 12
  • 37
  • 63
  • I'm automating this test not checking manually. I can see this manually in POSTMAN - google chrome plugin for REST API testing. – Alpha Sep 28 '15 at 13:08
  • 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? – Aurasphere Sep 28 '15 at 13:13