Finally, I found the error - thanks for helping anyway ;)
It's a camel bug (2.4., 2.6) affecting the classes
org.apache.camel.component.http.DefaultHttpBinding
org.apache.camel.component.http4.DefaultHttpBinding
method readRequest needs to check null-values, as POST requests may not
set any headers.
...
Map<String, Object> headers = message.getHeaders();
Enumeration names = request.getHeaderNames();
while (names.hasMoreElements()) {
String name = (String)names.nextElement();
Object value = request.getHeader(name);
...
As a workaround you need to write a custom http binding as described in
the camel-component docs. The attached file works for me, calling
super() in case there are headers, otherwise we need to leave out fancy
header evaluation and message transformation (we do not have access to
some private props)
cheers, Knut
On 23.03.2011 02:46, Knut Enners wrote:
Hi,
basically I need to implement a service to which xml-documents are send
via http post. Afterwards they should get routed to a JMS queue.
Problem: whatever I post to the service results in the Exception:
(curl -v -d file.xml 'http://localhost:4443/to2-service/sendMessage' ;
http get requests are answered)
java.lang.ArrayIndexOutOfBoundsException: 1
at
org.apache.camel.component.http.DefaultHttpBinding.populateRequestParameters(DefaultHttpBinding.java:159)[198:org.apache.camel.camel-http:2.6.0.fuse-00-00]
at
org.apache.camel.component.http.DefaultHttpBinding.readRequest(DefaultHttpBinding.java:100)[198:org.apache.camel.camel-http:2.6.0.fuse-00-00]
at
org.apache.camel.component.http.HttpMessage.<init>(HttpMessage.java:46)[198:org.apache.camel.camel-http:2.6.0.fuse-00-00]
...
Here is a simplified version that leads to the same error:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route>
<from uri="jetty:http://0.0.0.0:4443/service?matchOnUriPrefix=true"/>
<log message="Copying ${file:name} to the output directory"/>
<to uri="file:data/output"/>
</route>
</camelContext>
</blueprint>
Servicemix: apache-servicemix-4.3.0 and apache-servicemix-4.3.1-fuse-00-00
I already played around with converting to String or StreamSource and
setting options like disableStreamCache... without luck.
With apache-servicemix-4.2.0 everything works fine, but I run into
following issue on the JMS side:
http://servicemix.396122.n5.nabble.com/java-lang-ClassNotFoundException-org-apache-camel-component-jms-JmsComponent-when-using-camel-from-u-td3413867.html
How can I get around this? Have I configured s.th. wrong, should I
implement the stuff with servicemix-xyz components or try to get
activemq running with apache-servicemix-4.2.0?
thanks und regards,
Knut
package your.packagename;
import java.io.InputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.camel.Exchange;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.StreamCache;
import org.apache.camel.component.http.DefaultHttpBinding;
import org.apache.camel.component.http.HttpConstants;
import org.apache.camel.component.http.HttpMessage;
import org.apache.camel.component.http.helper.HttpHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @version $Revision$
* @author Knut Enners
* From camel 2.4 we need a bug-workaround as http post requests
* with empty headers will break the camel route
*/
public class CustomHttpBinding extends DefaultHttpBinding {
private static final transient Log LOG = LogFactory.getLog(CustomHttpBinding.class);
@Override
public void readRequest(HttpServletRequest request, HttpMessage message) {
// in case there are headers we can safely use the original method
if (request.getHeaderNames() != null) {
super.readRequest(request, message);
}
// otherwise we bypass the fancy header evaluation stuff and leave out de-serialization
// lets force a parse of the body and headers
message.getBody();
// populate the headers from the request
Map<String, Object> headers = message.getHeaders();
if (request.getCharacterEncoding() != null) {
headers.put(Exchange.HTTP_CHARACTER_ENCODING, request.getCharacterEncoding());
message.getExchange().setProperty(Exchange.CHARSET_NAME, request.getCharacterEncoding());
}
try {
populateRequestParameters(request, message);
} catch (UnsupportedEncodingException e) {
throw new RuntimeCamelException("Cannot read request parameters due " + e.getMessage(), e);
}
Object body = message.getBody();
// reset the stream cache if the body is the instance of StreamCache
if (body instanceof StreamCache) {
((StreamCache)body).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());
headers.put(Exchange.HTTP_URL, request.getRequestURL());
headers.put(Exchange.HTTP_URI, request.getRequestURI());
headers.put(Exchange.HTTP_PATH, request.getPathInfo());
headers.put(Exchange.CONTENT_TYPE, request.getContentType());
populateAttachments(request, message);
}
}