Add setConnectTimeout and setReadTimeout methods in RestTemplateBuilder #6346

Closed
yanglifan opened this Issue Jul 7, 2016 · 2 comments

Comments

Projects
None yet
4 participants
@yanglifan

I noticed that Spring Boot 1.4.0 brought in a great tool - RestTemplateBuilder. It provide lots of methods which help to customize RestTemplate. But I hope that RestTemplateBuilder could have methods to customize timeout values for RestTemplate, like the connect timeout and read timeout. Since these configurations are very helpful to keep the thread invoke RestTemplate from being hung up by IO timeout for a long time.

Of course, via ClientHttpRequestFactory implementations, these timeouts can be configured. But let RestTemplateBuilder has this ability can make this work to be simplified and standardized.

Before Spring Boot 1.4.0, I created my own RestTemplateBuilder. It has abilities to configure such as the connect timeout and the read timeout. The usage is like following:

RestTemplateBuilder.create()
            .withClientKey("myRestTemplate")
            .implementation(HttpClientImplementation.OK_HTTP)
            .clearMessageConverters()
            .setMessageConverter(new MappingJackson2HttpMessageConverter(), MediaType.TEXT_PLAIN)
            .enableAutoQueryParams()
            .connectTimeout(100)
            .readTimeout(200)
            .header(HttpHeaders.USER_AGENT, "MyAgent")
            .build();

Methods connectTimeout and readTimeout can set timeout for all ClientHttpRequestFactory implementations provided by spring-web.

@philwebb

This comment has been minimized.

Show comment
Hide comment
@philwebb

philwebb Jul 7, 2016

Member

It's a neat idea, especially if we can find a common set of properties that work across all ClientHttpRequestFactory implementations. Thanks for the suggestion.

Member

philwebb commented Jul 7, 2016

It's a neat idea, especially if we can find a common set of properties that work across all ClientHttpRequestFactory implementations. Thanks for the suggestion.

@philwebb philwebb added this to the 1.4.0 milestone Jul 7, 2016

@yanglifan

This comment has been minimized.

Show comment
Hide comment
@yanglifan

yanglifan Jul 8, 2016

Though in ClientHttpRequestFactory there is no setConnectTimeout and setReadTimeout declaration, but implementations of ClientHttpRequestFactory do have these two methods. So these two properties can be configured via reflection. That is the way my RestTemplateBuilder implemented.

So an implementation of RestTemplateCustomizer can be created to configure the common properties of ClientHttpRequestFactory. The following is the main code:

Class<? extends ClientHttpRequestFactory> factoryClass = clientHttpRequestFactory.getClass();

Method setConnectTimeoutMethod = ReflectionUtils.findMethod(factoryClass,
        SET_CONNECT_TIMEOUT_METHOD_NAME, int.class);
if (setConnectTimeoutMethod != null && connectTimeout != 0) {
    try {
        invokeMethod(setConnectTimeoutMethod, clientHttpRequestFactory, connectTimeout);
    } catch (Exception e) {
        // ClientHttpRequestFactory does not have setConnectTimeout method
        e.printStackTrace();
    }
}

Method setReadTimeoutMethod = ReflectionUtils.findMethod(factoryClass,
        SET_READ_TIMEOUT_METHOD, int.class);
if (setReadTimeoutMethod != null && readTimeout != 0) {
    try {
        invokeMethod(setReadTimeoutMethod, clientHttpRequestFactory, readTimeout);
    } catch (Exception e) {
        // ClientHttpRequestFactory does not have setReadTimeout method
        e.printStackTrace();
    }
}

The full code is here in my fork.

yanglifan commented Jul 8, 2016

Though in ClientHttpRequestFactory there is no setConnectTimeout and setReadTimeout declaration, but implementations of ClientHttpRequestFactory do have these two methods. So these two properties can be configured via reflection. That is the way my RestTemplateBuilder implemented.

So an implementation of RestTemplateCustomizer can be created to configure the common properties of ClientHttpRequestFactory. The following is the main code:

Class<? extends ClientHttpRequestFactory> factoryClass = clientHttpRequestFactory.getClass();

Method setConnectTimeoutMethod = ReflectionUtils.findMethod(factoryClass,
        SET_CONNECT_TIMEOUT_METHOD_NAME, int.class);
if (setConnectTimeoutMethod != null && connectTimeout != 0) {
    try {
        invokeMethod(setConnectTimeoutMethod, clientHttpRequestFactory, connectTimeout);
    } catch (Exception e) {
        // ClientHttpRequestFactory does not have setConnectTimeout method
        e.printStackTrace();
    }
}

Method setReadTimeoutMethod = ReflectionUtils.findMethod(factoryClass,
        SET_READ_TIMEOUT_METHOD, int.class);
if (setReadTimeoutMethod != null && readTimeout != 0) {
    try {
        invokeMethod(setReadTimeoutMethod, clientHttpRequestFactory, readTimeout);
    } catch (Exception e) {
        // ClientHttpRequestFactory does not have setReadTimeout method
        e.printStackTrace();
    }
}

The full code is here in my fork.

@wilkinsona wilkinsona changed the title from Add setConnectTimeout and setRequestTimeout methods in RestTemplateBuilder to Add setConnectTimeout and setReadTimeout methods in RestTemplateBuilder Jul 13, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment