Skip to content

Commit

Permalink
Introduce HttpComponents HttpClient 5 support.
Browse files Browse the repository at this point in the history
Resolves #1164.
Original Pull Request: #1356.
  • Loading branch information
cachescrubber authored and gregturn committed May 12, 2023
1 parent 6edbdeb commit 4ebe0ba
Show file tree
Hide file tree
Showing 8 changed files with 1,065 additions and 241 deletions.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
<ehcache.version>2.10.9.2</ehcache.version>
<greenmail.version>2.0.0-alpha-2</greenmail.version>
<httpclient.version>4.5.3</httpclient.version>
<httpclient5.version>5.2.1</httpclient5.version>
<jakarta-annotation.version>2.1.1</jakarta-annotation.version>
<jakarta-jms.version>3.1.0</jakarta-jms.version>
<jakarta-mail-api.version>2.1.0</jakarta-mail-api.version>
Expand Down
18 changes: 18 additions & 0 deletions spring-ws-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,24 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>${httpclient5.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.eclipse.jetty</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,184 +54,184 @@
*/
@Deprecated
public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSender
implements InitializingBean, DisposableBean {

private static final int DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS = (60 * 1000);

private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);

private HttpClient httpClient;

private Credentials credentials;

private AuthScope authScope;

/**
* Create a new instance of the {@code CommonsHttpMessageSender} with a default {@link HttpClient} that uses a default
* {@link MultiThreadedHttpConnectionManager}.
*/
public CommonsHttpMessageSender() {
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS);
setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
}

/**
* Create a new instance of the {@code CommonsHttpMessageSender} with the given {@link HttpClient} instance.
*
* @param httpClient the HttpClient instance to use for this sender
*/
public CommonsHttpMessageSender(HttpClient httpClient) {
Assert.notNull(httpClient, "httpClient must not be null");
this.httpClient = httpClient;
}

/** Returns the {@code HttpClient} used by this message sender. */
public HttpClient getHttpClient() {
return httpClient;
}

/** Set the {@code HttpClient} used by this message sender. */
public void setHttpClient(HttpClient httpClient) {
this.httpClient = httpClient;
}

/** Returns the credentials to be used. */
public Credentials getCredentials() {
return credentials;
}

/**
* Sets the credentials to be used. If not set, no authentication is done.
*
* @see UsernamePasswordCredentials
* @see NTCredentials
*/
public void setCredentials(Credentials credentials) {
this.credentials = credentials;
}

/**
* Sets the timeout until a connection is etablished. A value of 0 means <em>never</em> timeout.
*
* @param timeout the timeout value in milliseconds
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setConnectionTimeout(int)
*/
public void setConnectionTimeout(int timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be a non-negative value");
}
getHttpClient().getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
}

/**
* Set the socket read timeout for the underlying HttpClient. A value of 0 means <em>never</em> timeout.
*
* @param timeout the timeout value in milliseconds
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)
*/
public void setReadTimeout(int timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be a non-negative value");
}
getHttpClient().getHttpConnectionManager().getParams().setSoTimeout(timeout);
}

/**
* Sets the maximum number of connections allowed for the underlying HttpClient.
*
* @param maxTotalConnections the maximum number of connections allowed
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setMaxTotalConnections(int)
*/
public void setMaxTotalConnections(int maxTotalConnections) {
if (maxTotalConnections <= 0) {
throw new IllegalArgumentException("maxTotalConnections must be a positive value");
}
getHttpClient().getHttpConnectionManager().getParams().setMaxTotalConnections(maxTotalConnections);
}

