Reputation: 17047
I'd like to have Spring IoC configure a CloseableHttpClient
object and inject it into my class so that customization of its configuration can be done via XML.
From what I can see, HttpClient
seems to resist this pattern quite forcibly. They want you to do things like
CloseableHttpClient chc =
HttpClients.custom().set<thing that should be a property>().build();
Ick.
Is there not some mechanism for making a singleton CloseableHttpClient
bean that I can then use?
Upvotes: 18
Views: 30474
Reputation: 1358
This seems to work for me:
<bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig"
factory-method="custom">
<property name="socketTimeout" value="${socketTimeoutInMillis}" />
<property name="connectTimeout" value="${connectionTimeoutInMillis}" />
</bean>
<bean id="requestConfig" factory-bean="requestConfigBuilder" factory-method="build" />
<bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder"
factory-method="create">
<property name="defaultRequestConfig" ref="requestConfig" />
</bean>
<bean id="httpClient" factory-bean="httpClientBuilder" factory-method="build" />
That gives me a CloseableHttpClient in the "httpClient" bean, with the socket and connection timeouts configured. You should be able to add more properties to either the requestConfigBuilder or the httpClientBuilder.
Upvotes: 44
Reputation: 279870
With Java config, this is as simple as
@Bean
public CloseableHttpClient httpClient() {
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setEverything(everything); // configure it
CloseableHttpClient httpClient = builder.build();
}
With XML config, it's a little more complex. You can create your own FactoryBean
implementation, say CloseableHttpClientFactoryBean
, which delegates all the calls to a HttpClientBuilder
and calls build()
inside getObject()
.
public class CloseableHttpClientFactoryBean implements FactoryBean<CloseableHttpClient> {
private HttpClientBuilder builder;
public CloseableHttpClientFactoryBean() {
builder = HttpClientBuilder.create();
}
... // all the setters
// for example
public void setEverything(Everything everything) {
// delegate
builder.setEverything(everything);
}
public CloseableHttpClient getObject() {
return builder.build();
}
}
And the config
<bean name="httpClient" class="com.spring.http.clients.CloseableHttpClientFactoryBean">
<property name="everything" ref="everything"/>
</bean>
You will need a setter method for each HttpClientBuilder
method.
Note that if you don't need any custom configuration, you can use factory-method
to get a default CloseableHttpClient
<bean name="httpClient" class="org.apache.http.impl.client.HttpClients" factory-method="createDefault" >
</bean>
Upvotes: 9