Search code examples
javaspringspring-cloudspring-cloud-streamspring-messaging

How to receive GenericMessage with Object payload instead of string from MessageCollector


I try to test message sending and receiving via spring-cloud-stream using MessageCollector.

When i am using native java serialization for stream cloud all works fine, but when i change serialization to json, MessageCollector returns me GenericMessage with string payload instead of SomeObject payload.

Configuration is

  cloud.stream.default.contentType=application/json 

Test case:

    Message outMsg = new GenericMessage<SomeObject>(new SomeObject(1));
    someChannel.send(outMsg);
    GenericMessage<SomeObject> inMsg = (GenericMessage<SomeObject>) messageCollector.forChannel(someChannel).poll();

    Assert.assertTrue(inMsg.getPayload() instanceof SomeObject);

As a result Assertions is false. inMsg contains string payload (the string contains valid json representation of SomeObject).

And my question is: How can i receive GenericMessage with SomeObject payload from MessageCollector?

production environment works fine without explicitly mapping to SomeObject.


Solution

  • But that's correct. The channel is for output to the messaging broker. So, we have just serialized your payload into the JSON and it is ready to be delivered. That's why you use everything OK in production because you have a messaging broker in between and the proper deserializer for the input on another side. This messageCollector approach is exactly for assertion what we are going to send to the broker, so adding some additional deserialization functionality is out of scope this utility.

    Only what I may suggest you is to use Jackson ObjectMapper directly on the payload after receiving inMsg from the collector:

    Message outMsg = new GenericMessage<SomeObject>(new SomeObject(1));
    someChannel.send(outMsg);
    GenericMessage<String> inMsg = (GenericMessage<String>) messageCollector.forChannel(someChannel).poll();
    SomeObject someObject = new ObjectMapper().readValue(inMsg.getPayload(), SomeObject.class);
    
    Assert.assertTrue(someObject instanceof SomeObject);