В данном заметке я напишу о том, как мне удалось заставить работать связку из Spring ws 2.1.0 и http components 4.2.1.
Итак, начну с конфига:
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="messageSenders">
<list>
<ref bean="httpSender" />
</list>
</property>
</bean>
<!-- http sender configuration -->
<bean id="httpSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
<constructor-arg>
<ref bean="httpClient"/>
</constructor-arg>
</bean>
<!-- http client definition -->
<bean id="httpClient" class="ru.chernykh.MyDefaultHttpClient">
<constructor-arg>
<ref bean="connmanager"/>
</constructor-arg>
<property name="params" ref="httpParams" />
</bean>
<!-- http params definition -->
<bean id="httpParams" class="org.apache.http.params.SyncBasicHttpParams"/>
<!-- setup thread-safe connection manager -->
<bean id="connmanager" class="org.apache.http.impl.conn.PoolingClientConnectionManager" destroy-method="shutdown">
<property name="maxTotal" value="100"></property>
<property name="defaultMaxPerRoute" value="100"></property>
</bean>
<!-- connection manager params -->
<bean id="connParams" class="org.apache.http.params.HttpConnectionParamBean">
<constructor-arg>
<ref bean="httpParams"/>
</constructor-arg>
<property name="soTimeout" value="10000"></property>
</bean>
Здесь всё стандартно за исключением бина httpClient. По умолчанию, если мы будем использовать DefaultHttpClient, то получим ошибку исполнения:
"Content-Length header already present". Это означает, что httpclient пытается поставить заголовок в надежде что его нет, но это не так, поэтому получаем исключение.
Класс ru.chernykh.MyDefaultHttpClient выглядит так:
public class MyDefaultHttpClient extends DefaultHttpClient{
protected BasicHttpProcessor createHttpProcessor() {
BasicHttpProcessor processor = super.createHttpProcessor();
processor.addInterceptor(new RemoveHttpHeadersInterceptor(), 0);
return processor;
}
public MyDefaultHttpClient(org.apache.http.impl.conn.PoolingClientConnectionManager connManager){
super(connManager);
}
}
А класс RemoveHttpHeadersInterceptor следующим образом:
public class RemoveHttpHeadersInterceptor implements HttpRequestInterceptor{
public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
if (request instanceof HttpEntityEnclosingRequest) {
if (request.containsHeader(HTTP.TRANSFER_ENCODING)) {
request.removeHeaders(HTTP.TRANSFER_ENCODING);
}
if (request.containsHeader(HTTP.CONTENT_LEN)) {
request.removeHeaders(HTTP.CONTENT_LEN);
}
}
}
}
После этого, клиент заработал, и ошибок не было.
Хочу обратить внимание, что по умолчанию в классе
org.springframework.ws.transport.http.HttpComponentsMessageSender используется deprecated API http components(рекомендую взглянуть в исходниках). Поэтому лучше потратить время на ручную установку параметров httpClient, как это сделал я.
Комментариев нет:
Отправить комментарий