简答
考虑以下代码:
Client client = ClientBuilder.newClient();
String result = client.target(url).request().get(String.class);
在后台,如果请求成功,Jersey 会调用Response#readEntity(Class<T>),并且将为您关闭连接。 所以这种情况下不需要手动关闭连接。
现在考虑以下代码:
Client client = ClientBuilder.newClient();
Response response = client.target(url).request().get();
对于这种情况,您需要调用Response#close() 来关闭连接。或者调用 Response#readEntity(Class<T>) 让 Jersey 为你关闭连接。
长答案
如documentation 中所述,如果您不使用read the entity,则需要通过调用Response#close() 手动关闭响应。
更多详情,请查看 Jersey 的 documentation 关于如何关闭连接:
5.7. Closing connections
为每个请求打开和关闭底层连接
收到响应并处理实体后(实体为
读)。请参见以下示例:
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 source。下面引用了最重要的部分。
在translate(ClientResponse, RequestScope, Class<T>) 方法中,您会看到response.readEntity(Class<T>) 被调用。
为当前请求同步调用 HTTP GET 方法。
@Override
public <T> T get(final Class<T> responseType)
throws ProcessingException, WebApplicationException {
return method("GET", responseType);
}
为当前请求同步调用任意方法。
@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);
}
同步调用请求并接收回指定类型的响应。
@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>)
如果请求成功,则使用Response#readEntity(Class<T>)将响应实体作为指定Java类型的实例读取:
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));
}
}