diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/AbstractHttpRequestExecutor.java b/spring-integration-http/src/main/java/org/springframework/integration/http/AbstractHttpRequestExecutor.java deleted file mode 100644 index 0ab160c1bb..0000000000 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/AbstractHttpRequestExecutor.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2002-2009 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.integration.http; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Base class for {@link HttpRequestExecutor} implementations. - * - * @author Mark Fisher - * @author Juergen Hoeller - * @since 1.0.2 - */ -public abstract class AbstractHttpRequestExecutor implements HttpRequestExecutor { - - protected static final String HTTP_HEADER_ACCEPT_LANGUAGE = "Accept-Language"; - - protected static final String HTTP_HEADER_ACCEPT_ENCODING = "Accept-Encoding"; - - protected static final String HTTP_HEADER_CONTENT_ENCODING = "Content-Encoding"; - - protected static final String HTTP_HEADER_CONTENT_TYPE = "Content-Type"; - - protected static final String HTTP_HEADER_CONTENT_LENGTH = "Content-Length"; - - protected static final String ENCODING_GZIP = "gzip"; - - - protected final Log logger = LogFactory.getLog(getClass()); - - private boolean acceptGzipEncoding = true; - - - /** - * Set whether to accept GZIP encoding, that is, whether to - * send the HTTP "Accept-Encoding" header with "gzip" as value. - *

Default is "true". Turn this flag off if you do not want - * GZIP response compression even if enabled on the HTTP server. - */ - public void setAcceptGzipEncoding(boolean acceptGzipEncoding) { - this.acceptGzipEncoding = acceptGzipEncoding; - } - - /** - * Return whether to accept GZIP encoding, that is, whether to - * send the HTTP "Accept-Encoding" header with "gzip" as its value. - */ - public boolean isAcceptGzipEncoding() { - return this.acceptGzipEncoding; - } - - /** - * Execute a request to send its content to its target URL. - * @param request the request to execute - * @return the HttpResponse result - * @throws IOException if thrown by I/O operations - * @throws Exception in case of general errors - */ - public final HttpResponse executeRequest(HttpRequest request) throws Exception { - if (logger.isDebugEnabled()) { - StringBuilder sb = new StringBuilder("Sending HTTP request to [" + request.getTargetUrl() + "]"); - Integer contentLength = request.getContentLength(); - if (contentLength != null) { - sb.append(", with size " + contentLength); - } - logger.debug(sb.toString()); - } - return doExecuteRequest(request); - } - - /** - * Subclasses must implement this method to execute the request. - */ - protected abstract HttpResponse doExecuteRequest(HttpRequest request) throws Exception; - - - /** - * Default implementation of {@link HttpResponse}. - */ - class DefaultHttpResponse implements HttpResponse { - - private final InputStream body; - - private final Map> headers; - - - public DefaultHttpResponse(InputStream body, Map> headers) { - this.body = body; - this.headers = (headers != null) ? headers : Collections.>emptyMap(); - } - - - public InputStream getBody() { - return this.body; - } - - public String getFirstHeader(String key) { - List values = this.headers.get(key); - return (values != null && values.size() > 0) ? values.get(0) : null; - } - - public Map> getHeaders() { - return this.headers; - } - - public List getHeaders(String key) { - return this.headers.get(key); - } - } - -} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/CommonsHttpRequestExecutor.java b/spring-integration-http/src/main/java/org/springframework/integration/http/CommonsHttpRequestExecutor.java deleted file mode 100644 index 64f5792cfa..0000000000 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/CommonsHttpRequestExecutor.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2002-2009 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.integration.http; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -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.HttpMethod; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; -import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; -import org.apache.commons.httpclient.methods.DeleteMethod; -import org.apache.commons.httpclient.methods.EntityEnclosingMethod; -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.context.i18n.LocaleContext; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Implementation of {@link HttpRequestExecutor} that uses a commons-http - * {@link HttpClient} to execute {@link HttpRequest} instances. - * - * @author Mark Fisher - * @author Juergen Hoeller - * @since 1.0.2 - */ -public class CommonsHttpRequestExecutor extends AbstractHttpRequestExecutor { - - /** - * 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 CommonsHttpRequestExecutor 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 CommonsHttpRequestExecutor() { - this.httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); - this.setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS); - } - - /** - * Create a new CommonsHttpRequestExecutor 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 CommonsHttpRequestExecutor(HttpClient httpClient) { - this.setHttpClient(httpClient); - } - - - /** - * Set the HttpClient instance to use for this request executor. - */ - public void setHttpClient(HttpClient httpClient) { - Assert.notNull(httpClient, "httpClient must not be null"); - this.httpClient = httpClient; - } - - /** - * Return the HttpClient instance that this request executor uses. - */ - public HttpClient getHttpClient() { - return this.httpClient; - } - - /** - * Set the socket read timeout for the underlying HttpClient. A value of 0 - * means never 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) { - if (timeout < 0) { - throw new IllegalArgumentException("timeout must be a non-negative value"); - } - this.httpClient.getHttpConnectionManager().getParams().setSoTimeout(timeout); - } - - @Override - protected HttpResponse doExecuteRequest(HttpRequest request) throws Exception { - HttpMethod httpMethod = createHttpMethod(request); - try { - if (httpMethod instanceof EntityEnclosingMethod) { - setRequestBody((EntityEnclosingMethod) httpMethod, request.getBody(), request.getContentType()); - } - executeHttpMethod(getHttpClient(), httpMethod); - validateResponse(httpMethod); - return new DefaultHttpResponse(readResponseBody(httpMethod), getResponseHeaders(httpMethod)); - } - finally { - // Need to explicitly release because it might be pooled. - httpMethod.releaseConnection(); - } - } - - /** - * Create a HttpMethod for the given {@link HttpRequest}. - *

This implementation creates an HttpMethod with the request's target - * URL as well as the "Accept-Language" and "Accept-Encoding" headers. If - * the method is "POST" or "PUT", the "Content-Type" header will also be - * set as specified in the given request. - * @param request the HTTP request to create a method for - * @return the HttpMethod instance - */ - private HttpMethod createHttpMethod(HttpRequest request) { - String url = request.getTargetUrl().toString(); - String methodName = request.getRequestMethod(); - HttpMethod httpMethod = null; - if ("GET".equals(methodName)) { - httpMethod = new GetMethod(url); - } - else if ("POST".equals(methodName)) { - httpMethod = new PostMethod(url); - } - else if ("PUT".equals(methodName)) { - httpMethod = new PutMethod(url); - } - else if ("DELETE".equals(methodName)) { - httpMethod = new DeleteMethod(url); - } - else if ("TRACE".equals(methodName)) { - httpMethod = new TraceMethod(url); - } - else if ("HEAD".equals(methodName)) { - httpMethod = new HeadMethod(url); - } - else if ("OPTIONS".equals(methodName)) { - httpMethod = new OptionsMethod(url); - } - else { - throw new UnsupportedOperationException("unsupported request method '" + methodName + "'"); - } - LocaleContext locale = LocaleContextHolder.getLocaleContext(); - if (locale != null) { - httpMethod.addRequestHeader(HTTP_HEADER_ACCEPT_LANGUAGE, StringUtils.toLanguageTag(locale.getLocale())); - } - if (isAcceptGzipEncoding()) { - httpMethod.addRequestHeader(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP); - } - if (httpMethod instanceof EntityEnclosingMethod) { - String contentType = request.getContentType(); - if (contentType != null) { - httpMethod.addRequestHeader(HTTP_HEADER_CONTENT_TYPE, contentType); - } - } - return httpMethod; - } - - /** - * Set the given byte stream as the request body. - *

This implementation simply sets the byte stream as the - * EntityEnclosingMethod's request body. This can be overridden, for - * example, to write a specific encoding and potentially set appropriate - * HTTP request headers. - * @param httpMethod the EntityEnclosingMethod on which to set the request body - * @param baos the ByteArrayOutputStream that contains the content - * @param contentType the request body's content type - * @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 - */ - private void setRequestBody( - EntityEnclosingMethod httpMethod, ByteArrayOutputStream baos, String contentType) - throws IOException { - httpMethod.setRequestEntity(new ByteArrayRequestEntity(baos.toByteArray(), contentType)); - } - - /** - * Execute the given HttpMethod instance. - * @param httpClient the HttpClient responsible for execution - * @param httpMethod the HttpMethod to be executed - * @throws IOException if thrown by I/O methods - * @see org.apache.commons.httpclient.HttpClient#executeMethod(org.apache.commons.httpclient.HttpMethod) - */ - private void executeHttpMethod(HttpClient httpClient, HttpMethod httpMethod) throws IOException { - httpClient.executeMethod(httpMethod); - } - - /** - * Validate the given response as contained in the HttpMethod object, - * throwing an exception if it does not correspond to a successful HTTP response. - *

This implementation rejects any HTTP status code beyond 2xx, to avoid - * parsing the response body and trying to read from a corrupted stream. - * @param httpMethod the executed HttpMethod to validate - * @throws IOException if validation failed - * @see org.apache.commons.httpclient.methods.PostMethod#getStatusCode() - * @see org.apache.commons.httpclient.HttpException - */ - private void validateResponse(HttpMethod httpMethod) throws IOException { - if (httpMethod.getStatusCode() >= 300) { - throw new HttpException( - "Did not receive successful HTTP response from [" + httpMethod.getURI() + - "]: status code = " + httpMethod.getStatusCode() + - ", status message = [" + httpMethod.getStatusText() + "]"); - } - } - - /** - * Extract the response body from the given executed request. - *

This implementation simply fetches the HttpMethod's response - * body stream. If the response is recognized as a GZIP response, the - * InputStream will be wrapped in a GZIPInputStream. - * @param httpMethod the HttpMethod from which to read the response body - * @return an InputStream for the response body, or null if no response stream is available - * @throws IOException if thrown by I/O methods - * @see #isGzipResponse - * @see java.util.zip.GZIPInputStream - * @see org.apache.commons.httpclient.HttpMethod#getResponseBodyAsStream() - */ - private InputStream readResponseBody(HttpMethod httpMethod) throws IOException { - byte[] responseBody = httpMethod.getResponseBody(); - InputStream responseStream = null; - if (responseBody != null) { - responseStream = new ByteArrayInputStream(responseBody); - if (isGzipResponse(httpMethod)) { - responseStream = new GZIPInputStream(responseStream); - } - } - return responseStream; - } - - private Map> getResponseHeaders(HttpMethod httpMethod) { - Map> headers = new HashMap>(); - for (Header header : httpMethod.getResponseHeaders()) { - String name = header.getName(); - String value = header.getValue(); - List values = headers.get(name); - if (values == null) { - values = new ArrayList(); - } - values.add(value); - headers.put(name, values); - } - return Collections.unmodifiableMap(headers); - } - - /** - * Determine whether the given response indicates a GZIP response. - *

This implementation checks whether the HTTP "Content-Encoding" - * header contains "gzip" (in any casing). - * @param httpMethod the HttpMethod to check - * @return whether the given response indicates a GZIP response - * @see org.apache.commons.httpclient.HttpMethod#getResponseHeader(String) - */ - private boolean isGzipResponse(HttpMethod httpMethod) { - Header encodingHeader = httpMethod.getResponseHeader(HTTP_HEADER_CONTENT_ENCODING); - return (encodingHeader != null && encodingHeader.getValue() != null - && encodingHeader.getValue().toLowerCase().indexOf(ENCODING_GZIP) != -1); - } - -} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequest.java b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequest.java deleted file mode 100644 index 9d55b20493..0000000000 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2002-2009 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.integration.http; - -import java.io.ByteArrayOutputStream; -import java.net.URL; - -/** - * Representation of an HTTP request to be executed by an implementation of - * the {@link HttpRequestExecutor} strategy. - * - * @author Mark Fisher - * @since 1.0.2 - */ -public interface HttpRequest { - - /** - * Return the target URL for this request. - */ - URL getTargetUrl(); - - /** - * Return the request method ("GET", "POST", etc). - */ - String getRequestMethod(); - - /** - * Return the content type for requests. - */ - String getContentType(); - - /** - * Return the content length if known, else null. - */ - Integer getContentLength(); - - /** - * Return the request body as a {@link ByteArrayOutputStream}, - * or null if this request has no body content. - */ - ByteArrayOutputStream getBody(); - -} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutor.java b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutor.java deleted file mode 100644 index bef208c105..0000000000 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutor.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2002-2009 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.integration.http; - -/** - * Strategy for executing an http request response exchange with a remote server. - * - * @author Iwein Fuld - * @author Mark Fisher - * @since 1.0.2 - */ -public interface HttpRequestExecutor { - - HttpResponse executeRequest(HttpRequest request) throws Exception; - -} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/SimpleHttpRequestExecutor.java b/spring-integration-http/src/main/java/org/springframework/integration/http/SimpleHttpRequestExecutor.java deleted file mode 100644 index 88e53f1849..0000000000 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/SimpleHttpRequestExecutor.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2002-2009 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.integration.http; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.List; -import java.util.Map; -import java.util.zip.GZIPInputStream; - -import org.springframework.context.i18n.LocaleContext; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.StringUtils; - -/** - * Implementation of {@link HttpRequestExecutor} that uses {@link HttpURLConnection} - * directly. This version has limited functionality but no additional dependencies. - * For more features, see {@link CommonsHttpRequestExecutor}. - * - * @author Juergen Hoeller - * @author Iwein Fuld - * @author Mark Fisher - * @since 1.0.2 - */ -public class SimpleHttpRequestExecutor extends AbstractHttpRequestExecutor { - - @Override - protected HttpResponse doExecuteRequest(HttpRequest request) throws Exception { - HttpURLConnection connection = this.openConnection(request.getTargetUrl()); - this.prepareConnection(connection, request); - this.writeRequestBody(connection, request.getBody()); - this.validateResponse(connection); - InputStream responseBody = this.readResponseBody(connection); - return new DefaultHttpResponse(responseBody, this.getResponseHeaders(connection)); - } - - /** - * Open an HttpURLConnection for the given request URL. - * @return the HttpURLConnection for the given request - * @throws IOException if thrown by I/O methods - * @see java.net.URL#openConnection() - */ - private HttpURLConnection openConnection(URL url) throws IOException { - URLConnection connection = url.openConnection(); - if (!(connection instanceof HttpURLConnection)) { - throw new IOException("target URL [" + url + "] is not an HTTP URL"); - } - return (HttpURLConnection) connection; - } - - /** - * Prepare the given HTTP connection. - *

- * The request method (e.g. "POST), "Content-Type" header, and content - * length will be determined from the provided {@link HttpRequest}. - * @param connection HttpURLConnection the connection to prepare - * @param request HttpRequest for which the connection should be prepared - * @throws IOException if thrown by HttpURLConnection methods - * @see java.net.HttpURLConnection#setRequestMethod - * @see java.net.HttpURLConnection#setRequestProperty - */ - private void prepareConnection(HttpURLConnection connection, HttpRequest request) throws IOException { - connection.setDoInput(true); - String requestMethod = request.getRequestMethod(); - if ("PUT".equals(requestMethod) || "POST".equals(requestMethod)) { - connection.setDoOutput(true); - } - else { - connection.setDoOutput(false); - } - connection.setRequestMethod(request.getRequestMethod()); - String contentType = request.getContentType(); - if (contentType != null) { - connection.setRequestProperty(HTTP_HEADER_CONTENT_TYPE, contentType); - } - Integer contentLength = request.getContentLength(); - if (contentLength != null) { - connection.setRequestProperty(HTTP_HEADER_CONTENT_LENGTH, contentLength.toString()); - } - LocaleContext locale = LocaleContextHolder.getLocaleContext(); - if (locale != null) { - connection.setRequestProperty(HTTP_HEADER_ACCEPT_LANGUAGE, - StringUtils.toLanguageTag(locale.getLocale())); - } - if (isAcceptGzipEncoding()) { - connection.setRequestProperty(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP); - } - } - - private void writeRequestBody(HttpURLConnection connection, ByteArrayOutputStream body) throws IOException { - if (body != null) { - byte[] bytes = body.toByteArray(); - if (bytes.length > 0) { - FileCopyUtils.copy(bytes, connection.getOutputStream()); - } - } - } - - private void validateResponse(HttpURLConnection connection) throws IOException { - if (connection.getResponseCode() >= 300) { - throw new IOException( - "Did not receive successful HTTP response from [" + connection.getURL() + - "]: status code = " + connection.getResponseCode() + - ", status message = [" + connection.getResponseMessage() + "]"); - } - } - - /** - * Extract the response body from the connection after the request has - * been successfully executed. - *

- * This implementation simply reads the HttpURLConnection's InputStream. - * If the response is recognized as GZIP response, the InputStream will be - * wrapped in a GZIPInputStream. - * @param connection the HttpURLConnection 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 java.net.HttpURLConnection#getInputStream() - */ - private InputStream readResponseBody(HttpURLConnection connection) throws IOException { - if (isGzipResponse(connection)) { - // GZIP response found - need to unzip. - return new GZIPInputStream(connection.getInputStream()); - } - else { - // Plain response found. - return connection.getInputStream(); - } - } - - private Map> getResponseHeaders(HttpURLConnection connection) { - return connection.getHeaderFields(); - } - - /** - * Determine whether the given response is a GZIP response. - *

- * This implementation checks whether the HTTP "Content-Encoding" header - * contains "gzip" (in any casing). - * @param connection the HttpURLConnection to check - */ - private boolean isGzipResponse(HttpURLConnection connection) { - String encodingHeader = connection.getHeaderField(HTTP_HEADER_CONTENT_ENCODING); - return (encodingHeader != null - && encodingHeader.toLowerCase().indexOf(ENCODING_GZIP) != -1); - } - -}