erj2code
erj2code

Reputation: 311

How do I convert the map returned to Camel into JSON?

This seems like such a simple thing to do, yet I can't seem to find it in the Camel documentation.

Related to my last question i.e., Get BeanCreationException when try to add Jackson Library I now have my code putting the JMS logging response messages into JSON format.

Here's what I currently get when I run my code:

23118 [hello.world.request.timer] INFO  hello.world.request  - Exchange[Id:e93861e4-    a5be-4d63-b658-5939f414e595, ExchangePattern:InOnly, Properties:    {CamelToEndpoint=log://hello.world.request?showAll=true, CamelTimerFiredTime=Fri Oct 11     12:03:20 EDT 2013, CamelTimerPeriod=10000, CamelTimerName=hello.world.request.timer},     Headers:{firedTime=Fri Oct 11 12:03:20 EDT 2013}, BodyType:null, Body:null, Out: null]

Returning Map
key= fruit1DataType, value= String
key= fruit1, value= apple
key= fruit1Calories, value= 95
key= fruit1ColorDataType, value= String
key= fruit1CaloriesDataType, value= int
key= fruit1Color, value= red
23122 [hello.world.request.timer] INFO  hello.world.response  - Exchange[Id:e93861e4-    a5be-4d63-b658-5939f414e595, ExchangePattern:InOnly, Properties:    {CamelToEndpoint=log://hello.world.response?showAll=true, CamelTimerFiredTime=Fri Oct 11     12:03:20 EDT 2013, CamelTimerPeriod=10000, CamelTimerName=hello.world.request.timer},     Headers:{firedTime=Fri Oct 11 12:03:20 EDT 2013}, BodyType:byte[], Body:    {"fruit1DataType":"String","fruit1":"apple","fruit1Calories":"95","fruit1ColorDataType":"St    ring","fruit1CaloriesDataType":"int","fruit1Color":"red"}, Out: null]

Ideally I'd just like to have Camel convert the contents of the map returned to JSON and print it to the console like this:

{"fruit1DataType":"String","fruit1":"apple","fruit1Calories":"95","fruit1ColorDataType":"String","fruit1CaloriesDataType":"int","fruit1Color":"red"}, Out: null]

How do I modify my applicationContext.xml to have Camel do this?

Here's my current applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <bean
        class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
    <context:component-scan base-package="sample" />
    <context:annotation-config />

    <camel:camelContext id="HelloWorldContext">

        <!-- Add Jackson library to render Java Map into JSON -->
        <camel:dataFormats>
          <camel:json id="jack" library="Jackson"/>
        </camel:dataFormats>

        <camel:route>
            <!-- sends a request to the hello world JMS queue every 10 seconds -->
            <camel:from
                uri="timer://hello.world.request.timer?fixedRate=true&amp;period=10000" />
            <camel:to uri="log:hello.world.request?level=INFO?showAll=true" />
            <camel:bean ref="helloWorld" />

            <!-- now print out the map in JSON format -->
            <camel:marshal ref ="jack"/>
            <camel:to uri="log:hello.world.response?level=INFO?showAll=true" />
        </camel:route>

    </camel:camelContext>

    <bean id="jms" class="org.apache.activemq.camel.component.ActiveMQComponent">
        <property name="configuration" ref="jmsConfig" />
    </bean>

    <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
        <property name="connectionFactory" ref="jmsConnectionFactory" />
        <property name="transacted" value="false" />
        <property name="concurrentConsumers" value="1" />
    </bean>

    <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="vm://localhost" />
        <property name="redeliveryPolicy" ref="redeliveryPolicy" />
        <property name="prefetchPolicy" ref="prefetchPolicy" />
    </bean>

    <bean id="prefetchPolicy" class="org.apache.activemq.ActiveMQPrefetchPolicy">
        <property name="queuePrefetch" value="5" />
    </bean>

    <bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
        <property name="maximumRedeliveries" value="1" />
        <property name="backOffMultiplier" value="2" />
        <property name="initialRedeliveryDelay" value="2000" />
    </bean>

</beans>

Upvotes: 1

Views: 12682

Answers (2)

Douglas Ianitsky
Douglas Ianitsky

Reputation: 167

You can do it in an easy way:

<route>
    <from id="from1" uri="anyway" />
    <marshal id="_marshal1">
        <json library="Jackson"/>
    </marshal>
    <log id="_log1" message="${body}"/>
    <to id="_to1" uri="mock:foo"/>
</route>

And import the dependency in .pom

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-jackson</artifactId>
    <version>2.9.2</version>
</dependency>

Upvotes: 0

Vidya
Vidya

Reputation: 30310

You need a Camel JSON endpoint in your route to serialize your Map to JSON. The link also shows how you can choose which serializer (Jackson is the best choice in my opinion) to use in your endpoint.

Something like this (not exact)

<camelContext>
        <dataFormats>
            <json id="serializer" library="Jackson"/>
        </dataFormats>
        <route>
            <from uri="servlet:///test-camel"/>
            <to uri="bean:someSpringBean"/>
            <to uri="bean:anotherSpringBean"/>
            <marshal ref="serializer"/>
        </route>            
</camelContext>

Note that the json element also takes an attribute called unmarshalTypeName for the type to serialize from/deserialize to. However, this defaults to Map as described in the link mentioned above. Since you have a Map, you don't need to specify.

Upvotes: 1

Related Questions