I am using Jersey client for REST calls from Java code:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.22.1</version>
</dependency>
In my GET request,
javax.ws.rs.client.Invocation.Builder builder = ClientBuilder.newClient().target(url).request();
builder.get().readEntity(String.class);
the client will be closed automatically after calling readEntity(String.class).
If I use,
builder.get(String.class);
I get the same output.
Is the connection closed automatically or do I need to close it manually in this case?
Consider the following code:
Client client = ClientBuilder.newClient();
String result = client.target(url).request().get(String.class);
Under the hood, Jersey invokes Response#readEntity(Class<T>) if the request has succeeded and the connection will be closed for you. So the connection doesn't need to be closed manually in this situation.
Now consider the following code:
Client client = ClientBuilder.newClient();
Response response = client.target(url).request().get();
For this situation, you need to invoke Response#close() to close the connection. Or invoke Response#readEntity(Class<T>) to make Jersey close the connection for you.
As stated in the documentation, if you don't read the entity, then you need to close the response manually by invoking Response#close().
For more details, have a look at Jersey's documentation about how to close connections:
5.7. Closing connections
The underlying connections are opened for each request and closed after the response is received and entity is processed (entity is read). See the following example:
final WebTarget target = ... some web target Response response = target.path("resource").request().get(); System.out.println("Connection is still open."); System.out.println("string response: " + response.readEntity(String.class)); System.out.println("Now the connection is closed.");If you don't read the entity, then you need to close the response manually by
response.close().Also if the entity is read into an
InputStream(byresponse.readEntity(InputStream.class)), the connection stays open until you finish reading from theInputStream. In that case, theInputStreamor theResponseshould be closed manually at the end of reading fromInputStream.
Additionally, have a look at JerseyInvocation source. The most important parts are quoted below.
In the translate(ClientResponse, RequestScope, Class<T>) method you'll see that response.readEntity(Class<T>) is invoked.
JerseyInvocation.Builder#get(Class<T>)Invoke HTTP GET method for the current request synchronously.
@Override
public <T> T get(final Class<T> responseType)
throws ProcessingException, WebApplicationException {
return method("GET", responseType);
}
JerseyInvocation.Builder#method(String, Class<T>)Invoke an arbitrary method for the current request synchronously.
@Override
public <T> T method(final String name, final Class<T> responseType)
throws ProcessingException, WebApplicationException {
// responseType null check omitted for brevity
requestContext.setMethod(name);
return new JerseyInvocation(this).invoke(responseType);
}
JerseyInvocation#invoke(Class<T>)Synchronously invoke the request and receive a response of the specified type back.
@Override
public <T> T invoke(final Class<T> responseType)
throws ProcessingException, WebApplicationException {
// responseType null check omitted for brevity
final ClientRuntime runtime = request().getClientRuntime();
final RequestScope requestScope = runtime.getRequestScope();
return requestScope.runInScope(new Producer<T>() {
@Override
public T call() throws ProcessingException {
try {
return translate(runtime.invoke(requestForCall(requestContext)),
requestScope, responseType);
} catch (final ProcessingException ex) {
// Exception handling omitted for brevity
}
}
});
}
JerseyInvocation#translate(ClientResponse, RequestScope, Class<T>)If the request suceeded, the response entity is read as an instance of specified Java type using Response#readEntity(Class<T>):
private <T> T translate(final ClientResponse response, final RequestScope scope,
final Class<T> responseType) throws ProcessingException {
if (responseType == Response.class) {
return responseType.cast(new InboundJaxrsResponse(response, scope));
}
if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) {
try {
return response.readEntity(responseType);
} catch (final ProcessingException ex) {
// Exception handling omitted for brevity
}
} else {
throw convertToException(new InboundJaxrsResponse(response, scope));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With