Закрытие соединения в GET-запросе с использованием Jersey Client 2.22.1
Я использую клиент Джерси для вызовов REST из кода Java:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.22.1</version>
</dependency>
В моем запросе GET,
javax.ws.rs.client.Invocation.Builder builder = ClientBuilder.newClient().target(url).request();
builder.get().readEntity(String.class);
клиент будет автоматически закрыт после звонка readEntity(String.class)
,
Если я использую,
builder.get(String.class);
Я получаю такой же вывод.
Соединение закрывается автоматически, или мне нужно закрыть его вручную в этом случае?
1 ответ
Короткий ответ
Рассмотрим следующий код:
Client client = ClientBuilder.newClient();
String result = client.target(url).request().get(String.class);
Под капотом Джерси призывает Response#readEntity(Class<T>)
если запрос был успешным, и соединение будет закрыто для вас. Таким образом, соединение в этом случае не нужно закрывать вручную.
Теперь рассмотрим следующий код:
Client client = ClientBuilder.newClient();
Response response = client.target(url).request().get();
Для этой ситуации вам нужно вызвать Response#close()
закрыть соединение. Или вызвать Response#readEntity(Class<T>)
чтобы Джерси закрыл для вас связь.
Длинный ответ
Как указано в документации, если вы не читаете объект, вам нужно закрыть ответ вручную, вызвав Response#close()
,
Для более подробной информации, посмотрите документацию Джерси о том, как закрыть соединения:
Базовые соединения открываются для каждого запроса и закрываются после получения ответа и обработки объекта (объект считывается). Смотрите следующий пример:
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.");
Если вы не читаете объект, то вам нужно вручную закрыть ответ
response.close()
,Также, если объект читается в
InputStream
(отresponse.readEntity(InputStream.class)
), соединение остается открытым, пока вы не закончите чтение изInputStream
, В этом случаеInputStream
илиResponse
должен быть закрыт вручную в конце чтения изInputStream
,
Кроме того, посмотрите на JerseyInvocation
источник. Наиболее важные части приведены ниже.
в translate(ClientResponse, RequestScope, Class<T>)
метод, который вы увидите, что response.readEntity(Class<T>)
вызывается.
JerseyInvocation.Builder#get(Class<T>)
Вызывать HTTP GET
Метод для текущего запроса синхронно.
@Override
public <T> T get(final Class<T> responseType)
throws ProcessingException, WebApplicationException {
return method("GET", responseType);
}
JerseyInvocation.Builder#method(String, Class<T>)
Вызовите произвольный метод для текущего запроса синхронно.
@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>)
Синхронно вызвать запрос и получить ответ указанного типа обратно.
@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>)
Если запрос выполнен успешно, объект ответа читается как экземпляр указанного типа Java с использованием 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));
}
}