【问题标题】:Setting request timeout for JAX-RS 2.0 Client API为 JAX-RS 2.0 客户端 API 设置请求超时
【发布时间】:2014-03-26 20:44:17
【问题描述】:

我编写了简单的 REST Web 服务客户端类,它使用 JAX-RS 2.0 客户端 API 来发出 REST 请求。我试图弄清楚如何为每次调用设置请求超时。这是请求的代码:

Client client = ClientBuilder.newBuilder().build();
WebTarget resourceTarget = client.target(restServiceUrl)
        .path("{regsysID}/{appointmentID}/")
        .resolveTemplate("regsysID", regSysId)
        .resolveTemplate("appointmentID", apptId);

Invocation invocation = resourceTarget.request(MediaType.APPLICATION_JSON).buildPut(null);
String createSessionJson = invocation.invoke(String.class);

【问题讨论】:

    标签: java rest jax-rs


    【解决方案1】:

    注意:这是 JAX-RS 2.1 上可用的新方法

    这是一篇很老的帖子,但下面的代码适用于球衣和 resteasy。

    ClientBuilder clientBuilder = ClientBuilder.newBuilder();
    clientBuilder.connectTimeout(10, TimeUnit.SECONDS);
    clientBuilder.readTimeout(12, TimeUnit.SECONDS);
    Client client = clientBuilder.build();
    

    【讨论】:

    • 投反对票是没有根据的。即使问题大约是 2.0,答案仍然很有帮助。在提出问题时,2.0 是最新的。现在 2.1 是最新的、最新的信息。对我投赞成票。
    • 这实际上是唯一不依赖于特定实现的答案。可能其他作者还没有理解 API 和实现之间的区别。
    【解决方案2】:

    您可以通过首先创建一个 ClientConfig 并在创建新客户端时将其作为参数提供来做到这一点。

    import org.glassfish.jersey.client.ClientProperties;
    
    ClientConfig configuration = new ClientConfig();
    configuration.property(ClientProperties.CONNECT_TIMEOUT, 1000);
    configuration.property(ClientProperties.READ_TIMEOUT, 1000);
    Client client = ClientBuilder.newClient(configuration);
    

    【讨论】:

    • 我认为您假设我使用球衣作为 JAXRS 的实现。实际上,我正在使用resteasy。但我想知道是否可以使用纯 JAX RS 2.0 客户端 API 以通用方式进行操作。
    • @Jeroen 你找到一个纯粹的解决方案了吗?我需要这个。
    • 没有通用的 JAX-RS 2.0 方法吗?
    • @icordoba 尝试:client.property(org.apache.cxf.message.Message.CONNECTION_TIMEOUT, 300000) // 5min .property(Message.RECEIVE_TIMEOUT, 300000) // 5min
    • @Custard 的回答效果很好。在此线程中找到该块之前,搜索了许多站点以寻找解决方案。如果你想让它保持“通用”,只需使用字符串常量而不是 cxf 类常量(例如“javax.xml.ws.client.connectionTimeout”、“javax.xml.ws.client.receiveTimeout”)。
    【解决方案3】:

    使用 Resteasy,这可以通过构建您的客户端来实现。

    Client client = new ResteasyClientBuilder()
        .establishConnectionTimeout(2, TimeUnit.SECONDS)
        .socketTimeout(2, TimeUnit.SECONDS)
        .build();
    

    我还没有看到您可以通过ClientBuilder.newClient(Configuration configuration) 设置的标准配置属性列表,这些属性是实现可移植性所必需的。

    【讨论】:

    • 谢谢@codylerum。是的,我认为在 JAX-RS 2.0 ClientBuilder 类中指定此类属性会很好。
    • 小心! 这仅适用于 GET 请求。对于任何其他 - Resteasy->Apache.HttpClient 集成中存在一个问题,它会删除所有客户端配置并用默认值替换它们。
    • @MaximKaravev 有什么方法可以解决你的问题吗?我也需要发帖。
    • @jlanza 我必须向两个库(HTTPClient 和 RestEASY)添加依赖项并覆盖一个方法,这会导致此问题。代码示例见下一条评论
    【解决方案4】:

    首先,您必须添加相关的依赖项(这里是 WildFly 10.1):

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
        <version>3.0.14.Final</version>
        <scope>provided</scope>
    </dependency>
    

    下一步 - 创建一个普通的 Apache HttpClient 并将其推送到 RestEasy Enginge 并覆盖一个方法,这会导致问题:

    // create here a normal Apache HttpClient with all parameters, that you need
    HttpClient httpClient = createHttpClient(connectTimeout,
                                             socketTimeout,
                                             connectionRequestTimeout,
                                             maxTotalHTTPConnections);
    // Deprecated Apache classes cleanup https://issues.jboss.org/browse/RESTEASY-1357
    // Client Framework not honoring connection timeouts Apache Client 4.3 https://issues.jboss.org/browse/RESTEASY-975
    ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient) {
            @Override
            protected void loadHttpMethod(ClientInvocation request, HttpRequestBase httpMethod) throws Exception {
                super.loadHttpMethod(request, httpMethod);
                httpMethod.setParams(new BasicHttpParams());
            }
        };
    
    return new ResteasyClientBuilder().httpEngine(engine).build();
    

    看看https://issues.jboss.org/browse/RESTEASY-975 好像,这个问题刚刚在3.1.0.Final版本中解决了。

    【讨论】:

    • 您能否澄清一下是否已解决意味着这现在适用于 POST 请求?链接线程中的示例使用 GET。
    • 我可以确认此解决方法对于 3.1.0.Final 和 3.0.20.Final 是必要的。
    • 没关系,使用最新版本的 httpclient 它可以在没有解决方法的情况下工作。
    【解决方案5】:

    对于那些被旧的 JAX-RS 2.0 API 和旧的 Resteasy 实现卡住的人,你可以使用这个方法:

    Client client = new ResteasyClientBuilder()             
         .establishConnectionTimeout(3, TimeUnit.SECONDS)
         .socketTimeout(5, TimeUnit.SECONDS).build();
    

    尽管名称如此,socketTimeout 代表“读取超时”,因为根据文档,它代表“等待数据的超时”。

    【讨论】:

      【解决方案6】:

      如果您使用的是 Jersey 2.x,这是对我有用的简单解决方案

      import com.jclient.JClient;
      
      Client c = Client.create();
      WebResource webResource = c.resource("requestUrl");
      c.setConnectTimeout(yourMins*60*1000);
      

      【讨论】:

        猜你喜欢
        • 2019-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-11
        • 2023-03-20
        • 2011-03-09
        相关资源
        最近更新 更多