2

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?

silentsudo
  • 6,730
  • 6
  • 39
  • 81
CR Sardar
  • 921
  • 2
  • 17
  • 32

3 Answers3

0

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);
Sneharghya Pathak
  • 990
  • 1
  • 9
  • 19
  • This will give an out like - "W3siaWQiOjEsIm5hbWUiOiJQZW5jaWwiLCJwcmljZSI6MTAwLjB9LHsiaWQiOjIsIm5hbWUiOiJQZW4iLCJwcmljZSI6MzAwLjB9LHsiaWQiOjMsIm5hbWUiOiJCb29rIiwicHJpY2UiOjM1MC4wfSx7ImlkIjo1LCJuYW1lIjoiQTQgUGFwZXJzIiwicHJpY2UiOjU1LjV9XQ==" – CR Sardar Mar 05 '21 at 09:58
  • this is a base64 encoding of the json output. Remove the .bindingMode(RestBindingMode.json) from your restConfiguration – Sneharghya Pathak Mar 05 '21 at 17:12
  • If we remove " .bindingMode(RestBindingMode.json) " we will get Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: org.apache.camel.converter.stream.InputStreamCache to the required type: com.crsardar.java.dao.Order with value org.apache.camel.converter.stream.InputStreamCache@76aca0ca at org.apache.camel.impl.converter.CoreTypeConverterRegistry.mandatoryConvertTo(CoreTypeConverterRegistry.java:275) at org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluateParameterValue(MethodInfo.java:713) ... 53 more – CR Sardar Mar 07 '21 at 08:29
0

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})");
karthick M
  • 192
  • 1
  • 13
  • Sorry, it is not working. The code mentioned by you, having compilation error. My complete code is he - https://github.com/crsardar/hands-on-java/tree/master/hands-on-camel-springboot please pull and check – CR Sardar Mar 08 '21 at 08:49
  • did u override any tostring method in order class ? seems working for me @CRSardar – karthick M Mar 08 '21 at 10:42
  • No buddy, It is as in the repo, I am changing only in "public class CamelController extends RouteBuilder" as you mentioned. Do you have GitHub repository? Can you please share your codes in GutHub? – CR Sardar Mar 08 '21 at 13:39
  • https://github.com/karthick-mr/camel-test/edit/master/README.md.. for me camel version was throwing error.. so used a different version.. it works for me – karthick M Mar 08 '21 at 14:28
0

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.

mpho mahase
  • 136
  • 5
  • Thanks for your response. Yes, I you are correct. I have fixed this in latest version of it. Thanks. But, in any version, on my system, there it was always working fine, without any error. Whatever, Thank you so much. – CR Sardar Mar 14 '21 at 21:19