Apache Camel - Marshalling within Rest DSL to Json

James :

I'm trying to process a csv file using the Rest DSL in Camel.

I'm getting some odd behaviour when I split the CSV and Marshall to a JSON. Here is my code:

@Component
public class
ProcessHandler extends RouteBuilder {

    @Override
    protected void defineRoute() throws Exception {

        DataFormat csv = new BindyCsvDataFormat(CsvModel.class);

        rest("/")
                .post().produces("application/json")
                .route()

                .unmarshal(csv)
                .split(body()).parallelProcessing().streaming()
                .marshal().json(JsonLibrary.Gson)
                .filter().jsonpath("$[?(@.counter==3)]")
                .log("${body}")

However I get the error message: Error during type conversion from type: java.lang.String to the required type: byte[] with value [CsvModel(....

However if I edit the route as follows:

@Component
public class
ProcessHandler extends RouteBuilder {

    @Override
    protected void defineRoute() throws Exception {

        DataFormat csv = new BindyCsvDataFormat(CsvModel.class);

        rest("/")
                .post().produces("application/json")
                .route()

                .unmarshal(csv)
                .marshal().json(JsonLibrary.Gson)
                .split(body()).parallelProcessing().streaming()
                //.filter().jsonpath("$[?(@.counter==3)]")
                .log("${body}")

It works ok.

However then I'm obviously not able to process my message correctly as it's marshalled to byte representation. The route also works fine if it's not using the Rest DSL, so I'm assuming the issue is with the http response. If I try the following:

@Component
public class
ProcessHandler extends RouteBuilder {

    @Override
    protected void defineRoute() throws Exception {

        DataFormat csv = new BindyCsvDataFormat(CsvModel.class);

        rest("/")
                .post().produces("application/json")
                .route()

                .unmarshal(csv)
                .marshal().json(JsonLibrary.Gson)

                .split(body()).parallelProcessing().streaming()
                .unmarshal().json(JsonLibrary.Gson)
                .filter().jsonpath("$[?(@.counter==3)]")
                .marshal().json(JsonLibrary.Gson)
                .log("${body}")

I get the same error. Is it possible to normalise the format, make some processing steps and then return a Json? Am I going wrong somewhere - I would appreciate understanding why this happens?

Hassam Abdelillah :

It may be more easy and hence comprehensible if you implement an aggregation strategy with your filtering within instead of using JsonPath.

Indeed, the split() methid if used by default will not give the results you are expecting

Here is an example :

@Component
public class ProcessHandler extends RouteBuilder {

            @Override
            protected void defineRoute() throws Exception {

            DataFormat csv = new BindyCsvDataFormat(CsvModel.class);

            rest("/")
                    .post().produces("application/json")
                         .route()
                              .unmarshal(csv)
                              .split().method(ItemsSplittingStrategy.class, "splitItems")
                                  .parallelProcessing()
                                  .marshal().json(JsonLibrary.Gson)
                              .end()
                    .to("file:/file.json");
    }
}

And in your ItemsSplittingStrategy class, do you filtering. You can find a simple, explicit example here

Also i invite you to check all the features that can be use for splitter and aggregator and their combinaison.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=154255&siteId=1