/**
* Sets the maximum number of connections per host for the underlying HttpClient. The maximum number of connections
* per host can be set in a form accepted by the {@code java.util.Properties} class, like as follows:
*
* <pre>
* https://www.example.com=1
* http://www.example.com:8080=7
* www.springframework.org=10
* *=5
* </pre>
*
* The host can be specified as hostname, or as URI (with scheme and port). The special host name {@code *} can be
* used to specify {@link org.apache.commons.httpclient.HostConfiguration#ANY_HOST_CONFIGURATION}.
*
* @param maxConnectionsPerHost a properties object specifying the maximum number of connection
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setMaxConnectionsPerHost(org.apache.commons.httpclient.HostConfiguration,
* int)
*/
public void setMaxConnectionsPerHost(Map<String, String> maxConnectionsPerHost) throws URIException {
for (String host : maxConnectionsPerHost.keySet()) {
HostConfiguration hostConfiguration = new HostConfiguration();
if ("*".equals(host)) {
hostConfiguration = HostConfiguration.ANY_HOST_CONFIGURATION;
} else if (host.startsWith("http://")) {
HttpURL httpURL = new HttpURL(host);
hostConfiguration.setHost(httpURL);
} else if (host.startsWith("https://")) {
HttpsURL httpsURL = new HttpsURL(host);
hostConfiguration.setHost(httpsURL);
} else {
hostConfiguration.setHost(host);
}
int maxHostConnections = Integer.parseInt(maxConnectionsPerHost.get(host));
getHttpClient().getHttpConnectionManager().getParams().setMaxConnectionsPerHost(hostConfiguration,
maxHostConnections);
}
}

/**
* Returns the authentication scope to be used. Only used when the {@code credentials} property has been set.
* <p>
* By default, the {@link AuthScope#ANY} is returned.
*/
public AuthScope getAuthScope() {
return authScope != null ? authScope : AuthScope.ANY;
}

/**
* Sets the authentication scope to be used. Only used when the {@code credentials} property has been set.
* <p>
* By default, the {@link AuthScope#ANY} is used.
*
* @see #setCredentials(Credentials)
*/
public void setAuthScope(AuthScope authScope) {
this.authScope = authScope;
}

@Override
public void afterPropertiesSet() throws Exception {
if (getCredentials() != null) {
getHttpClient().getState().setCredentials(getAuthScope(), getCredentials());
getHttpClient().getParams().setAuthenticationPreemptive(true);
}
}

@Override
public void destroy() throws Exception {
HttpConnectionManager connectionManager = getHttpClient().getHttpConnectionManager();
if (connectionManager instanceof MultiThreadedHttpConnectionManager) {
((MultiThreadedHttpConnectionManager) connectionManager).shutdown();
}
}

@Override
public WebServiceConnection createConnection(URI uri) throws IOException {
PostMethod postMethod = new PostMethod(uri.toString());
if (isAcceptGzipEncoding()) {
postMethod.addRequestHeader(HttpTransportConstants.HEADER_ACCEPT_ENCODING,
HttpTransportConstants.CONTENT_ENCODING_GZIP);
}
return new CommonsHttpConnection(getHttpClient(), postMethod);
}

}
implements InitializingBean, DisposableBean {

private static final int DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS = (60 * 1000);

private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);

private HttpClient httpClient;

private Credentials credentials;

private AuthScope authScope;

/**
* Create a new instance of the {@code CommonsHttpMessageSender} with a default {@link HttpClient} that uses a default
* {@link MultiThreadedHttpConnectionManager}.
*/
public CommonsHttpMessageSender() {
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS);
setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
}

/**
* Create a new instance of the {@code CommonsHttpMessageSender} with the given {@link HttpClient} instance.
*
* @param httpClient the HttpClient instance to use for this sender
*/
public CommonsHttpMessageSender(HttpClient httpClient) {
Assert.notNull(httpClient, "httpClient must not be null");
this.httpClient = httpClient;
}

/** Returns the {@code HttpClient} used by this message sender. */
public HttpClient getHttpClient() {
return httpClient;
}

/** Set the {@code HttpClient} used by this message sender. */
public void setHttpClient(HttpClient httpClient) {
this.httpClient = httpClient;
}

/** Returns the credentials to be used. */
public Credentials getCredentials() {
return credentials;
}

/**
* Sets the credentials to be used. If not set, no authentication is done.
*
* @see UsernamePasswordCredentials
* @see NTCredentials
*/
public void setCredentials(Credentials credentials) {
this.credentials = credentials;
}

/**
* Sets the timeout until a connection is etablished. A value of 0 means <em>never</em> timeout.
*
* @param timeout the timeout value in milliseconds
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setConnectionTimeout(int)
*/
public void setConnectionTimeout(int timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be a non-negative value");
}
getHttpClient().getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
}

