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

时间:2016-02-08 08:52:32

标签: jersey jersey-2.0 jersey-client

我使用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);  

我得到相同的输出。

连接是自动关闭还是我需要手动关闭它?

1 个答案:

答案 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关于如何关闭连接的信息:

  

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()手动完成。

     

此外,如果实体被读入   InputStreamresponse.readEntity(InputStream.class)),{。}   连接保持打开状态,直到您完成InputStream的阅读。   在这种情况下,应关闭InputStreamResponse   在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));
    }
}