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?
The documentation seems pretty clear to me: "Base implementation of HttpClient that also implements Closeable" - HttpClient is an interface; CloseableHttpClient is an abstract class, but because it implements AutoCloseable you can use it in a try-with-resources statement.
Create instance of CloseableHttpClient using helper class HttpClients . Create HttpGet or HttpPost instance based on the HTTP request type. Use addHeader method to add required headers such as User-Agent, Accept-Encoding etc. For POST, create list of NameValuePair and add all the form parameters.
[Closeable]HttpClient implementations are expected to be thread safe. It is recommended that the same instance of this class is reused for multiple request executions.
Class HttpComponentsClientHttpRequestFactory. ClientHttpRequestFactory implementation that uses Apache HttpComponents HttpClient to create requests. Allows to use a pre-configured HttpClient instance - potentially with authentication, HTTP connection pooling, etc.
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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With