Apache Camel JSON Marshalling to POJO Java Bean

29,594

Solution 1

My impression is that your actual issue isn't about marshalling (which should be entirely straightforward), but about processing a response after having routed the message using choice(). You need to close the choice() block using end() (assuming the result of each branch will be processed in the same way), then make sure the response gets written to the out message body in the last step of the route.

Anyway, here is an example I've just tested:

public class JacksonTestRoute extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("jetty:http://localhost:8181/foo").to("direct:foo");

        from("direct:foo")
        .unmarshal().json(JsonLibrary.Jackson, Foo.class)
        .choice()
            .when().simple("${body.foo} == 'toto'")
                .log("sending to beanA")
                .to("bean:beanA")
            .otherwise()
                .log("sending to beanB")
                .to("bean:beanB")
        // close the choice() block :
        .end()
        // per the javadoc for marshall(), "the output will be added to the out body" :
        .marshal().json(JsonLibrary.Jackson);
    }
}

public class Foo {
    private String foo; // Constructor and accessor omitted for brevity
}

public class Bar1 {
    private String bar1; // Constructor and accessor omitted for brevity
}

public class Bar2 {
    private String bar2; // Constructor and accessor omitted for brevity
}

public class BeanA {
    public Bar1 doSomething(final Foo arg) {
        return new Bar1(arg.getFoo() + "A");
    }
}

public class BeanB {
    public Bar2 doSomething(final Foo arg) {
        return new Bar2(arg.getFoo() + "B");
    }
}

POSTing {"foo":"toto"} returns {"bar1":"totoA"} (and logs sending to beanA).

POSTing {"foo":"titi"} returns {"bar2":"titiB"} (and logs sending to beanB).

Solution 2

It is as simple as this .marshal().json(JsonLibrary.Jackson) (this is what you want)

Share:
29,594
bicster
Author by

bicster

Updated on January 09, 2020

Comments

  • bicster
    bicster over 4 years

    I think I have a simple question, but can't seem to figure it out.

    I'm invoking a POJO with a class created from unmarshalling JSON as the parameter for the method. The question is, how do I marshal the return from the method back to JSON?

    My route is below;

    from("direct:start")
     .choice()
      .when(header("methodname").isEqualTo("listCases"))
       .unmarshal().json(JsonLibrary.Jackson, UserDetails.class)
       .to("bean:com.xxx.BeanA")
      .when(header("methodName").isEqualTo("listPersons"))
       .unmarshal().json(JsonLibrary.Jackson, CaseDetails.class)
       .to("bean:com.xxx.BeanB");
    

    ...and I'm invoking the route by the below;

    ProducerTemplate template = camelContext.createProducerTemplate();
    template.setDefaultEndpoint(camelContext.getEndpoint("direct:start"));
    InvocationResult result = (InvocationResult)template.requestBodyAndHeader(payload, "methodName", methodName);
    

    Payload is JSON, and the methodName is either listCases or listPersons in this example.

    My InvocationResult class is generic and contains a String returnCode attribute as well as an object reference to the object I would like to be converted to JSON. This object will be different depending on whether listCases or listPersons is executed.

    Thanks,

    Bic

  • bicster
    bicster over 7 years
    I tried that, but it doesn't take effect; from("direct:start") .choice() .when(header("methodname").isEqualTo("listCases")) .unmarshal().json(JsonLibrary.Jackson, UserDetails.class) .to("bean:com.xxx.BeanA") .when(header("methodName").isEqualTo("listPersons")) .unmarshal().json(JsonLibrary.Jackson, CaseDetails.class) .to("bean:com.xxx.BeanB") .marshal().json(JsonLibrary.Jackson); My InvocationResult object is returned as is, neither it nor any of its attributes are converted to JSON format - what am I missing?