Removed Apache Commons HttpClient support (superseded by Apache HttpComponents)

This commit is contained in:
Juergen Hoeller 2013-03-29 15:03:55 +01:00
parent 8fab14dfeb
commit 15441da969
6 changed files with 0 additions and 644 deletions

View File

@ -83,7 +83,6 @@ configure(allprojects) { project ->
"http://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs", // commonj
"http://quartz-scheduler.org/api/2.1.5",
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
"http://hc.apache.org/httpclient-3.x/apidocs",
"http://fasterxml.github.com/jackson-core/javadoc/2.0.0",
"http://jackson.codehaus.org/1.4.2/javadoc",
"http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs",
@ -453,7 +452,6 @@ project("spring-web") {
optional("rome:rome:1.0")
optional("commons-fileupload:commons-fileupload:1.2")
optional("commons-io:commons-io:1.3")
optional("commons-httpclient:commons-httpclient:3.1")
optional("org.apache.httpcomponents:httpclient:4.2")
optional("org.codehaus.jackson:jackson-mapper-asl:1.4.2")
optional("com.fasterxml.jackson.core:jackson-databind:2.0.1")

View File

@ -1,89 +0,0 @@
/*
* Copyright 2002-2012 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
*
* http://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.http.client;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
/**
* {@link org.springframework.http.client.ClientHttpRequest} implementation that uses
* Apache Commons HttpClient to execute requests.
*
* <p>Created via the {@link CommonsClientHttpRequestFactory}.
*
* @author Arjen Poutsma
* @since 3.0
* @see CommonsClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
* @deprecated In favor of {@link HttpComponentsClientHttpRequest}
*/
@Deprecated
final class CommonsClientHttpRequest extends AbstractBufferingClientHttpRequest {
private final HttpClient httpClient;
private final HttpMethodBase httpMethod;
CommonsClientHttpRequest(HttpClient httpClient, HttpMethodBase httpMethod) {
this.httpClient = httpClient;
this.httpMethod = httpMethod;
}
public HttpMethod getMethod() {
return HttpMethod.valueOf(this.httpMethod.getName());
}
public URI getURI() {
try {
return URI.create(this.httpMethod.getURI().getEscapedURI());
}
catch (URIException ex) {
throw new IllegalStateException("Could not get HttpMethod URI: " + ex.getMessage(), ex);
}
}
@Override
public ClientHttpResponse executeInternal(HttpHeaders headers, byte[] output) throws IOException {
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
String headerName = entry.getKey();
for (String headerValue : entry.getValue()) {
httpMethod.addRequestHeader(headerName, headerValue);
}
}
if (this.httpMethod instanceof EntityEnclosingMethod) {
EntityEnclosingMethod entityEnclosingMethod = (EntityEnclosingMethod) this.httpMethod;
RequestEntity requestEntity = new ByteArrayRequestEntity(output);
entityEnclosingMethod.setRequestEntity(requestEntity);
}
this.httpClient.executeMethod(this.httpMethod);
return new CommonsClientHttpResponse(this.httpMethod);
}
}

View File

@ -1,172 +0,0 @@
/*
* Copyright 2002-2012 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
*
* http://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.http.client;
import java.io.IOException;
import java.net.URI;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.OptionsMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.TraceMethod;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.http.HttpMethod;
import org.springframework.util.Assert;
/**
* {@link org.springframework.http.client.ClientHttpRequestFactory} implementation that uses
* <a href="http://jakarta.apache.org/commons/httpclient">Jakarta Commons HttpClient</a> to create requests.
*
* <p>Allows to use a pre-configured {@link HttpClient} instance -
* potentially with authentication, HTTP connection pooling, etc.
*
* @author Arjen Poutsma
* @since 3.0
* @see org.springframework.http.client.SimpleClientHttpRequestFactory
* @deprecated In favor of {@link HttpComponentsClientHttpRequestFactory}
*/
@Deprecated
public class CommonsClientHttpRequestFactory implements ClientHttpRequestFactory, DisposableBean {
private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);
private HttpClient httpClient;
/**
* Create a new instance of the {@code CommonsHttpRequestFactory} with a default
* {@link HttpClient} that uses a default {@link MultiThreadedHttpConnectionManager}.
*/
public CommonsClientHttpRequestFactory() {
this.httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
this.setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
}
/**
* Create a new instance of the {@code CommonsHttpRequestFactory} with the given
* {@link HttpClient} instance.
* @param httpClient the HttpClient instance to use for this factory
*/
public CommonsClientHttpRequestFactory(HttpClient httpClient) {
Assert.notNull(httpClient, "httpClient must not be null");
this.httpClient = httpClient;
}
/**
* Set the {@code HttpClient} used by this factory.
*/
public void setHttpClient(HttpClient httpClient) {
this.httpClient = httpClient;
}
/**
* Return the {@code HttpClient} used by this factory.
*/
public HttpClient getHttpClient() {
return this.httpClient;
}
/**
* Set the connection timeout for the underlying HttpClient.
* A timeout value of 0 specifies an infinite timeout.
* @param timeout the timeout value in milliseconds
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setConnectionTimeout(int)
*/
public void setConnectTimeout(int timeout) {
Assert.isTrue(timeout >= 0, "Timeout must be a non-negative value");
this.httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
}
/**
* Set the socket read timeout for the underlying HttpClient.
* A timeout value of 0 specifies an infinite timeout.
* @param timeout the timeout value in milliseconds
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)
*/
public void setReadTimeout(int timeout) {
Assert.isTrue(timeout >= 0, "Timeout must be a non-negative value");
getHttpClient().getHttpConnectionManager().getParams().setSoTimeout(timeout);
}
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
HttpMethodBase commonsHttpMethod = createCommonsHttpMethod(httpMethod, uri.toString());
postProcessCommonsHttpMethod(commonsHttpMethod);
return new CommonsClientHttpRequest(getHttpClient(), commonsHttpMethod);
}
/**
* Create a Commons HttpMethodBase object for the given HTTP method
* and URI specification.
* @param httpMethod the HTTP method
* @param uri the URI
* @return the Commons HttpMethodBase object
*/
protected HttpMethodBase createCommonsHttpMethod(HttpMethod httpMethod, String uri) {
switch (httpMethod) {
case GET:
return new GetMethod(uri);
case DELETE:
return new DeleteMethod(uri);
case HEAD:
return new HeadMethod(uri);
case OPTIONS:
return new OptionsMethod(uri);
case POST:
return new PostMethod(uri);
case PUT:
return new PutMethod(uri);
case TRACE:
return new TraceMethod(uri);
case PATCH:
throw new IllegalArgumentException(
"HTTP method PATCH not available before Apache HttpComponents HttpClient 4.2");
default:
throw new IllegalArgumentException("Invalid HTTP method: " + httpMethod);
}
}
/**
* Template method that allows for manipulating the {@link org.apache.commons.httpclient.HttpMethodBase}
* before it is returned as part of a {@link CommonsClientHttpRequest}.
* <p>The default implementation is empty.
* @param httpMethod the Commons HTTP method object to process
*/
protected void postProcessCommonsHttpMethod(HttpMethodBase httpMethod) {
}
/**
* Shutdown hook that closes the underlying {@link HttpConnectionManager}'s
* connection pool, if any.
*/
public void destroy() {
HttpConnectionManager connectionManager = getHttpClient().getHttpConnectionManager();
if (connectionManager instanceof MultiThreadedHttpConnectionManager) {
((MultiThreadedHttpConnectionManager) connectionManager).shutdown();
}
}
}