/**
* Set the socket read timeout for the underlying HttpClient. A value of 0 means <em>never</em> timeout.
*
* @param timeout the timeout value in milliseconds
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)
*/
public void setReadTimeout(int timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be a non-negative value");
}
getHttpClient().getHttpConnectionManager().getParams().setSoTimeout(timeout);
}

/**
* Sets the maximum number of connections allowed for the underlying HttpClient.
*
* @param maxTotalConnections the maximum number of connections allowed
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setMaxTotalConnections(int)
*/
public void setMaxTotalConnections(int maxTotalConnections) {
if (maxTotalConnections <= 0) {
throw new IllegalArgumentException("maxTotalConnections must be a positive value");
}
getHttpClient().getHttpConnectionManager().getParams().setMaxTotalConnections(maxTotalConnections);
}

/**
* Sets the maximum number of connections per host for the underlying HttpClient. The maximum number of connections
* per host can be set in a form accepted by the {@code java.util.Properties} class, like as follows:
*
* <pre>
* https://www.example.com=1
* http://www.example.com:8080=7
* www.springframework.org=10
* *=5
* </pre>
*
* The host can be specified as hostname, or as URI (with scheme and port). The special host name {@code *} can be
* used to specify {@link org.apache.commons.httpclient.HostConfiguration#ANY_HOST_CONFIGURATION}.
*
* @param maxConnectionsPerHost a properties object specifying the maximum number of connection
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setMaxConnectionsPerHost(org.apache.commons.httpclient.HostConfiguration,
* int)
*/
public void setMaxConnectionsPerHost(Map<String, String> maxConnectionsPerHost) throws URIException {
for (String host : maxConnectionsPerHost.keySet()) {
HostConfiguration hostConfiguration = new HostConfiguration();
if ("*".equals(host)) {
hostConfiguration = HostConfiguration.ANY_HOST_CONFIGURATION;
} else if (host.startsWith("http://")) {
HttpURL httpURL = new HttpURL(host);
hostConfiguration.setHost(httpURL);
} else if (host.startsWith("https://")) {
HttpsURL httpsURL = new HttpsURL(host);
hostConfiguration.setHost(httpsURL);
} else {
hostConfiguration.setHost(host);
}
int maxHostConnections = Integer.parseInt(maxConnectionsPerHost.get(host));
getHttpClient().getHttpConnectionManager().getParams().setMaxConnectionsPerHost(hostConfiguration,
maxHostConnections);
}
}

/**
* Returns the authentication scope to be used. Only used when the {@code credentials} property has been set.
* <p>
* By default, the {@link AuthScope#ANY} is returned.
*/
public AuthScope getAuthScope() {
return authScope != null ? authScope : AuthScope.ANY;
}

/**
* Sets the authentication scope to be used. Only used when the {@code credentials} property has been set.
* <p>
* By default, the {@link AuthScope#ANY} is used.
*
* @see #setCredentials(Credentials)
*/
public void setAuthScope(AuthScope authScope) {
this.authScope = authScope;
}

@Override
public void afterPropertiesSet() throws Exception {
if (getCredentials() != null) {
getHttpClient().getState().setCredentials(getAuthScope(), getCredentials());
getHttpClient().getParams().setAuthenticationPreemptive(true);
}
}

@Override
public void destroy() throws Exception {
HttpConnectionManager connectionManager = getHttpClient().getHttpConnectionManager();
if (connectionManager instanceof MultiThreadedHttpConnectionManager) {
((MultiThreadedHttpConnectionManager) connectionManager).shutdown();
}
}

@Override
public WebServiceConnection createConnection(URI uri) throws IOException {
PostMethod postMethod = new PostMethod(uri.toString());
if (isAcceptGzipEncoding()) {
postMethod.addRequestHeader(HttpTransportConstants.HEADER_ACCEPT_ENCODING,
HttpTransportConstants.CONTENT_ENCODING_GZIP);
}
return new CommonsHttpConnection(getHttpClient(), postMethod);
}

}
Loading

0 comments on commit 4ebe0ba

Please sign in to comment.