Search code examples
javajerseyjax-rsjersey-client

How to close Response object when we get http body directly in JAX-RS?


When we write REST client with jersey we should close Response like this:

Client c = ClientBuilder.newClient();

Response r = null;
try {
    r = c.target("http://localhost:8080/testrest/customers/854878").request().get();
    Customer cus = r.readEntity(Customer.class);

    /* process result */
} catch (Exception e) {
    /* log here */
    if (r != null) {
        r.close();
    }
}

how should we access Response object when we directly read HTTP body:

Client c = ClientBuilder.newClient();
Customer cus = c.target("http://localhost:8080/testrest/customers/854878").request().get(Customer.class);
/* close Response object and process result */

Solution

  • Assuming you are using Glassfish's jersey-client implementation version 2.3.1 (or check the other versions too), you can follow the calls that get(Class) makes. A little down the line you will find a call to

    org.glassfish.jersey.message.internal.InboundMessageContext#readEntity(Class<T>, Type, Annotation[], PropertiesDelegate)
    

    which, based on some rules, closes the response

    if (!buffered && !(t instanceof Closeable) && !(t instanceof Source)) {
        entityContent.close(); // wrapper to the actual response stream
    }
    

    where t is the object created based on the specified Class object.

    The API itself doesn't seem to say anything about this so an implementation doesn't have to close the underlying response stream. The only thing I could find is from Client javadoc which states

    Client instances must be properly closed before being disposed to avoid leaking resources.

    So do not depend on a specific implementation, make sure to close everything yourself, even if that means you have to break your Fluent method invocations and store intermediate object references in variables.