View File

@ -1,77 +0,0 @@
/*
* Copyright 2002-2012 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
*
* http://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.http.client;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpMethod;
import org.springframework.http.HttpHeaders;
/**
* {@link org.springframework.http.client.ClientHttpResponse} implementation that uses
* Apache Commons HttpClient to execute requests.
*
* <p>Created via the {@link CommonsClientHttpRequest}.
*
* @author Arjen Poutsma
* @since 3.0
* @see CommonsClientHttpRequest#execute()
* @deprecated In favor of {@link HttpComponentsClientHttpResponse}
*/
@Deprecated
final class CommonsClientHttpResponse extends AbstractClientHttpResponse {
private final HttpMethod httpMethod;
private HttpHeaders headers;
CommonsClientHttpResponse(HttpMethod httpMethod) {
this.httpMethod = httpMethod;
}
public int getRawStatusCode() {
return this.httpMethod.getStatusCode();
}
public String getStatusText() {
return this.httpMethod.getStatusText();
}
public HttpHeaders getHeaders() {
if (this.headers == null) {
this.headers = new HttpHeaders();
for (Header header : this.httpMethod.getResponseHeaders()) {
this.headers.add(header.getName(), header.getValue());
}
}
return this.headers;
}
public InputStream getBody() throws IOException {
return this.httpMethod.getResponseBodyAsStream();
}
public void close() {
this.httpMethod.releaseConnection();
}
}

View File

