Search code examples
kotlinapache-camelspring-camel

How to automatically convert from org.apache.camel.converter.stream.InputStreamCache to Pojo using Jackson in a Spring Boot Camel Kotlin application


In a Spring Boot 2.7. Camel 3.20.x project written in Kotlin I have a REST endpoint that receives a JSON payload. I've added the Camel Jackson dependency to deal with JSON<->POJO transformation:

        <dependency>
            <groupId>org.apache.camel.springboot</groupId>
            <artifactId>camel-jackson-starter</artifactId>
            <version>${camel.version}</version>
        </dependency>
data class Payment(val iban: String, val amount: Float)
    rest("/payments")
            .post("/")
            .to("direct:processPayment")

    from("direct:processPayment")
            .log("Body \${body}")
            .log("Body \${body.getClass()}")

These are the logs of the route:

Body {"payment":{"iban":"ABCD","amount":150.0}}
Body class org.apache.camel.converter.stream.InputStreamCache

As you can see the body is correctly displayed as String, however, the type is InputStreamCache instead of my Payment DTO.

I updated the route to unmarshall the body to the Payment DTO:

    from("direct:processPayment")
        .unmarshal().json(JsonLibrary.Jackson, Payment::class.java)
        .log("Body \${body}")
        .log("Body \${body.getClass()}")

This fails with:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `xxx.Payment` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

Why isn't the conversion working?


Solution

  • The encountered error has nothing to see with Camel nor Spring, but is directly related to Jackson.

    As the error message indicates it, the reason is that the Payment pojo does not satisfy the requirement of having a default (parameterless) constructor.