'JERSEY : Error Trace : java.lang.IllegalStateException: Entity input stream has already been closed
I am working with Jersey 2.x.
Following is my controller
@GET
@Path("{id}")
@Produces("application/json")
public Response getUser(@PathParam("id") int userId, @Context ContainerRequestContext containerRequestContext) {
ContainerRequestContext requestContext = logRequest(containerRequestContext);
//To further operations using requestContext
}
Following is my method inside the same controller class to record request
private ContainerRequestContext logRequest(ContainerRequestContext requestContext) {
JSONObject requestData = new JSONObject();
try {
Map bm = null;
ContainerRequest cr = (ContainerRequest) requestContext;
cr.bufferEntity();
bm = cr.readEntity(Map.class);
if (!String.valueOf(bm).equalsIgnoreCase("null")) {
requestData.put("parameters", bm.toString());
}
requestData.put("uri", requestContext.getUriInfo().getRequestUri());
requestData.put("ClientIp", requestContext.getProperty("requesterIp"));
requestContext.setProperty("requestData", requestData);
} catch (IOException | NumberFormatException | ProcessingException ex) {
//Logging
} catch (Exception ex) {
//Logging
}
return requestContext;
}
As you can see I am using bufferEntity()
to read ContainerRequestContext multiple times.
Still when I deploy my API on my server.
I am facing this error :
Error Trace : java.lang.IllegalStateException: Entity input stream has already been closed.
What I am doing wrong here. I will be thankful if somebody could explain me this behavior.
Solution 1:[1]
I have had a similar requirement and the way I've worked around this issue was by kind of "cloning" the request entity, with a help of Apache Commons' IOUtils like the code snippet below:
//--- Create a new InputStream with the original entity ---//
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IOUtils.copy(requestContext.getEntityStream(), baos);
InputStream originalEntity = new ByteArrayInputStream(baos.toByteArray()));
//--- Reasign the original entity to Request Context ---//
requestContext.setEntityStream(new ByteArrayInputStream(baos.toByteArray()));
//--- From this point onwards, you can do whatever you want with the original request entity ---//
. . .
//--- In my case, I am working with JsonObject as below (try/catch ommited for brevity) ---//
JsonReader jsonReader = Json.createReader(originalEntity);
JsonObject requestEntity = jsonReader.readObject();
. . .
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Eduardo Ponzoni |