1616
1717package org .springframework .ws .transport .http ;
1818
19- import java .io .IOException ;
20- import java .net .URI ;
2119import java .time .Duration ;
2220import java .util .Map ;
2321
2422import org .apache .hc .client5 .http .auth .AuthScope ;
2523import org .apache .hc .client5 .http .auth .Credentials ;
2624import org .apache .hc .client5 .http .classic .HttpClient ;
27- import org .apache .hc .client5 .http .classic .methods .HttpPost ;
28- import org .apache .hc .client5 .http .impl .classic .CloseableHttpClient ;
2925import org .apache .hc .client5 .http .impl .classic .HttpClientBuilder ;
3026import org .apache .hc .client5 .http .impl .io .PoolingHttpClientConnectionManager ;
31- import org .apache .hc .core5 .http .EntityDetails ;
32- import org .apache .hc .core5 .http .HttpException ;
33- import org .apache .hc .core5 .http .HttpHeaders ;
34- import org .apache .hc .core5 .http .HttpHost ;
35- import org .apache .hc .core5 .http .HttpRequest ;
3627import org .apache .hc .core5 .http .HttpRequestInterceptor ;
37- import org .apache .hc .core5 .http .protocol .HttpContext ;
3828
39- import org .springframework .beans .factory .DisposableBean ;
4029import org .springframework .beans .factory .InitializingBean ;
4130import org .springframework .util .Assert ;
42- import org .springframework .ws .transport .WebServiceConnection ;
4331
4432/**
45- * {@code WebServiceMessageSender } implementation that uses
46- * <a href="http://hc.apache.org/httpcomponents-client">Apache HttpClient</a> to execute
47- * POST requests.
33+ * {@code AbstractHttpComponents5MessageSender } implementation that configures the
34+ * underlying <a href="http://hc.apache.org/httpcomponents-client">Apache HttpClient</a>
35+ * that executes POST requests.
4836 * <p>
49- * Allows to use a pre-configured HttpClient instance, potentially with authentication,
50- * HTTP connection pooling, etc. Authentication can also be set by injecting a
51- * {@link Credentials} instance (such as the
52- * {@link org.apache.hc.client5.http.auth.UsernamePasswordCredentials}).
37+ * To specify the {@link HttpClient}, consider using
38+ * {@link SimpleHttpComponents5MessageSender} instead.
5339 *
5440 * @author Alan Stewart
5541 * @author Barry Pitman
5945 * @since 4.0.5
6046 * @see HttpClient
6147 */
62- public class HttpComponents5MessageSender extends AbstractHttpWebServiceMessageSender
63- implements InitializingBean , DisposableBean {
48+ public class HttpComponents5MessageSender extends AbstractHttpComponents5MessageSender implements InitializingBean {
6449
6550 private static final String HTTP_CLIENT_ALREADY_SET = "httpClient already set" ;
6651
@@ -87,40 +72,43 @@ public HttpComponents5MessageSender() {
8772 * {@linkplain HttpClientBuilder#addRequestInterceptorFirst(HttpRequestInterceptor)
8873 * add} the {@link RemoveSoapHeadersInterceptor}.
8974 * @param httpClient the HttpClient instance to use for this sender
75+ * @deprecated as of 4.1.0 in favor of {@link SimpleHttpComponents5MessageSender}
9076 */
77+ @ Deprecated (since = "4.1.0" , forRemoval = true )
9178 public HttpComponents5MessageSender (HttpClient httpClient ) {
9279 this ();
9380 Assert .notNull (httpClient , "httpClient must not be null" );
9481 this .httpClient = httpClient ;
9582 }
9683
97- /*
98- * * @see HttpComponents5ClientFactory#setAuthScope(AuthScope)
84+ @ Override
85+ public HttpClient getHttpClient () {
86+ return this .httpClient ;
87+ }
88+
89+ /**
90+ * Set the authentication scope to be used. Only used when the {@code credentials}
91+ * property has been set.
92+ * @see HttpComponents5ClientFactory#setAuthScope(AuthScope)
9993 */
10094 public void setAuthScope (AuthScope authScope ) {
101- if (getHttpClient () != null ) {
95+ if (this . httpClient != null ) {
10296 throw new IllegalStateException (HTTP_CLIENT_ALREADY_SET );
10397 }
10498 this .clientFactory .setAuthScope (authScope );
10599 }
106100
107- /*
108- * * @see HttpComponents5ClientFactory#setCredentials(Credentials)
101+ /**
102+ * Set the credentials to be used. If not set, no authentication is done.
103+ * @see HttpComponents5ClientFactory#setCredentials(Credentials)
109104 */
110105 public void setCredentials (Credentials credentials ) {
111- if (getHttpClient () != null ) {
106+ if (this . httpClient != null ) {
112107 throw new IllegalStateException (HTTP_CLIENT_ALREADY_SET );
113108 }
114109 this .clientFactory .setCredentials (credentials );
115110 }
116111
117- /**
118- * Returns the {@code HttpClient} used by this message sender.
119- */
120- public HttpClient getHttpClient () {
121- return this .httpClient ;
122- }
123-
124112 /**
125113 * Set the {@code HttpClient} used by this message sender.
126114 * <p>
@@ -129,7 +117,9 @@ public HttpClient getHttpClient() {
129117 * {@linkplain HttpClientBuilder#addRequestInterceptorFirst(HttpRequestInterceptor)
130118 * add} the {@link RemoveSoapHeadersInterceptor}.
131119 * @param httpClient the HttpClient to use
120+ * @deprecated as of 4.1.0 in favor of {@link SimpleHttpComponents5MessageSender}
132121 */
122+ @ Deprecated (since = "4.1.0" , forRemoval = true )
133123 public void setHttpClient (HttpClient httpClient ) {
134124 this .httpClient = httpClient ;
135125 }
@@ -139,7 +129,7 @@ public void setHttpClient(HttpClient httpClient) {
139129 * @see HttpComponents5ClientFactory#setConnectionTimeout(Duration)
140130 */
141131 public void setConnectionTimeout (Duration timeout ) {
142- if (getHttpClient () != null ) {
132+ if (this . httpClient != null ) {
143133 throw new IllegalStateException (HTTP_CLIENT_ALREADY_SET );
144134 }
145135 this .clientFactory .setConnectionTimeout (timeout );
@@ -150,7 +140,7 @@ public void setConnectionTimeout(Duration timeout) {
150140 * @see HttpComponents5ClientFactory#setReadTimeout(Duration)
151141 */
152142 public void setReadTimeout (Duration timeout ) {
153- if (getHttpClient () != null ) {
143+ if (this . httpClient != null ) {
154144 throw new IllegalStateException (HTTP_CLIENT_ALREADY_SET );
155145 }
156146 this .clientFactory .setReadTimeout (timeout );
@@ -161,7 +151,7 @@ public void setReadTimeout(Duration timeout) {
161151 * @see HttpComponents5ClientFactory#setMaxTotalConnections(int)
162152 */
163153 public void setMaxTotalConnections (int maxTotalConnections ) {
164- if (getHttpClient () != null ) {
154+ if (this . httpClient != null ) {
165155 throw new IllegalStateException (HTTP_CLIENT_ALREADY_SET );
166156 }
167157 this .clientFactory .setMaxTotalConnections (maxTotalConnections );
@@ -172,74 +162,17 @@ public void setMaxTotalConnections(int maxTotalConnections) {
172162 * @see HttpComponents5ClientFactory#setMaxConnectionsPerHost(Map)
173163 */
174164 public void setMaxConnectionsPerHost (Map <String , String > maxConnectionsPerHost ) {
175- if (getHttpClient () != null ) {
165+ if (this . httpClient != null ) {
176166 throw new IllegalStateException (HTTP_CLIENT_ALREADY_SET );
177167 }
178168 this .clientFactory .setMaxConnectionsPerHost (maxConnectionsPerHost );
179169 }
180170
181171 @ Override
182172 public void afterPropertiesSet () throws Exception {
183- if (getHttpClient () == null ) {
173+ if (this . httpClient == null ) {
184174 this .httpClient = this .clientFactory .getObject ();
185175 }
186176 }
187177
188- @ Override
189- public WebServiceConnection createConnection (URI uri ) throws IOException {
190-
191- HttpPost httpPost = new HttpPost (uri );
192-
193- if (isAcceptGzipEncoding ()) {
194- httpPost .addHeader (HttpTransportConstants .HEADER_ACCEPT_ENCODING ,
195- HttpTransportConstants .CONTENT_ENCODING_GZIP );
196- }
197-
198- HttpHost httpHost = HttpHost .create (uri );
199- HttpContext httpContext = createContext (uri );
200-
201- return new HttpComponents5Connection (getHttpClient (), httpHost , httpPost , httpContext );
202- }
203-
204- /**
205- * Template method that allows for creation of an {@link HttpContext} for the given
206- * uri. Default implementation returns {@code null}.
207- * @param uri the URI to create the context for
208- * @return the context, or {@code null}
209- */
210- protected HttpContext createContext (URI uri ) {
211- return null ;
212- }
213-
214- @ Override
215- public void destroy () throws Exception {
216-
217- if (getHttpClient () instanceof CloseableHttpClient client ) {
218- client .close ();
219- }
220- }
221-
222- /**
223- * HttpClient {@link HttpRequestInterceptor} implementation that removes
224- * {@code Content-Length} and {@code Transfer-Encoding} headers from the request.
225- * Necessary, because some SAAJ and other SOAP implementations set these headers
226- * themselves, and HttpClient throws an exception if they have been set.
227- */
228- public static class RemoveSoapHeadersInterceptor implements HttpRequestInterceptor {
229-
230- @ Override
231- public void process (HttpRequest request , EntityDetails entityDetails , HttpContext httpContext )
232- throws HttpException , IOException {
233-
234- if (request .containsHeader (HttpHeaders .TRANSFER_ENCODING )) {
235- request .removeHeaders (HttpHeaders .TRANSFER_ENCODING );
236- }
237-
238- if (request .containsHeader (HttpHeaders .CONTENT_LENGTH )) {
239- request .removeHeaders (HttpHeaders .CONTENT_LENGTH );
240- }
241- }
242-
243- }
244-
245178}
0 commit comments