Skip to content

Commit 86e5d92

Browse files
committed
Polishing.
Related: #1164.
1 parent 05daff5 commit 86e5d92

File tree

4 files changed

+120
-74
lines changed

4 files changed

+120
-74
lines changed

spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpComponents5ClientFactory.java

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
import java.net.URI;
2020
import java.net.URISyntaxException;
21+
import java.time.Duration;
2122
import java.util.Map;
22-
import java.util.concurrent.TimeUnit;
2323

2424
import org.apache.hc.client5.http.HttpRoute;
2525
import org.apache.hc.client5.http.auth.AuthScope;
@@ -31,25 +31,28 @@
3131
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
3232
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
3333
import org.apache.hc.core5.http.HttpHost;
34-
34+
import org.apache.hc.core5.util.Timeout;
3535
import org.springframework.beans.factory.FactoryBean;
3636

3737
/**
38-
* {@code FactoryBean} to set up a <a href="http://hc.apache.org/httpcomponents-client">Apache
39-
* CloseableHttpClient</a>
38+
* {@link FactoryBean} to set up a {@link CloseableHttpClient} using HttpComponents HttpClient 5.
4039
*
40+
* @see http://hc.apache.org/httpcomponents-client
4141
* @author Lars Uffmann
4242
* @since 4.0.5
4343
*/
4444
public class HttpComponents5ClientFactory implements FactoryBean<CloseableHttpClient> {
45-
private static final int DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS = (60 * 1000);
4645

47-
private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS;
48-
private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);
46+
private static final Duration DEFAULT_CONNECTION_TIMEOUT = Duration.ofSeconds(60);
47+
48+
private static final Duration DEFAULT_READ_TIMEOUT = Duration.ofSeconds(60);
49+
50+
private Duration connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
4951

50-
private int readTimeout = DEFAULT_READ_TIMEOUT_MILLISECONDS;
52+
private Duration readTimeout = DEFAULT_READ_TIMEOUT;
5153

5254
private int maxTotalConnections = -1;
55+
5356
private AuthScope authScope = null;
5457

