Setting request timeout for JAX-RS 2.0 Client API

2019-01-11 17:48发布

问题:

I have written simple REST web service client class which uses the JAX-RS 2.0 client API to make REST requests. I am trying to figure out how to set a request timeout for each invocation. Here is the code for a request:

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

回答1:

You can do this by creating a ClientConfig first and providing it as an argument when creating the new client.

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


回答2:

With Resteasy this can be accomplished by building your Client as such.

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

I have not seen a list of standard configuration properties you could set via ClientBuilder.newClient(Configuration configuration) which would be needed to make this portable.



回答3:

Note: this is a new method available on JAX-RS 2.1

This is a very old post but the below code will work for both jersey and resteasy.

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


回答4:

First, you have to add relevant dependencies (here is for the 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>

Next - create a normal Apache HttpClient and push it the RestEasy Enginge with overriding one method, which causes the problem:

// 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();

Have a look at https://issues.jboss.org/browse/RESTEASY-975 Seems, that the problem was just resolved in the version 3.1.0.Final.



回答5:

For people stuck with older JAX-RS 2.0 API and old Resteasy implementation, you may use this method:

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

Despite the name, socketTimeout stands for "read timeout", since by the docs, it stands for "The timeout for waiting for data".



标签: java rest jax-rs