Remove deprecated methods

This commit removes method that were deprecated quite some time ago
as part of the 2.0 line:

- `FaultAwareWebServiceConnection#setFault(boolean)`
- Commons HttpClient v3
- EhCache v2

Closes gh-1321
This commit is contained in:
Stéphane Nicoll
2025-03-10 14:19:52 +01:00
parent 2b22c5a5c8
commit 0929ef64ff
11 changed files with 0 additions and 713 deletions

View File

@@ -17,9 +17,6 @@ dependencies {
api("org.springframework:spring-web")
api("org.springframework:spring-webmvc")
optional("commons-httpclient:commons-httpclient") {
exclude(group: "commons-logging", module: "commons-logging")
}
optional("jakarta.mail:jakarta.mail-api")
optional("jakarta.servlet:jakarta.servlet-api")
optional("org.apache.httpcomponents:httpclient") {

View File

@@ -42,17 +42,6 @@ public interface FaultAwareWebServiceConnection extends WebServiceConnection {
*/
boolean hasFault() throws IOException;
/**
* Sets whether this connection will send a fault.
* <p>
* Typically implemented by setting an HTTP status code.
* @param fault {@code true} if this will send a fault; {@code false} otherwise.
* @throws IOException in case of I/O errors
* @deprecated In favor of {@link #setFaultCode(QName)}
*/
@Deprecated
void setFault(boolean fault) throws IOException;
/**
* Sets a specific fault code.
* <p>

View File

@@ -167,11 +167,6 @@ public abstract class AbstractHttpSenderConnection extends AbstractSenderConnect
return false;
}
@Override
@Deprecated
public final void setFault(boolean fault) {
}
@Override
public final void setFaultCode(QName faultCode) throws IOException {
}

View File

@@ -1,177 +0,0 @@
/*
* Copyright 2005-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.transport.http;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Iterator;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.transport.WebServiceConnection;
/**
* Implementation of {@link WebServiceConnection} that is based on Jakarta Commons
* HttpClient. Exposes a {@link PostMethod}.
*
* @author Arjen Poutsma
* @author Greg Turnquist
* @since 1.0.0
* @deprecated In favor of {@link HttpComponentsConnection}
*/
@Deprecated
public class CommonsHttpConnection extends AbstractHttpSenderConnection {
private final HttpClient httpClient;
private final PostMethod postMethod;
private ByteArrayOutputStream requestBuffer;
private MultiThreadedHttpConnectionManager connectionManager;
protected CommonsHttpConnection(HttpClient httpClient, PostMethod postMethod) {
Assert.notNull(httpClient, "httpClient must not be null");
Assert.notNull(postMethod, "postMethod must not be null");
this.httpClient = httpClient;
this.postMethod = postMethod;
}
public PostMethod getPostMethod() {
return this.postMethod;
}
@Override
public void onClose() throws IOException {
this.postMethod.releaseConnection();
if (this.connectionManager != null) {
this.connectionManager.shutdown();
}
}
/*
* URI
*/
@Override
public URI getUri() throws URISyntaxException {
try {
return new URI(this.postMethod.getURI().toString());
}
catch (URIException ex) {
throw new URISyntaxException("", ex.getMessage());
}
}
/*
* Sending request
*/
@Override
protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
this.requestBuffer = new ByteArrayOutputStream();
}
@Override
public void addRequestHeader(String name, String value) throws IOException {
this.postMethod.addRequestHeader(name, value);
}
@Override
protected OutputStream getRequestOutputStream() throws IOException {
return this.requestBuffer;
}
@Override
protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
this.postMethod.setRequestEntity(new ByteArrayRequestEntity(this.requestBuffer.toByteArray()));
this.requestBuffer = null;
try {
this.httpClient.executeMethod(this.postMethod);
}
catch (IllegalStateException ex) {
if ("Connection factory has been shutdown.".equals(ex.getMessage())) {
// The application context has been closed, resulting in a connection
// factory shutdown and an ISE.
// Let's create a new connection factory for this connection only.
this.connectionManager = new MultiThreadedHttpConnectionManager();
this.httpClient.setHttpConnectionManager(this.connectionManager);
this.httpClient.executeMethod(this.postMethod);
}
else {
throw ex;
}
}
}
/*
* Receiving response
*/
@Override
protected int getResponseCode() throws IOException {
return this.postMethod.getStatusCode();
}
@Override
protected String getResponseMessage() throws IOException {
return this.postMethod.getStatusText();
}
@Override
protected long getResponseContentLength() throws IOException {
return this.postMethod.getResponseContentLength();
}
@Override
protected InputStream getRawResponseInputStream() throws IOException {
return this.postMethod.getResponseBodyAsStream();
}
@Override
public Iterator<String> getResponseHeaderNames() throws IOException {
Header[] headers = this.postMethod.getResponseHeaders();
String[] names = new String[headers.length];
for (int i = 0; i < headers.length; i++) {
names[i] = headers[i].getName();
}
return Arrays.asList(names).iterator();
}
@Override
public Iterator<String> getResponseHeaders(String name) throws IOException {
Header[] headers = this.postMethod.getResponseHeaders(name);
String[] values = new String[headers.length];
for (int i = 0; i < headers.length; i++) {
values[i] = headers[i].getValue();
}
return Arrays.asList(values).iterator();
}
}

View File

@@ -1,244 +0,0 @@
/*
* Copyright 2005-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.transport.http;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpURL;
import org.apache.commons.httpclient.HttpsURL;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.ws.transport.WebServiceConnection;
/**
* {@code WebServiceMessageSender} implementation that uses
* <a href="http://jakarta.apache.org/commons/httpclient">Jakarta Commons HttpClient</a>
* to execute POST requests.
* <p>
* Allows to use a preconfigured HttpClient instance, potentially with authentication,
* HTTP connection pooling, etc. Authentication can also be set by injecting a
* {@link Credentials} instance (such as the {@link UsernamePasswordCredentials}).
*
* @author Arjen Poutsma
* @since 1.0.0
* @see HttpUrlConnectionMessageSender
* @see HttpClient
* @see #setCredentials(Credentials)
* @deprecated In favor of {@link HttpComponents5MessageSender}
*/
@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() {
this.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 this.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 this.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 (this.authScope != null) ? this.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);
}
}

