使用Jersey Client 2.22.1在GET请求中关闭连接 [英] Closing connection in GET request using Jersey Client 2.22.1
问题描述
我正在使用Jersey客户端进行来自Java代码的REST调用:
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>
在我的GET请求中,
javax.ws.rs.client.Invocation.Builder builder = ClientBuilder.newClient().target(url).request();
builder.get().readEntity(String.class);
调用readEntity(String.class)
后,客户端将自动关闭.
the client will be closed automatically after calling readEntity(String.class)
.
如果我使用
builder.get(String.class);
我得到相同的输出.
在这种情况下,连接是自动关闭还是需要手动关闭?
Is the connection closed automatically or do I need to close it manually in this case?
推荐答案
简短答案
考虑以下代码:
Short answer
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.
现在考虑以下代码:
Client client = ClientBuilder.newClient();
Response response = client.target(url).request().get();
对于这种情况,您需要调用 Response#close()
关闭连接.或调用 Response#readEntity(Class<T>)
使Jersey可以为您关闭连接.
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.
文档中所述,如果您不a href ="https://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Response.html#readEntity-java.lang.Class-" rel ="noreferrer">读取实体,那么您需要通过调用
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:
为每个请求打开并关闭基础连接 在收到响应并处理实体之后(实体为 读).请参见以下示例:
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.");
如果您不阅读实体,则需要关闭响应
由 response.close()
一个>.
If you don't read the entity, then you need to close the response
manually by response.close()
.
如果将实体读入
InputStream
(通过response.readEntity(InputStream.class)
) , 这
连接保持打开状态,直到您从 InputStream
.
在这种情况下, InputStream
或 Response
应该关闭
从 InputStream
.
Also if the entity is read into an
InputStream
(by response.readEntity(InputStream.class)
), the
connection stays open until you finish reading from the InputStream
.
In that case, the InputStream
or the Response
should be closed
manually at the end of reading from InputStream
.
Additionally, have a look at JerseyInvocation
source. The most important parts are quoted below.
在translate(ClientResponse, RequestScope, Class<T>)
方法中,您将看到response.readEntity(Class<T>)
被调用.
In the translate(ClientResponse, RequestScope, Class<T>)
method you'll see that response.readEntity(Class<T>)
is invoked.
为当前请求同步调用HTTP GET
方法.
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>)
同步调用请求并收到指定类型的响应.
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>)
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));
}
}
这篇关于使用Jersey Client 2.22.1在GET请求中关闭连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
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>)
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>)
JerseyInvocation#translate(ClientResponse, RequestScope, Class<T>)
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));
}
}