使用 Jersey Client 2.22.1 关闭 GET 请求中的连接 [英] Closing connection in GET request using Jersey Client 2.22.1

查看:25
本文介绍了使用 Jersey Client 2.22.1 关闭 GET 请求中的连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<依赖><groupId>org.glassfish.jersey.core</groupId><artifactId>jersey-client</artifactId><版本>2.22.1</版本></依赖>

在我的 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);

我得到相同的输出.

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

解决方案

简答

考虑以下代码:

Client client = ClientBuilder.newClient();字符串结果 = client.target(url).request().get(String.class);

在后台,Jersey 调用 Response#readEntity(Class<T>) 如果请求成功并且连接将为您关闭.所以这种情况下不需要手动关闭连接.

现在考虑以下代码:

Client client = ClientBuilder.newClient();响应响应 = client.target(url).request().get();

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

长答案

文档中所述,如果您不这样做读取实体,那么您需要通过调用 Response#close().

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

<块引用>

5.7.关闭连接

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

final WebTarget target = ... 一些网络目标响应 response = target.path("resource").request().get();System.out.println("连接仍然打开.");System.out.println("字符串响应:" + response.readEntity(String.class));System.out.println("现在连接已关闭.");

如果你没有读取实体,那么你需要关闭响应手动通过 response.关闭().

如果实体被读入InputStream (通过 response.readEntity(InputStream.class)),连接保持打开状态,直到您从 InputStream.在这种情况下,InputStreamResponse 应该关闭在阅读结束时手动从 InputStream.

另外,看看 JerseyInvocation 源代码.下面引用了最重要的部分.

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

JerseyInvocation.Builder#get(Class<T>)

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

@Override公共<T>T get(final Class responseType)抛出处理异常,WebApplicationException {返回方法(GET",响应类型);}

JerseyInvocation.Builder#method(String, Class<T>)

为当前请求同步调用任意方法.

@Override公共<T>T 方法(最终字符串名称,最终类 responseType)抛出处理异常,WebApplicationException {//为简洁起见省略了 responseType 空检查requestContext.setMethod(name);return new JerseyInvocation(this).invoke(responseType);}

JerseyInvocation#invoke(Class<T>)

同步调用请求并接收回指定类型的响应.

@Override公共<T>T调用(最终类响应类型)抛出处理异常,WebApplicationException {//为简洁起见省略了 responseType 空检查最终 ClientRuntime 运行时 = request().getClientRuntime();最终 RequestScope requestScope = runtime.getRequestScope();return requestScope.runInScope(new Producer<T>() {@覆盖公共 T 调用()抛出 ProcessingException {尝试 {返回翻译(runtime.invoke(requestForCall(requestContext)),请求范围,响应类型);} 捕捉(最终的 ProcessingException ex){//为简洁起见省略异常处理}}});}

JerseyInvocation#translate(ClientResponse, RequestScope, Class<T>)

如果请求成功,则使用 Response#readEntity(Class<T>):

private <T>T translate(最终的 ClientResponse 响应,最终的 RequestScope 范围,最终类<T>responseType) 抛出 ProcessingException {if (responseType == Response.class) {return responseType.cast(new InboundJaxrsResponse(response, scope));}if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) {尝试 {返回 response.readEntity(responseType);} 捕捉(最终的 ProcessingException ex){//为简洁起见省略异常处理}} 别的 {throw convertToException(new InboundJaxrsResponse(response, scope));}}

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> 

In my GET request,

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

the client will be closed automatically after calling readEntity(String.class).

If I use,

builder.get(String.class);  

I get the same output.

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.

Now consider the following code:

Client client = ClientBuilder.newClient();
Response response = client.target(url).request().get();

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.

Long answer

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:

5.7. Closing 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.");

If you don't read the entity, then you need to close the response manually by response.close().

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.

In the translate(ClientResponse, RequestScope, Class<T>) method you'll see that response.readEntity(Class<T>) is invoked.

JerseyInvocation.Builder#get(Class<T>)

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>)

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>)

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