How to invoke a REST call (POST with JSON body) from Camel in Java DSL

JStefan picture JStefan · Oct 4, 2013 · Viewed 13.6k times · Source

Having the following working Camel flow setup in a ServletContextListener in a Web project running on IBM WebSphere, an incoming XML is converted to JSON and printed to the System.out and printed to the report.txt. So far so good.

@WebListener
public class SetupCamel implements ServletContextListener {

    private CamelContext camelContext;

@Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("SetupCamel:contextInitialized - enter");
        try {
            Context ctx = new InitialContext();
            QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("jms/TestConnectionFactory");

            camelContext = new DefaultCamelContext();

            JmsConfiguration jmsConfiguration = new JmsConfiguration(qcf);
            JmsComponent jmsComponent = new JmsComponent(jmsConfiguration);
            camelContext.addComponent("jms", jmsComponent);

            final XmlJsonDataFormat xmlJsonFormat = new XmlJsonDataFormat();
            xmlJsonFormat.setEncoding("UTF-8");
            xmlJsonFormat.setForceTopLevelObject(false);
            xmlJsonFormat.setTrimSpaces(true);
            xmlJsonFormat.setRootName("newRoot");
            xmlJsonFormat.setSkipNamespaces(true);
            xmlJsonFormat.setRemoveNamespacePrefixes(true);

            camelContext.addRoutes(new RouteBuilder() {
                public void configure() {
                    onException(Exception.class)
                    .to("log:GeneralError?level=ERROR")
                    .end();

                    from("jms:queue:TestQueue?concurrentConsumers=1")
                    .marshal(xmlJsonFormat)
                    .to("file:/tmp/messages?fileName=report.txt&fileExist=Append")
                    .to("stream:out")
                    ;
                }
            });
            camelContext.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("SetupCamel:contextInitialized - leaving");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("SetupCamel:contextDestroyed - enter");
        try {
            if (camelContext != null) {
                camelContext.stop();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("SetupCamel:contextDestroyed - leaving");
    }
}

I have to extend the flow to POST the JSON to a REST service/consumer. (The Rest resource is tested and works..)

Searching (web)documentation doesn't give me a good/complete Java DSL example that I'm able to use. Based upon what I did find, I think it should be something similar to adding a endpoint like:

.to("cxfrs://http://localhost:9080/WebContext/TestResource") 

But this doesn't work and I don't understand how to set the converted JSON as body and make it a POST request. There is also no exception printed.

How can I add the REST call as a POST with JSON body in this flow ?

Running in IBM WebSphere v8.5.5, IBM jdk 1.7x, Camel 2.11.2

The following jar files are in the WEB-INF/lib classpath:

camel-core-2.11.2.jar
camel-cxf-2.11.2.jar
camel-cxf-transport-2.11.2.jar
camel-jms-2.11.2.jar
camel-servletlistener-2.11.2.jar
camel-spring-2.11.2.jar
camel-stream-2.11.2.jar
camel-xmljson-2.11.2.jar
com.ibm.ws.prereq.jackson.jar
commons-beanutils-1.8.0.jar
commons-collections-3.2.1.jar
commons-lang-2.5.jar
commons-logging-1.1.1.jar
cxf-api-2.7.6.jar
cxf-rt-frontend-jaxrs-2.7.6.jar
ezmorph-1.0.6.jar
json-lib-2.4-jdk15.jar
slf4j-api-1.7.5.jar
spring-beans-3.1.4.RELEASE.jar
spring-context-3.1.4.RELEASE.jar
spring-core-3.1.4.RELEASE.jar
spring-jms-3.1.4.RELEASE.jar
spring-tx-3.1.4.RELEASE.jar
xom-1.2.5.jar

Thanks.

Answer

Willem Jiang picture Willem Jiang · Dec 9, 2013

If you just want to post the JSON message to the REST service, you don't need to use camel-cxfrs component, as you already has the request message body, you just need to use camel-http endpoint to send the request.

So the route could be

from("jms:queue:TestQueue?concurrentConsumers=1")
                    .marshal(xmlJsonFormat)
                    .to("http://localhost:9080/WebContext/TestResource");