wst
wst

Reputation: 4338

Spring Cloud Stream message JSON conversion is not working

I followed my previous question Spring Cloud Stream message from/to JSON conversion configuration and configured stream as described, yet, I can't make it work correctly.

My setup is as follows. I have two apps A and B. App A uses input channel one, output two. App B uses input two. Channel two is configured with content type application/json.

App A. Properties.

spring.cloud.stream.bindings.input.destination=one
spring.cloud.stream.bindings.input.group=default

spring.cloud.stream.bindings.output.destination=two
spring.cloud.stream.bindings.output.content-type=application/json

Listener method.

@ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
public Dto handle(byte[] payload) throws IOException {
    final Dto dto = new ObjectMapper().readValue(payload, Dto.class);
    logger.info("{}", dto);
    dto.setId(dto.getId() + 1000);
    return dto;
}

App B. Properties.

spring.cloud.stream.bindings.input.destination=two
spring.cloud.stream.bindings.input.group=default
spring.cloud.stream.bindings.input.content-type=application/json

Listener method.

@ServiceActivator(inputChannel = Sink.INPUT)
public void handle(Dto dto) throws IOException {
    logger.info("DTO {}", dto);
}

When I manually send a message with proper JSON string to channel one, it is processed correctly and send to channel two as a JSON message (headers exactly the same as described in above mentioned question). After that, it's received on channel two by App B and exception is thrown: Method handle(java.lang.String) cannot be found

Of course when I create both methods, handling Dto and String as an input, it works, but always String method is invoked and have to deserialize the payload by myself.

Am I mistaken somewhere? How do I setup method with such signature: public Dto handle(Dto incoming)?

Upvotes: 3

Views: 5961

Answers (2)

Bashar Ali Labadi
Bashar Ali Labadi

Reputation: 1074

if use @StreamListener you don't have to use the answer way, but you have to remove (don't specify anything, otherwise it will be a json string):

spring.cloud.stream.bindings.input.content-type=application/json

from AppB properties

source (old docs but still valid): https://docs.spring.io/spring-cloud-stream/docs/Brooklyn.RELEASE/reference/html/contenttypemanagement.html#__literal_streamlistener_literal_and_message_conversion

Upvotes: 0

Alexander
Alexander

Reputation: 50

You should change the content-type declaration of input of AppB to

application/x-java-object;type=your.package.Dto.

As it is specified in your question, of course you accept JSON strings only.

Upvotes: 2

Related Questions