Решением, которое работало для нас, было создание перехватчика Http, который выполняет сжатие, и предоставление WebServiceTemplate
нового HttpComponentMessageSender
с этим перехватчиком.Вот как выглядит перехватчик:
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.client.entity.GzipCompressingEntity;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import java.net.URI;
import java.net.URISyntaxException;
public class GzipHttpRequestInterceptor implements HttpRequestInterceptor {
private final String targetHost;
public GzipHttpRequestInterceptor(String targetUrl) throws URISyntaxException {
this.targetHost = getDomainName(targetUrl);
}
private String getDomainName(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost() + ":" + uri.getPort();
return domain.startsWith("www.") ? domain.substring(4) : domain;
}
@Override
public void process(HttpRequest httpRequest, HttpContext httpContext) {
final HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) httpRequest;
final HttpEntity entity = entityRequest.getEntity();
if (entity != null) {
final GzipCompressingEntity zippedEntity = new GzipCompressingEntity(entity);
entityRequest.setEntity(zippedEntity);
httpRequest.removeHeaders(HTTP.CONTENT_ENCODING);
httpRequest.addHeader(zippedEntity.getContentEncoding());
httpRequest.removeHeaders(HTTP.CONTENT_LEN);
httpRequest.removeHeaders("Accept");
httpRequest.removeHeaders(HTTP.TRANSFER_ENCODING);
httpRequest.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
httpRequest.addHeader(HTTP.TARGET_HOST, targetHost);
}
}
}
В нашей веб-конфигурации мы собираем компоненты org.apache.http.protocol.HttpProcessor
и org.springframework.ws.transport.http.HttpComponentsMessageSender
:
@Bean
public HttpProcessor httpRequestCompressionProcessor(String url) throws URISyntaxException {
return HttpProcessorBuilder.create()
.add(new GzipHttpRequestInterceptor(url))
.build();
}
@Bean
public HttpComponentsMessageSender messageGzipSender(String url) throws URISyntaxException {
return new HttpComponentsMessageSender(HttpClients.custom()
.addInterceptorFirst(new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor())
.setHttpProcessor(httpRequestCompressionProcessor(url))
.build());
}
И затем назначаем отправителя этого сообщения нашему WebServiceTemplate
с использованием setMessageSender(messageGzipSender(url)
Полагаю, я не возражаю против комментариев к этому коду, если он может быть улучшен и все еще готов услышать, если есть более простой способ.