2

Here is if do so: body -> string -> user

    .to("direct:httpClient")
    .process(new Processor() {
        @Override
        public void process(Exchange exchange) throws JsonProcessingException {
            String body = exchange.getIn().getBody(String.class);
            User[] users = jacksonDataFormat.getObjectMapper().readValue(body, User[].class);
        }
    })

This option works great, but if you do this:

User [] body = exchange.getIn().getBody(User[].class);

body -> user, it doesn't work. User always null.

For clarity:

from("timer://test?period=2000")
                .setHeader(Exchange.HTTP_METHOD).constant(HttpMethod.GET)
                .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
                .convertBodyTo(User[].class)
                .to("http://localhost:8085/api/user")
                .process(exchange -> System.out.println(exchange.getIn().getBody(String.class)))

Console output:

[
   {
      "name":"BLA"
   },
   {
      "name":"BLA"
   },
   {
      "name":"BLA"
   }
]

If so:

from("timer://test?period=2000")
                .setHeader(Exchange.HTTP_METHOD).constant(HttpMethod.GET)
                .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
                .convertBodyTo(User[].class)
                .to("http://localhost:8085/api/user")
                .process(exchange -> System.out.println(exchange.getIn().getBody(User[].class)))

Console output: null

What is the reason? how can I fix this?

Denis Denis
  • 77
  • 1
  • 9

2 Answers2

1

The first option deserializes a String that is a JSON payload to Objects. It uses Jacksons ObjectMapper to do this.

Camel > get body as String
Jackson > parse String to JSON and deserialize it to Objects

The second option does not use Jackson, it has no clue about JSON it tries to cast the payload to User objects. But this does not work, because the payload is a JSON String.

I assume it does something similar like this

if (body instanceof User[]) {
    return (User[]) body;
} else {
    return null;
}

Therefore the return value is null because Camel can't find a User array in the body.

If you tell Camel what datatype you expect in the message body but the body does not contain this datatype, Camel returns null.

burki
  • 6,741
  • 1
  • 15
  • 31
  • how to adequately correct this in order to immediately deserialize into a user object? – Denis Denis Feb 03 '21 at 08:17
  • As long as you receive a JSON payload, you have to use a JSON library to deserialize it. There is no "direct way" to do this. But it is worth it, JSON is portable (works nearly everywhere) and pretty lightweight. Java serialization only works Java-to-Java and couples client and server very tight. – burki Feb 03 '21 at 09:28
  • It is very strange, look here https://stackoverflow.com/questions/65978493/apache-camel-when-deserializing-an-object-it-throws-an-exception-com-fasterxml, one of the problems was solved with the help new JacksonDataFormat(User[].class) – Denis Denis Feb 03 '21 at 12:52
  • I think it must have a solution, otherwise it's terrible code – Denis Denis Feb 03 '21 at 13:07
  • 1
    Wait, is your question why you have to extract the body as string and deserialize it in a second step? I thought you ask why you have to use Jackson – burki Feb 03 '21 at 14:43
  • The question is why it is not possible to do deserialization in user immediately – Denis Denis Feb 03 '21 at 14:56
  • I have extended my answer a bit. If this still not answers your question, please explain your question more exactly. – burki Feb 04 '21 at 06:37
  • Thank you, the correct answer was given above, it was necessary to add unmarshalling – Denis Denis Feb 04 '21 at 08:04
1

If you want Camel to handle the JSON string to Java object process, you can add it as a marshaller - https://camel.apache.org/components/latest/dataformats/jacksonxml-dataformat.html

dfrugg
  • 26
  • 1