You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2010/12/27 10:53:45 UTC
svn commit: r1053033 - in
/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4:
DefaultHttpBinding.java HttpComponent.java HttpConstants.java
HttpEndpoint.java HttpProducer.java
Author: davsclaus
Date: Mon Dec 27 09:53:44 2010
New Revision: 1053033
URL: http://svn.apache.org/viewvc?rev=1053033&view=rev
Log:
CAMEL-3218: Ported changes from camel-http to camel-http4
Added:
camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java
Modified:
camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java
camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java
camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java
camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java
Modified: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java?rev=1053033&r1=1053032&r2=1053033&view=diff
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java (original)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java Mon Dec 27 09:53:44 2010
@@ -19,15 +19,13 @@ package org.apache.camel.component.http4
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.Map;
-
import javax.activation.DataHandler;
-import javax.activation.FileDataSource;
-import javax.activation.FileTypeMap;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -54,48 +52,56 @@ public class DefaultHttpBinding implemen
private boolean useReaderForPayload;
private HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();
+ private HttpEndpoint endpoint;
+ @Deprecated
public DefaultHttpBinding() {
}
+ @Deprecated
public DefaultHttpBinding(HeaderFilterStrategy headerFilterStrategy) {
this.headerFilterStrategy = headerFilterStrategy;
}
+ public DefaultHttpBinding(HttpEndpoint endpoint) {
+ this.endpoint = endpoint;
+ this.headerFilterStrategy = endpoint.getHeaderFilterStrategy();
+ }
+
public void readRequest(HttpServletRequest request, HttpMessage message) {
// lets force a parse of the body and headers
message.getBody();
// populate the headers from the request
Map<String, Object> headers = message.getHeaders();
-
+
//apply the headerFilterStrategy
Enumeration names = request.getHeaderNames();
while (names.hasMoreElements()) {
- String name = (String)names.nextElement();
+ String name = (String) names.nextElement();
Object value = request.getHeader(name);
// mapping the content-type
if (name.toLowerCase().equals("content-type")) {
name = Exchange.CONTENT_TYPE;
}
if (headerFilterStrategy != null
- && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
+ && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
headers.put(name, value);
}
}
-
+
if (request.getCharacterEncoding() != null) {
headers.put(Exchange.HTTP_CHARACTER_ENCODING, request.getCharacterEncoding());
message.getExchange().setProperty(Exchange.CHARSET_NAME, request.getCharacterEncoding());
- }
+ }
- popluateRequestParameters(request, message);
+ populateRequestParameters(request, message);
// reset the stream cache
StreamCache cache = message.getBody(StreamCache.class);
if (cache != null) {
cache.reset();
}
-
+
// store the method and query and other info in headers
headers.put(Exchange.HTTP_METHOD, request.getMethod());
headers.put(Exchange.HTTP_QUERY, request.getQueryString());
@@ -103,23 +109,24 @@ public class DefaultHttpBinding implemen
headers.put(Exchange.HTTP_URI, request.getRequestURI());
headers.put(Exchange.HTTP_PATH, request.getPathInfo());
headers.put(Exchange.CONTENT_TYPE, request.getContentType());
-
- popluateAttachments(request, message);
+
+ populateAttachments(request, message);
}
-
- protected void popluateRequestParameters(HttpServletRequest request, HttpMessage message) {
+
+ protected void populateRequestParameters(HttpServletRequest request, HttpMessage message) {
//we populate the http request parameters without checking the request method
Map<String, Object> headers = message.getHeaders();
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
- String name = (String)names.nextElement();
+ String name = (String) names.nextElement();
Object value = request.getParameter(name);
if (headerFilterStrategy != null
- && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
+ && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
headers.put(name, value);
}
}
- if (request.getMethod().equals("POST") && request.getContentType() != null && request.getContentType().startsWith("application/x-www-form-urlencoded")) {
+ if (request.getMethod().equals("POST") && request.getContentType() != null
+ && request.getContentType().startsWith(HttpConstants.CONTENT_TYPE_WWW_FORM_URLENCODED)) {
String charset = request.getCharacterEncoding();
if (charset == null) {
charset = "UTF-8";
@@ -132,7 +139,7 @@ public class DefaultHttpBinding implemen
String name = URLDecoder.decode(pair[0], charset);
String value = URLDecoder.decode(pair[1], charset);
if (headerFilterStrategy != null
- && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
+ && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
headers.put(name, value);
}
}
@@ -141,8 +148,8 @@ public class DefaultHttpBinding implemen
}
}
}
-
- protected void popluateAttachments(HttpServletRequest request, HttpMessage message) {
+
+ protected void populateAttachments(HttpServletRequest request, HttpMessage message) {
// check if there is multipart files, if so will put it into DataHandler
Enumeration names = request.getAttributeNames();
while (names.hasMoreElements()) {
@@ -150,7 +157,7 @@ public class DefaultHttpBinding implemen
Object object = request.getAttribute(name);
if (object instanceof File) {
String fileName = request.getParameter(name);
- message.addAttachment(fileName, new DataHandler(new CamelFileDataSource((File)object, fileName)));
+ message.addAttachment(fileName, new DataHandler(new CamelFileDataSource((File) object, fileName)));
}
}
}
@@ -184,14 +191,22 @@ public class DefaultHttpBinding implemen
}
public void doWriteExceptionResponse(Throwable exception, HttpServletResponse response) throws IOException {
- response.setStatus(500); // 500 for internal server error
- response.setContentType("text/plain");
-
- // append the stacktrace as response
- PrintWriter pw = response.getWriter();
- exception.printStackTrace(pw);
-
- pw.flush();
+ // 500 for internal server error
+ response.setStatus(500);
+ if (endpoint != null && endpoint.isTransferException()) {
+ // transfer the exception as a serialized java object
+ response.setContentType(HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
+ ObjectOutputStream oos = new ObjectOutputStream(response.getOutputStream());
+ oos.writeObject(exception);
+ oos.flush();
+ IOHelper.close(oos);
+ } else {
+ // write stacktrace as plain text
+ response.setContentType("text/plain");
+ PrintWriter pw = response.getWriter();
+ exception.printStackTrace(pw);
+ pw.flush();
+ }
}
public void doWriteFaultResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException {
Modified: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java?rev=1053033&r1=1053032&r2=1053033&view=diff
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java (original)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java Mon Dec 27 09:53:44 2010
@@ -147,6 +147,7 @@ public class HttpComponent extends Heade
binding = resolveAndRemoveReferenceParameter(parameters, "httpBinding", HttpBinding.class);
}
Boolean throwExceptionOnFailure = getAndRemoveParameter(parameters, "throwExceptionOnFailure", Boolean.class);
+ Boolean transferException = getAndRemoveParameter(parameters, "transferException", Boolean.class);
Boolean bridgeEndpoint = getAndRemoveParameter(parameters, "bridgeEndpoint", Boolean.class);
Boolean matchOnUriPrefix = getAndRemoveParameter(parameters, "matchOnUriPrefix", Boolean.class);
Boolean disableStreamCache = getAndRemoveParameter(parameters, "disableStreamCache", Boolean.class);
@@ -158,7 +159,7 @@ public class HttpComponent extends Heade
URI endpointUri = URISupport.createRemainingURI(new URI(addressUri), CastUtils.cast(httpClientParameters));
// restructure uri to be based on the parameters left as we dont want to include the Camel internal options
URI httpUri = URISupport.createRemainingURI(new URI(addressUri), CastUtils.cast(parameters));
-
+
// validate http uri that end-user did not duplicate the http part that can be a common error
String part = httpUri.getSchemeSpecificPart();
if (part != null) {
@@ -190,6 +191,10 @@ public class HttpComponent extends Heade
if (throwExceptionOnFailure != null) {
endpoint.setThrowExceptionOnFailure(throwExceptionOnFailure);
}
+ // should we transfer exception as serialized object
+ if (transferException != null) {
+ endpoint.setTransferException(transferException);
+ }
if (bridgeEndpoint != null) {
endpoint.setBridgeEndpoint(bridgeEndpoint);
}
Added: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java?rev=1053033&view=auto
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java (added)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java Mon Dec 27 09:53:44 2010
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.component.http4;
+
+/**
+ * @version $Revision$
+ */
+public final class HttpConstants {
+
+ public static final String CONTENT_TYPE_JAVA_SERIALIZED_OBJECT = "application/x-java-serialized-object";
+ public static final String CONTENT_TYPE_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
+
+ private HttpConstants() {
+ }
+}
Modified: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java?rev=1053033&r1=1053032&r2=1053033&view=diff
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java (original)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java Mon Dec 27 09:53:44 2010
@@ -56,6 +56,7 @@ public class HttpEndpoint extends Defaul
private boolean matchOnUriPrefix;
private boolean chunked = true;
private boolean disableStreamCache;
+ private boolean transferException;
public HttpEndpoint() {
}
@@ -187,7 +188,7 @@ public class HttpEndpoint extends Defaul
public HttpBinding getBinding() {
if (binding == null) {
- binding = new DefaultHttpBinding(getHeaderFilterStrategy());
+ binding = new DefaultHttpBinding(this);
}
return binding;
}
@@ -279,4 +280,11 @@ public class HttpEndpoint extends Defaul
this.chunked = chunked;
}
+ public boolean isTransferException() {
+ return transferException;
+ }
+
+ public void setTransferException(boolean transferException) {
+ this.transferException = transferException;
+ }
}
Modified: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java?rev=1053033&r1=1053032&r2=1053033&view=diff
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java (original)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java Mon Dec 27 09:53:44 2010
@@ -19,6 +19,7 @@ package org.apache.camel.component.http4
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -60,6 +61,7 @@ public class HttpProducer extends Defaul
private static final transient Log LOG = LogFactory.getLog(HttpProducer.class);
private HttpClient httpClient;
private boolean throwException;
+ private boolean transferException;
public HttpProducer(HttpEndpoint endpoint) {
super(endpoint);
@@ -68,7 +70,7 @@ public class HttpProducer extends Defaul
}
public void process(Exchange exchange) throws Exception {
- if (((HttpEndpoint)getEndpoint()).isBridgeEndpoint()) {
+ if (getEndpoint().isBridgeEndpoint()) {
exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
}
HttpRequestBase httpRequest = createMethod(exchange);
@@ -87,7 +89,7 @@ public class HttpProducer extends Defaul
httpRequest.addHeader(entry.getKey(), headerValue);
}
}
-
+
// lets store the result in the output message.
HttpResponse httpResponse = null;
try {
@@ -121,7 +123,8 @@ public class HttpProducer extends Defaul
return (HttpEndpoint) super.getEndpoint();
}
- protected void populateResponse(Exchange exchange, HttpRequestBase httpRequest, HttpResponse httpResponse, Message in, HeaderFilterStrategy strategy, int responseCode) throws IOException {
+ protected void populateResponse(Exchange exchange, HttpRequestBase httpRequest, HttpResponse httpResponse,
+ Message in, HeaderFilterStrategy strategy, int responseCode) throws IOException, ClassNotFoundException {
Message answer = exchange.getOut();
answer.setHeaders(in.getHeaders());
@@ -142,26 +145,33 @@ public class HttpProducer extends Defaul
}
}
- protected HttpOperationFailedException populateHttpOperationFailedException(Exchange exchange, HttpRequestBase httpRequest, HttpResponse httpResponse, int responseCode) throws IOException {
- HttpOperationFailedException exception;
+ protected Exception populateHttpOperationFailedException(Exchange exchange, HttpRequestBase httpRequest, HttpResponse httpResponse, int responseCode) throws IOException, ClassNotFoundException {
+ Exception answer;
+
String uri = httpRequest.getURI().toString();
String statusText = httpResponse.getStatusLine() != null ? httpResponse.getStatusLine().getReasonPhrase() : null;
Map<String, String> headers = extractResponseHeaders(httpResponse.getAllHeaders());
- InputStream is = extractResponseBody(httpRequest, httpResponse, exchange);
+
+ Object responseBody = extractResponseBody(httpRequest, httpResponse, exchange);
+ if (transferException && responseBody != null && responseBody instanceof Exception) {
+ // if the response was a serialized exception then use that
+ return (Exception) responseBody;
+ }
+
// make a defensive copy of the response body in the exception so its detached from the cache
String copy = null;
- if (is != null) {
- copy = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, is);
+ if (responseBody != null) {
+ copy = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, responseBody);
}
Header locationHeader = httpResponse.getFirstHeader("location");
if (locationHeader != null && (responseCode >= 300 && responseCode < 400)) {
- exception = new HttpOperationFailedException(uri, responseCode, statusText, locationHeader.getValue(), headers, copy);
+ answer = new HttpOperationFailedException(uri, responseCode, statusText, locationHeader.getValue(), headers, copy);
} else {
- exception = new HttpOperationFailedException(uri, responseCode, statusText, null, headers, copy);
+ answer = new HttpOperationFailedException(uri, responseCode, statusText, null, headers, copy);
}
- return exception;
+ return answer;
}
/**
@@ -198,10 +208,10 @@ public class HttpProducer extends Defaul
* Extracts the response from the method as a InputStream.
*
* @param httpRequest the method that was executed
- * @return the response as a stream
+ * @return the response either as a stream, or as a deserialized java object
* @throws IOException can be thrown
*/
- protected static InputStream extractResponseBody(HttpRequestBase httpRequest, HttpResponse httpResponse, Exchange exchange) throws IOException {
+ protected static Object extractResponseBody(HttpRequestBase httpRequest, HttpResponse httpResponse, Exchange exchange) throws IOException, ClassNotFoundException {
HttpEntity entity = httpResponse.getEntity();
if (entity == null) {
return null;
@@ -219,16 +229,40 @@ public class HttpProducer extends Defaul
is = GZIPHelper.uncompressGzip(contentEncoding, is);
}
// Honor the character encoding
+ String contentType = null;
header = httpRequest.getFirstHeader("content-type");
if (header != null) {
- String contentType = header.getValue();
+ contentType = header.getValue();
// find the charset and set it to the Exchange
HttpHelper.setCharsetFromContentType(contentType, exchange);
}
- return doExtractResponseBody(is, exchange);
+ InputStream response = doExtractResponseBodyAsStream(is, exchange);
+ if (contentType != null && contentType.equals(HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT)) {
+ return doDeserializeJavaObjectFromResponse(response);
+ } else {
+ return response;
+ }
}
- private static InputStream doExtractResponseBody(InputStream is, Exchange exchange) throws IOException {
+ private static Object doDeserializeJavaObjectFromResponse(InputStream response) throws ClassNotFoundException, IOException {
+ if (response == null) {
+ LOG.debug("Cannot deserialize response body as java object as there are no response body.");
+ return null;
+ }
+
+ Object answer = null;
+ ObjectInputStream ois = new ObjectInputStream(response);
+ try {
+ answer = ois.readObject();
+ } finally {
+ IOHelper.close(ois);
+ }
+
+ return answer;
+ }
+
+
+ private static InputStream doExtractResponseBodyAsStream(InputStream is, Exchange exchange) throws IOException {
// As httpclient is using a AutoCloseInputStream, it will be closed when the connection is closed
// we need to cache the stream for it.
try {
@@ -248,8 +282,9 @@ public class HttpProducer extends Defaul
* @param exchange the exchange
* @return the created method as either GET or POST
* @throws URISyntaxException is thrown if the URI is invalid
- * @throws org.apache.camel.InvalidPayloadException is thrown if message body cannot
- * be converted to a type supported by HttpClient
+ * @throws org.apache.camel.InvalidPayloadException
+ * is thrown if message body cannot
+ * be converted to a type supported by HttpClient
*/
protected HttpRequestBase createMethod(Exchange exchange) throws URISyntaxException, InvalidPayloadException {
String url = HttpProducerHelper.createURL(exchange, getEndpoint());
@@ -298,8 +333,9 @@ public class HttpProducer extends Defaul
*
* @param exchange the exchange with the IN message with data to send
* @return the data holder
- * @throws org.apache.camel.InvalidPayloadException is thrown if message body cannot
- * be converted to a type supported by HttpClient
+ * @throws org.apache.camel.InvalidPayloadException
+ * is thrown if message body cannot
+ * be converted to a type supported by HttpClient
*/
protected HttpEntity createRequestEntity(Exchange exchange) throws InvalidPayloadException {
Message in = exchange.getIn();
@@ -326,9 +362,9 @@ public class HttpProducer extends Defaul
// do not fallback to use the default charset as it can influence the request
// (for example application/x-www-form-urlencoded forms being sent)
String charset = IOConverter.getCharsetName(exchange, false);
- answer = new StringEntity((String)data, charset);
+ answer = new StringEntity((String) data, charset);
if (contentType != null) {
- ((StringEntity)answer).setContentType(contentType);
+ ((StringEntity) answer).setContentType(contentType);
}
}
@@ -338,7 +374,7 @@ public class HttpProducer extends Defaul
in.getMandatoryBody(InputStream.class);
answer = new InputStreamEntity(in.getBody(InputStream.class), -1);
if (contentType != null) {
- ((InputStreamEntity)answer).setContentType(contentType);
+ ((InputStreamEntity) answer).setContentType(contentType);
}
}
}