我使用Jersey客户端从Java代码进行REST调用:
<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);
我得到相同的输出。
连接是自动关闭还是我需要手动关闭它?
答案 0 :(得分:17)
请考虑以下代码:
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>)
让泽西岛为您关闭连接。
正如documentation中所述,如果您不是read the entity,则需要通过调用Response#close()
手动关闭响应。
有关详细信息,请查看泽西岛documentation关于如何关闭连接的信息:
为每个请求打开基础连接并关闭 收到响应并处理实体后(实体是 读)。请参阅以下示例:
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>)
被调用。
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>)
如果请求成功,则使用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));
}
}