View File

@@ -156,18 +156,6 @@ public class HttpServletConnection extends AbstractReceiverConnection
return false;
}
@Override
@Deprecated
public void setFault(boolean fault) throws IOException {
if (fault) {
getHttpServletResponse().setStatus(HttpTransportConstants.STATUS_INTERNAL_SERVER_ERROR);
}
else {
getHttpServletResponse().setStatus(HttpTransportConstants.STATUS_OK);
}
this.statusCodeSet = true;
}
@Override
public void setFaultCode(QName faultCode) throws IOException {
if (faultCode != null) {

View File

@@ -1,128 +0,0 @@
/*
* Copyright 2005-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.transport.http;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.xml.soap.MessageFactory;
import org.apache.commons.httpclient.URIException;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.util.FileCopyUtils;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
import org.springframework.ws.transport.WebServiceConnection;
import org.springframework.ws.transport.support.FreePortScanner;
@Deprecated
public class CommonsHttpMessageSenderIntegrationTest
extends AbstractHttpWebServiceMessageSenderIntegrationTest<CommonsHttpMessageSender> {
@Override
protected CommonsHttpMessageSender createMessageSender() {
return new CommonsHttpMessageSender();
}
@Test
public void testMaxConnections() throws URIException {
CommonsHttpMessageSender messageSender = new CommonsHttpMessageSender();
messageSender.setMaxTotalConnections(2);
Map<String, String> maxConnectionsPerHost = new HashMap<>();
maxConnectionsPerHost.put("https://www.example.com", "1");
maxConnectionsPerHost.put("http://www.example.com:8080", "7");
maxConnectionsPerHost.put("www.springframework.org", "10");
maxConnectionsPerHost.put("*", "5");
messageSender.setMaxConnectionsPerHost(maxConnectionsPerHost);
}
@Test
public void testContextClose() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
int port = FreePortScanner.getFreePort();
Server jettyServer = new Server(port);
Connector connector = new ServerConnector(jettyServer);
jettyServer.addConnector(connector);
ServletContextHandler jettyContext = new ServletContextHandler();
jettyContext.setContextPath("/");
jettyContext.addServlet(EchoServlet.class, "/");
jettyServer.setHandler(jettyContext);
jettyServer.start();
WebServiceConnection connection = null;
try {
StaticApplicationContext appContext = new StaticApplicationContext();
appContext.registerSingleton("messageSender", CommonsHttpMessageSender.class);
appContext.refresh();
CommonsHttpMessageSender messageSender = appContext.getBean("messageSender",
CommonsHttpMessageSender.class);
connection = messageSender.createConnection(new URI("http://localhost:" + port));
appContext.close();
connection.send(new SaajSoapMessage(messageFactory.createMessage()));
connection.receive(new SaajSoapMessageFactory(messageFactory));
}
finally {
if (connection != null) {
try {
connection.close();
}
catch (IOException ex) {
// ignore
}
}
if (jettyServer.isRunning()) {
jettyServer.stop();
}
}
}
@SuppressWarnings("serial")
public static class EchoServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/xml");
FileCopyUtils.copy(request.getInputStream(), response.getOutputStream());
}
}
}

View File

@@ -21,7 +21,6 @@ dependencies {
api("com.icegreen:greenmail-junit5:2.0.1")
api("com.icegreen:greenmail-spring:2.0.1")
api("com.sun.xml.messaging.saaj:saaj-impl:3.0.4")
api("commons-httpclient:commons-httpclient:3.1")
api("commons-io:commons-io:2.16.1")
api("jakarta.activation:jakarta.activation-api:2.1.3")
api("jakarta.annotation:jakarta.annotation-api:2.1.1")
@@ -32,7 +31,6 @@ dependencies {
api("jakarta.xml.soap:jakarta.xml.soap-api:3.0.2")
api("jaxen:jaxen:1.1.6")
api("net.minidev:json-smart:2.5.2")
api("net.sf.ehcache:ehcache:2.10.9.2")
api("org.apache.commons:commons-collections4:4.4")
api("org.apache.httpcomponents.client5:httpclient5:5.2.3")
api("org.apache.httpcomponents:httpclient:4.5.14")

View File

@@ -22,7 +22,6 @@ dependencies {
api("org.springframework.security:spring-security-core")
optional("com.sun.xml.messaging.saaj:saaj-impl")
optional("net.sf.ehcache:ehcache")
testImplementation("org.apache.logging.log4j:log4j-core")
testImplementation("org.apache.logging.log4j:log4j-slf4j2-impl")

View File

@@ -1,119 +0,0 @@
/*
* Copyright 2005-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.soap.security.x509.cache;
import java.security.cert.X509Certificate;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.Assert;
/**
* Caches {@code User} objects using a Spring IoC defined
* <a href="http://ehcache.sourceforge.net">EHCACHE</a>.
* <p>
* Migrated from Spring Security 2 since it has been removed in Spring Security 3.
* </p>
*
* @author Luke Taylor
* @author Ben Alex
* @author Greg Turnquist
* @deprecated Migrate to {@link SpringBasedX509UserCache} and inject a platform neutral
* Spring-based {@link org.springframework.cache.Cache}.
*/
@Deprecated
public class EhCacheBasedX509UserCache implements X509UserCache, InitializingBean {
// ~ Static fields/initializers
// =====================================================================================
private static final Log logger = LogFactory.getLog(EhCacheBasedX509UserCache.class);
// ~ Instance fields
// ================================================================================================
private Ehcache cache;
// ~ Methods
// ========================================================================================================
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.cache, "cache is mandatory");
}
@Override
public UserDetails getUserFromCache(X509Certificate userCert) {
Element element;
try {
element = this.cache.get(userCert);
}
catch (CacheException cacheException) {
throw new DataRetrievalFailureException("Cache failure: " + cacheException.getMessage());
}
if (logger.isDebugEnabled()) {
String subjectDN = "unknown";
if ((userCert != null) && (userCert.getSubjectDN() != null)) {
subjectDN = userCert.getSubjectDN().toString();
}
logger.debug("X.509 Cache hit. SubjectDN: " + subjectDN);
}
if (element == null) {
return null;
}
else {
return (UserDetails) element.getObjectValue();
}
}
@Override
public void putUserInCache(X509Certificate userCert, UserDetails user) {
Element element = new Element(userCert, user);
if (logger.isDebugEnabled()) {
logger.debug("Cache put: " + userCert.getSubjectDN());
}
this.cache.put(element);
}
@Override
public void removeUserFromCache(X509Certificate userCert) {
if (logger.isDebugEnabled()) {
logger.debug("Cache remove: " + userCert.getSubjectDN());
}
this.cache.remove(userCert);
}
public void setCache(Ehcache cache) {
this.cache = cache;
}
}

View File

@@ -169,17 +169,6 @@ public class HttpExchangeConnection extends AbstractReceiverConnection
return this.responseStatusCode == HttpTransportConstants.STATUS_INTERNAL_SERVER_ERROR;
}
@Override
@Deprecated
public void setFault(boolean fault) throws IOException {
if (fault) {
this.responseStatusCode = HttpTransportConstants.STATUS_INTERNAL_SERVER_ERROR;
}
else {
this.responseStatusCode = HttpTransportConstants.STATUS_OK;
}
}
@Override
public void setFaultCode(QName faultCode) throws IOException {
if (faultCode != null) {