Camel SpringBoot POST returning Object NOT JSON

Viewed 721

I am completely new to Camel, I have created two simple REST end points(using Camel 3.8.0 and SpringBoot 2.4.3), one GET and one POST, like this -

@Component
public class CamelController extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        restConfiguration()
                .component("servlet")
                .port(8080)
                .host("127.0.0.1")
                .bindingMode(RestBindingMode.json);

        rest().post("/order")
                .produces(MediaType.APPLICATION_JSON_VALUE)
                .type(Order.class)
                .outType(Order.class)
                .to("bean:orderService?method=addOrder(${body})");

        rest().get("/order")
                .produces(MediaType.APPLICATION_JSON_VALUE)
                .to("bean:orderService?method=getOrders()");

    }
}

When I call GET on http://localhost:8080/order I am getting an array of JSON(as expected), like this -

[
  {
    "id": 1,
    "name": "Pencil",
    "price": 100.0
  },
  {
    "id": 2,
    "name": "Pen",
    "price": 300.0
  },
  {
    "id": 3,
    "name": "Book",
    "price": 350.0
  }
]

But, when I make a POST request on http://localhost:8080/order with input

{
    "name": "A4 Papers",
    "price": 55.5
}

Then it is returning Object, like -

Order(id=6, name=A4 Papers, price=55.5)

How can I make it to return JSON? Like -

{
    "id": 6,
    "name": "A4 Papers",
    "price": 55.5
}

My pom.xml

 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.3</version>
    <relativePath/>
</parent>

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>

    <camelVersion>3.8.0</camelVersion>
</properties>

<dependencies>
    <!-- SpringBoot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Camel -->
    <dependency>
        <groupId>org.apache.camel.springboot</groupId>
        <artifactId>camel-spring-boot-bom</artifactId>
        <version>${camelVersion}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jackson</artifactId>
        <version>${camelVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-servlet-starter</artifactId>
        <version>${camelVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel.springboot</groupId>
        <artifactId>camel-spring-boot-starter</artifactId>
        <version>${camelVersion}</version>
    </dependency>

    <!-- Others -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.18</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

My complete code is he - https://github.com/crsardar/hands-on-java/tree/master/hands-on-camel-springboot

How can I make the POST API to return JSON?

3 Answers

Your output data is a As you are using outType, your data which is an object of type Order is getting mapped into an arraylist. You need to convert your data explicitly into json format.

rest()
  .post("/order")
  .produces(MediaType.APPLICATION_JSON_VALUE)
  .type(Order.class)
  .route()
    .to("bean:orderService?method=addOrder(${body})")
    .marshal().json(JsonLibrary.Jackson);

Add marshaling before hitting API.

rest().post("/order")
.produces(MediaType.APPLICATION_JSON_VALUE)
.marshal().json(JsonLibrary.Jackson, Order.class)
.to("bean:orderService?method=addOrder(${body})");

I pulled your project on the referenced Github url: https://github.com/crsardar/hands-on-java/tree/master/hands-on-camel-springboot and found that it throws an error at compilation time due to the camel-servlet-starter

<dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-servlet-starter</artifactId>
   <version>${camel.version}</version>
</dependency>

enter image description here

I then proceeded to update it to use the following dependency:

<dependency>
   <groupId>org.apache.camel.springboot</groupId>
   <artifactId>camel-servlet-starter</artifactId>
   <version>${camel.version}</version>
</dependency>

Once I imported this dependency I was able to get the project running, and I tested the POST endpoint http://localhost:8080/camel/order and was getting the expected output

enter image description here

resulting in me not doing any code changes and yet getting the result you wanted, also one thing I've noticed in your yml file you use the /camel as your context-path yet in your above question you don't use in your rest call, leading me to believe that there is a project version mismatch.

Based on your question and the Github project you referenced above and also the investigation I did, hope this assists.

Related