@ -1,267 +0,0 @@
/*
* Copyright 2002-2011 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
*
* http://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.remoting.httpinvoker;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.remoting.support.RemoteInvocationResult;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* {@link HttpInvokerRequestExecutor} implementation that uses
* <a href="http://jakarta.apache.org/commons/httpclient">Jakarta Commons HttpClient</a>
* to execute POST requests. Requires Commons HttpClient 3.0 or higher.
*
* <p>Allows to use a pre-configured {@link org.apache.commons.httpclient.HttpClient}
* instance, potentially with authentication, HTTP connection pooling, etc.
* Also designed for easy subclassing, providing specific template methods.
*
* @author Juergen Hoeller
* @author Mark Fisher
* @since 1.1
* @see SimpleHttpInvokerRequestExecutor
*/
public class CommonsHttpInvokerRequestExecutor extends AbstractHttpInvokerRequestExecutor {
/**
* Default timeout value if no HttpClient is explicitly provided.
*/
private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);
private HttpClient httpClient;
/**
* Create a new CommonsHttpInvokerRequestExecutor with a default
* HttpClient that uses a default MultiThreadedHttpConnectionManager.
* Sets the socket read timeout to {@link #DEFAULT_READ_TIMEOUT_MILLISECONDS}.
* @see org.apache.commons.httpclient.HttpClient
* @see org.apache.commons.httpclient.MultiThreadedHttpConnectionManager
*/
public CommonsHttpInvokerRequestExecutor() {
this.httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
}
/**
* Create a new CommonsHttpInvokerRequestExecutor with the given
* HttpClient instance. The socket read timeout of the provided
* HttpClient will not be changed.
* @param httpClient the HttpClient instance to use for this request executor
*/
public CommonsHttpInvokerRequestExecutor(HttpClient httpClient) {
this.httpClient = httpClient;
}
/**
* Set the HttpClient instance to use for this request executor.
*/
public void setHttpClient(HttpClient httpClient) {
this.httpClient = httpClient;
}
/**
* Return the HttpClient instance that this request executor uses.
*/
public HttpClient getHttpClient() {
return this.httpClient;
}
/**
* Set the connection timeout for the underlying HttpClient.
* A timeout value of 0 specifies an infinite timeout.
* @param timeout the timeout value in milliseconds
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setConnectionTimeout(int)
*/
public void setConnectTimeout(int timeout) {
Assert.isTrue(timeout >= 0, "Timeout must be a non-negative value");
this.httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
}
/**
* Set the socket read timeout for the underlying HttpClient.
* A timeout value of 0 specifies an infinite timeout.
* @param timeout the timeout value in milliseconds
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)
* @see #DEFAULT_READ_TIMEOUT_MILLISECONDS
*/
public void setReadTimeout(int timeout) {
Assert.isTrue(timeout >= 0, "Timeout must be a non-negative value");
this.httpClient.getHttpConnectionManager().getParams().setSoTimeout(timeout);
}
/**
* Execute the given request through Commons HttpClient.
* <p>This method implements the basic processing workflow:
* The actual work happens in this class's template methods.
* @see #createPostMethod
* @see #setRequestBody
* @see #executePostMethod
* @see #validateResponse
* @see #getResponseBody
*/
@Override
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
throws IOException, ClassNotFoundException {
PostMethod postMethod = createPostMethod(config);
try {
setRequestBody(config, postMethod, baos);
executePostMethod(config, getHttpClient(), postMethod);
validateResponse(config, postMethod);
InputStream responseBody = getResponseBody(config, postMethod);
return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
}
finally {
// Need to explicitly release because it might be pooled.
postMethod.releaseConnection();
}
}
/**
* Create a PostMethod for the given configuration.
* <p>The default implementation creates a standard PostMethod with
* "application/x-java-serialized-object" as "Content-Type" header.
* @param config the HTTP invoker configuration that specifies the
* target service
* @return the PostMethod instance
* @throws IOException if thrown by I/O methods
*/
protected PostMethod createPostMethod(HttpInvokerClientConfiguration config) throws IOException {
PostMethod postMethod = new PostMethod(config.getServiceUrl());
LocaleContext locale = LocaleContextHolder.getLocaleContext();
if (locale != null) {
postMethod.addRequestHeader(HTTP_HEADER_ACCEPT_LANGUAGE, StringUtils.toLanguageTag(locale.getLocale()));
}
if (isAcceptGzipEncoding()) {
postMethod.addRequestHeader(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
}
return postMethod;
}
/**
* Set the given serialized remote invocation as request body.
* <p>The default implementation simply sets the serialized invocation as the
* PostMethod's request body. This can be overridden, for example, to write a
* specific encoding and to potentially set appropriate HTTP request headers.
* @param config the HTTP invoker configuration that specifies the target service
* @param postMethod the PostMethod to set the request body on
* @param baos the ByteArrayOutputStream that contains the serialized
* RemoteInvocation object
* @throws IOException if thrown by I/O methods
* @see org.apache.commons.httpclient.methods.PostMethod#setRequestBody(java.io.InputStream)
* @see org.apache.commons.httpclient.methods.PostMethod#setRequestEntity
* @see org.apache.commons.httpclient.methods.InputStreamRequestEntity
*/
protected void setRequestBody(
HttpInvokerClientConfiguration config, PostMethod postMethod, ByteArrayOutputStream baos)
throws IOException {
postMethod.setRequestEntity(new ByteArrayRequestEntity(baos.toByteArray(), getContentType()));
}
/**
* Execute the given PostMethod instance.
* @param config the HTTP invoker configuration that specifies the target service
* @param httpClient the HttpClient to execute on
* @param postMethod the PostMethod to execute
* @throws IOException if thrown by I/O methods
* @see org.apache.commons.httpclient.HttpClient#executeMethod(org.apache.commons.httpclient.HttpMethod)
*/
protected void executePostMethod(
HttpInvokerClientConfiguration config, HttpClient httpClient, PostMethod postMethod)
throws IOException {
httpClient.executeMethod(postMethod);
}
/**
* Validate the given response as contained in the PostMethod object,
* throwing an exception if it does not correspond to a successful HTTP response.
* <p>Default implementation rejects any HTTP status code beyond 2xx, to avoid
* parsing the response body and trying to deserialize from a corrupted stream.
* @param config the HTTP invoker configuration that specifies the target service
* @param postMethod the executed PostMethod to validate
* @throws IOException if validation failed
* @see org.apache.commons.httpclient.methods.PostMethod#getStatusCode()
* @see org.apache.commons.httpclient.HttpException
*/
protected void validateResponse(HttpInvokerClientConfiguration config, PostMethod postMethod)
throws IOException {
if (postMethod.getStatusCode() >= 300) {
throw new HttpException(
"Did not receive successful HTTP response: status code = " + postMethod.getStatusCode() +
", status message = [" + postMethod.getStatusText() + "]");
}
}
/**
* Extract the response body from the given executed remote invocation request.
* <p>The default implementation simply fetches the PostMethod's response body stream.
* If the response is recognized as GZIP response, the InputStream will get wrapped
* in a GZIPInputStream.
* @param config the HTTP invoker configuration that specifies the target service
* @param postMethod the PostMethod to read the response body from
* @return an InputStream for the response body
* @throws IOException if thrown by I/O methods
* @see #isGzipResponse
* @see java.util.zip.GZIPInputStream
* @see org.apache.commons.httpclient.methods.PostMethod#getResponseBodyAsStream()
* @see org.apache.commons.httpclient.methods.PostMethod#getResponseHeader(String)
*/
protected InputStream getResponseBody(HttpInvokerClientConfiguration config, PostMethod postMethod)
throws IOException {
if (isGzipResponse(postMethod)) {
return new GZIPInputStream(postMethod.getResponseBodyAsStream());
}
else {
return postMethod.getResponseBodyAsStream();
}
}
/**
* Determine whether the given response indicates a GZIP response.
* <p>The default implementation checks whether the HTTP "Content-Encoding"
* header contains "gzip" (in any casing).
* @param postMethod the PostMethod to check
* @return whether the given response indicates a GZIP response
*/
protected boolean isGzipResponse(PostMethod postMethod) {
Header encodingHeader = postMethod.getResponseHeader(HTTP_HEADER_CONTENT_ENCODING);
return (encodingHeader != null && encodingHeader.getValue() != null &&
encodingHeader.getValue().toLowerCase().contains(ENCODING_GZIP));
}
}

View File

@ -1,37 +0,0 @@
/*
* Copyright 2002-2012 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
*
* http://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.http.client;
import java.net.URI;
import org.junit.Test;
import org.springframework.http.HttpMethod;
@Deprecated
public class CommonsHttpRequestFactoryTests extends AbstractHttpRequestFactoryTestCase {
@Override
protected ClientHttpRequestFactory createRequestFactory() {
return new CommonsClientHttpRequestFactory();
}
@Test(expected=IllegalArgumentException.class)
public void httpPatch() throws Exception {
factory.createRequest(new URI(baseUrl + "/methods/PATCH"), HttpMethod.PATCH);
}
}