JERSEY : Error Trace : java.lang.IllegalStateException: Entity input stream has already been closed

守給你的承諾、 提交于 2019-12-22 10:57:01

问题


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.


回答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();

. . .


来源:https://stackoverflow.com/questions/45585665/jersey-error-trace-java-lang-illegalstateexception-entity-input-stream-has

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!