使用Jersey Client 2.22.1关闭GET请求中的连接

dev*_*v ツ 8 jersey jersey-client jersey-2.0

我使用Jersey客户端从Java代码进行REST调用:

<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>2.22.1</version>
</dependency> 
Run Code Online (Sandbox Code Playgroud)

在我的GET请求中,

javax.ws.rs.client.Invocation.Builder builder = ClientBuilder.newClient().target(url).request(); 
builder.get().readEntity(String.class);
Run Code Online (Sandbox Code Playgroud)

客户将在致电后自动关闭readEntity(String.class).

如果我用,

builder.get(String.class);  
Run Code Online (Sandbox Code Playgroud)

我得到相同的输出.

连接是自动关闭还是我需要在这种情况下手动关闭它?

cas*_*lin 19

简短的回答

请考虑以下代码:

Client client = ClientBuilder.newClient();
String result = client.target(url).request().get(String.class);
Run Code Online (Sandbox Code Playgroud)

在引擎盖下,Response#readEntity(Class<T>)如果请求成功并且连接将为您关闭,则Jersey会调用.因此,在这种情况下不需要手动关闭连接.

现在考虑以下代码:

Client client = ClientBuilder.newClient();
Response response = client.target(url).request().get();
Run Code Online (Sandbox Code Playgroud)

对于这种情况,您需要调用Response#close()以关闭连接.或者调用Response#readEntity(Class<T>)以使Jersey为您关闭连接.

答案很长

文档中所述,如果您不读取实体,则需要通过调用手动关闭响应Response#close().

有关更多详细信息,请查看Jersey 有关如何关闭连接的文档:

5.7.关闭连接

为每个请求打开基础连接,并在收到响应并处理实体(读取实体)后关闭.请参阅以下示例:

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.");
Run Code Online (Sandbox Code Playgroud)

如果您没有读取实体,则需要手动关闭响应response.close().

此外,如果实体被读入 InputStream(by response.readEntity(InputStream.class)),则连接保持打开状态,直到您完成读取InputStream.在这种情况下,应该在读取结束时手动关闭InputStreamResponse关闭InputStream.

另外,看看JerseyInvocation来源.最重要的部分引用如下.

translate(ClientResponse, RequestScope, Class<T>)方法中,您将看到response.readEntity(Class<T>)被调用.

JerseyInvocation.Builder#get(Class<T>)

GET同步调用当前请求的HTTP 方法.

@Override
public <T> T get(final Class<T> responseType)
    throws ProcessingException, WebApplicationException {

    return method("GET", responseType);
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

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
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

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));
    }
}
Run Code Online (Sandbox Code Playgroud)