7 Replies Latest reply on Jan 15, 2013 5:44 AM by milanmilas

    Camel and best practice of using POJO

    milanmilas

      Hi,

       

      I've been playing with camel for a month and went from PAYLOAD to POJO format.

      I want to use this one as objects I will be getting are going to be complex.

       

      I still have questions and don't have clear picture how to use it.

       

      When getting exchange from cxf:pojo I can use:

      MessageContentsList msgList = (MessageContentsList)exchange.getIn().getBody();

      Person person = (Person)msgList.get(0);

      to get my Person object (class generated by plugin).

       

      I am not sure now to push it to ActiveMQ, using xstream?

       

      As well I am not sure how to deserialise object on another ESB where camel is reading from

      ActiveMQ as I will need reference to Person class?

      What if first ESB with ActiveMQ is third party project and in second ESB I am reading from

      that ActiveMQ in Camel?

       

      Is there a way in java to do Deserialisation/Unmarshaling without having reference to java class type?

        • 1. Re: Camel and best practice of using POJO
          davsclaus

          Hi

           

          Just a note you can get the person a bit quicker using

          Person person = exchange.getIn().getBody(Person.class);
          

           

          When you use CXF in POJO mode, you may have generated the source code from a wsdl file using wsdl2java. If so the generated code has JAXB annotations on the source code.

           

          This allows you to automatic transform the POJO to/from XML using JAXB. So you do not need to use xstream etc.

           

          So when you send the POJO to a JMS queue, then Camel will send the message depending on the type of the message body. So a POJO will be send as a javax.jms.ObjectMessage. But you want that as XML text instead, so you can either do:

           

          Convert the message to XML before sending to JMS, eg

           

          <route>
            ...
            <convertBodyTo type="String"></convertBodyTo>
            <to uri="activemq:queue:foo"></to>
          </route>
          

           

          Or you can configure the JMS/ActiveMQ endpoint with the type you want, using the jmsMessageType option eg

          <route>
            ...
            <to uri="activemq:queue:foo?jmsMessageType=Text"></to>
          </route>
          

           

          • 2. Re: Camel and best practice of using POJO
            davsclaus

            Just a note, you would need to have camel-jaxb on the classpath. This is automatic installed if using Fuse ESB.

             

            camel-jaxb allows Camel to seamless convert data from JAXB to/from XML.

            • 3. Re: Camel and best practice of using POJO
              milanmilas

              using<convertBodyTo type="String"/>

              -


               

                      <log message="$"/>         <convertBodyTo type="String"/>         <log message="Converted body to string"/>         <inOnly uri="activemq:topic:Producer"/> -


              org.apache.camel.InvalidPayloadException: No body available of type: java.lang.String but has value: of type: org.apache.cxf.message.MessageContentsList on: Message: . Caused by: No type converter available to convert from type: org.apache.cxf.message.MessageContentsList to the required type: java.lang.String with value . Exchange[Message: ]. Caused by: [org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type: org.apache.cxf.message.MessageContentsList to the required type: java.lang.String with value ] org.apache.camel.InvalidPayloadException: No body available of type: java.lang.String but has value: of type: org.apache.cxf.message.MessageContentsList on: Message: . Caused by: No type converter available to convert from type: org.apache.cxf.message.MessageContentsList to the required type: java.lang.String with value . Exchange[Message: [com.all ocatesoftware.pocesb.Person@e38a55]]. Caused by: [org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type: org.apache.cxf.message.MessageContentsList to the required type: java.lang.String with value ] using <inOnly uri="activemq:topic:Producer?jmsMessageType=Text"/> -
              producer: <inOnly uri="activemq:topic:Producer?jmsMessageType=Text"/> consumer: <route id="consumerCxf">         <from uri="activemqconsumercxf:queue:Consumer?jmsMessageType=Text"/>         <log message="With Camel Headers"/>         <log message="$"/>         <log message="$"/>

              -


              There is no exception but body is null.

               

              If I try to use:

                 

               

              I am getting error:

              org.apache.camel.InvalidPayloadException: No body available of type: java.lang.String but has value: of type: org.apache.cxf.message.MessageContentsList on: Message: . Caused by: No type converter available to convert from type: org.apache.cxf.message.MessageContentsList to the required type: java.lang.String with value . Exchange[Message: ]. Caused by: [org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type: org.apache.cxf.message.MessageContentsList to the required type: java.lang.String

               

              I know body is MessageContentsList where first element i the list is Person but in every

              example on internet only from().marshall() is used.

               

              Is there example on the web where I can see how someone is pushing data to CXF with

              POJO and after that to the Queue and back?

               

              Edited by: milanmilas on Jan 14, 2013 10:58 AM

               

              Edited by: milanmilas on Jan 14, 2013 10:59 AM

              • 4. Re: Camel and best practice of using POJO
                milanmilas

                -

                 

                Edited by: milanmilas on Jan 15, 2013 10:35 AM

                • 5. Re: Camel and best practice of using POJO
                  milanmilas

                  -

                   

                  Edited by: milanmilas on Jan 15, 2013 10:44 AM

                  • 6. Re: Camel and best practice of using POJO
                    davsclaus

                    Hi

                     

                    Ah yeah camel-cxf is unforuntaly using that internal MessageContextList that complicates things.

                     

                    You can convert to the POJO class instead first

                    <convertBodyTo type="com.pocesb.Person"/>
                    

                     

                    Then the message contains the POJO class, and then you can convert that to a String afterwards. So you do 2x conversions.

                    <convertBodyTo type="String"/>
                    

                     

                    Though you can omit the String convertBodyTo, if you configure the JMS endpoint with jmsMessageType=Text, which tells Camel to force converting to String when sending the message to the JMS message queue.

                    • 7. Re: Camel and best practice of using POJO
                      milanmilas

                      First step works fine:

                       

                          jaxb prettyPrint="false" contextPath="com.pocesb"

                          partClass="com.pocesb.Person"

                          fragment="true"

                          partNamespace="Person" />

                       

                       

                      Thanks for help, it took me too much time to understand all this.

                       

                      Edited by: milanmilas on Jan 15, 2013 10:45 AM

                       

                      Edited by: milanmilas on Jan 15, 2013 10:46 AM

                       

                      Edited by: milanmilas on Jan 15, 2013 10:51 AM