5558
private Credentials credentials = null;
@@ -86,24 +89,28 @@ public void setAuthScope(AuthScope authScope) {
8689
/**
8790
* Sets the timeout until a connection is established. A value of 0 means <em>never</em> timeout.
8891
*
89-
* @param timeout the timeout value in milliseconds
92+
* @param timeout the timeout value
9093
*/
91-
public void setConnectionTimeout(int timeout) {
92-
if (timeout < 0) {
94+
public void setConnectionTimeout(Duration timeout) {
95+
96+
if (timeout.isNegative()) {
9397
throw new IllegalArgumentException("timeout must be a non-negative value");
9498
}
99+
95100
this.connectionTimeout = timeout;
96101
}
97102

98103
/**
99104
* Set the socket read timeout for the underlying HttpClient. A value of 0 means <em>never</em> timeout.
100105
*
101-
* @param timeout the timeout value in milliseconds
106+
* @param timeout the timeout value
102107
*/
103-
public void setReadTimeout(int timeout) {
104-
if (timeout < 0) {
108+
public void setReadTimeout(Duration timeout) {
109+
110+
if (timeout.isNegative()) {
105111
throw new IllegalArgumentException("timeout must be a non-negative value");
106112
}
113+
107114
this.readTimeout = timeout;
108115
}
109116

@@ -114,9 +121,11 @@ public void setReadTimeout(int timeout) {
114121
* @see PoolingHttpClientConnectionManager...
115122
*/
116123
public void setMaxTotalConnections(int maxTotalConnections) {
124+
117125
if (maxTotalConnections <= 0) {
118126
throw new IllegalArgumentException("maxTotalConnections must be a positive value");
119127
}
128+
120129
this.maxTotalConnections = maxTotalConnections;
121130
}
122131

@@ -142,14 +151,14 @@ public void setMaxConnectionsPerHost(Map<String, String> maxConnectionsPerHost)
142151
void applyMaxConnectionsPerHost(PoolingHttpClientConnectionManager connectionManager) throws URISyntaxException {
143152

144153
for (Map.Entry<String, String> entry : maxConnectionsPerHost.entrySet()) {
154+
145155
URI uri = new URI(entry.getKey());
146156
HttpHost host = new HttpHost(uri.getScheme(), uri.getHost(), getPort(uri));
147157
final HttpRoute route;
148158

149159
if (uri.getScheme().equals("https")) {
150160
route = new HttpRoute(host, null, true);
151-
}
152-
else {
161+
} else {
153162
route = new HttpRoute(host);
154163
}
155164
int max = Integer.parseInt(entry.getValue());
@@ -158,14 +167,17 @@ void applyMaxConnectionsPerHost(PoolingHttpClientConnectionManager connectionMan
158167
}
159168

160169
static int getPort(URI uri) {
170+
161171
if (uri.getPort() == -1) {
172+
162173
if ("https".equalsIgnoreCase(uri.getScheme())) {
163174
return 443;
164175
}
165176
if ("http".equalsIgnoreCase(uri.getScheme())) {
166177
return 80;
167178
}
168179
}
180+
169181
return uri.getPort();
170182
}
171183

@@ -176,34 +188,38 @@ public boolean isSingleton() {
176188

177189
@Override
178190
public CloseableHttpClient getObject() throws Exception {
179-
PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create();
191+
192+
PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder
193+
.create();
194+
180195
if (this.maxTotalConnections != -1) {
181196
connectionManagerBuilder.setMaxConnTotal(this.maxTotalConnections);
182197
}
183198

184-
if (null != this.connectionManagerBuilderCustomizer) {
199+
if (this.connectionManagerBuilderCustomizer != null) {
185200
this.connectionManagerBuilderCustomizer.customize(connectionManagerBuilder);
186201
}
187202

188203
this.connectionManager = connectionManagerBuilder.build();
189204

190205
applyMaxConnectionsPerHost(connectionManager);
191206

192-
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom()
193-
.setConnectTimeout(connectionTimeout, TimeUnit.MILLISECONDS)
194-
.setResponseTimeout(readTimeout, TimeUnit.MILLISECONDS);
207+
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom() //
208+
.setConnectionRequestTimeout(Timeout.of(connectionTimeout)) //
209+
.setResponseTimeout(Timeout.of(readTimeout));
195210

196-
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
197-
.setDefaultRequestConfig(requestConfigBuilder.build())
211+
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create() //
212+
.setDefaultRequestConfig(requestConfigBuilder.build()) //
198213
.setConnectionManager(connectionManager);
199214

200-
if (null != credentials && null != authScope) {
215+
if (credentials != null && authScope != null) {
216+
201217
BasicCredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider();
202218
basicCredentialsProvider.setCredentials(authScope, credentials);
203219
httpClientBuilder.setDefaultCredentialsProvider(basicCredentialsProvider);
204220
}
205221

206-
if (null != this.clientBuilderCustomizer) {
222+
if (this.clientBuilderCustomizer != null) {
207223
clientBuilderCustomizer.customize(httpClientBuilder);
208224
}
209225

@@ -223,7 +239,8 @@ public void setClientBuilderCustomizer(HttpClientBuilderCustomizer clientBuilder
223239
this.clientBuilderCustomizer = clientBuilderCustomizer;
224240
}
225241

226-
public void setConnectionManagerBuilderCustomizer(PoolingHttpClientConnectionManagerBuilderCustomizer connectionManagerBuilderCustomizer) {
242+
public void setConnectionManagerBuilderCustomizer(
243+
PoolingHttpClientConnectionManagerBuilderCustomizer connectionManagerBuilderCustomizer) {
227244
this.connectionManagerBuilderCustomizer = connectionManagerBuilderCustomizer;
228245
}
229246

spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpComponents5Connection.java

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,19 @@
2828
import org.apache.hc.client5.http.classic.HttpClient;
2929
import org.apache.hc.client5.http.classic.methods.HttpPost;
3030
import org.apache.hc.core5.http.ClassicHttpResponse;
31-
import org.apache.hc.core5.http.Header;
3231
import org.apache.hc.core5.http.HttpEntity;
3332
import org.apache.hc.core5.http.HttpResponse;
33+
import org.apache.hc.core5.http.NameValuePair;
3434
import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
3535
import org.apache.hc.core5.http.io.entity.EntityUtils;
3636
import org.apache.hc.core5.http.protocol.HttpContext;
37-
3837
import org.springframework.util.Assert;
3938
import org.springframework.ws.WebServiceMessage;
4039
import org.springframework.ws.transport.WebServiceConnection;
4140

4241
/**
43-
* Implementation of {@link WebServiceConnection} that is based on Apache HttpClient. Exposes a {@link org.apache.hc.client5.http.classic.methods.HttpPost} and
44-
* {@link org.apache.hc.core5.http.HttpResponse
42+
* Implementation of {@link WebServiceConnection} that is based on Apache HttpClient 5. Exposes a {@link HttpPost} and
43+
* {@link HttpResponse}.
4544
*
4645
* @author Alan Stewart
4746
* @author Barry Pitman
@@ -63,8 +62,10 @@ public class HttpComponents5Connection extends AbstractHttpSenderConnection {
6362
private ByteArrayOutputStream requestBuffer;
6463

6564
protected HttpComponents5Connection(HttpClient httpClient, HttpPost httpPost, HttpContext httpContext) {
65+
6666
Assert.notNull(httpClient, "httpClient must not be null");
6767
Assert.notNull(httpPost, "httpPost must not be null");
68+
6869
this.httpClient = httpClient;
6970
this.httpPost = httpPost;
7071
this.httpContext = httpContext;
@@ -80,8 +81,9 @@ public HttpResponse getHttpResponse() {
8081

8182
@Override
8283
public void onClose() throws IOException {
83-
//XXX:
84+
8485
if (httpResponse instanceof ClassicHttpResponse response) {
86+
8587
if (response.getEntity() != null) {
8688
EntityUtils.consume(response.getEntity());
8789
}
@@ -117,9 +119,10 @@ protected OutputStream getRequestOutputStream() throws IOException {
117119

118120
@Override
119121
protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
120-
//XXX
122+
121123
httpPost.setEntity(new ByteArrayEntity(requestBuffer.toByteArray(), null));
122124
requestBuffer = null;
125+
123126
if (httpContext != null) {
124127
httpResponse = httpClient.execute(httpPost, httpContext);
125128
} else {
@@ -143,8 +146,9 @@ protected String getResponseMessage() throws IOException {
143146

144147
@Override
145148
protected long getResponseContentLength() throws IOException {
146-
//XXX:
149+
147150
if (httpResponse instanceof ClassicHttpResponse response) {
151+
148152
HttpEntity entity = response.getEntity();
149153
if (entity != null) {
150154
return entity.getContentLength();
@@ -155,32 +159,31 @@ protected long getResponseContentLength() throws IOException {
155159

156160
@Override
157161
protected InputStream getRawResponseInputStream() throws IOException {
162+
158163
if (httpResponse instanceof ClassicHttpResponse response) {
164+
159165
HttpEntity entity = response.getEntity();
160166
if (entity != null) {
161167
return entity.getContent();
162168
}
163169
}
170+
164171
throw new IllegalStateException("Response has no enclosing response entity, cannot create input stream");
165172
}
166173

167174
@Override
168175
public Iterator<String> getResponseHeaderNames() throws IOException {
169-
Header[] headers = httpResponse.getHeaders();
170-
String[] names = new String[headers.length];
171-
for (int i = 0; i < headers.length; i++) {
172-
names[i] = headers[i].getName();
173-
}
174-
return Arrays.asList(names).iterator();
176+
177+
return Arrays.stream(httpResponse.getHeaders()) //
178+
.map(NameValuePair::getName) //
179+
.iterator();
175180
}
176181

177182
@Override
178183
public Iterator<String> getResponseHeaders(String name) throws IOException {
179-
Header[] headers = httpResponse.getHeaders(name);
180-
String[] values = new String[headers.length];
181-
for (int i = 0; i < headers.length; i++) {
182-
values[i] = headers[i].getValue();
183-
}
184-
return Arrays.asList(values).iterator();
184+
185+
return Arrays.stream(httpResponse.getHeaders(name)) //
186+
.map(NameValuePair::getValue) //
187+
.iterator();
185188
}
186189
}

0 commit comments

Comments
 (0)