Jan R. Krejci
Jan R. Krejci

Reputation: 119

Transform Header and payload to Json nodes

I am trying to enrich payload with some Headers keys and convert to a json structure like that:

{
 "Header": { ["key" : "value", "key2": "value"]}
 "Payload": { "attribute" : "value" }
}

My gateway is configured like this:

    @MessagingGateway 
public static interface MailService {
    @Gateway(requestChannel = "mail.input")
    void sendMail(String body, @Headers Map<String,String> headers);        
}

Here is my flow:

@Bean 
public IntegrationFlow errorFlow(){
    return IntegrationFlows.from(recoveryChannel())
                            .transform("payload.failedMessage")                             
                            .enrichHeaders(c -> c.header(FileHeaders.FILENAME, "emailErrors.json"))
                            .handle(this.fileOutboundAdapter())
                            .get();
}

How could I solve this issue?

Thanks.

Upvotes: 1

Views: 2160

Answers (2)

Gary Russell
Gary Russell

Reputation: 174504

@SpringBootApplication
public class So41223173Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(So41223173Application.class, args);
        context.getBean("flow.input", MessageChannel.class)
                .send(new ErrorMessage(new MessagingException(new GenericMessage<>(new Foo()))));
        context.close();
    }

    @Bean
    public IntegrationFlow flow() {
        return f -> f.transform("payload.failedMessage")
                .enrichHeaders(c -> c.header("foo", "bar"))
                .transform(toMap(), "transform")
                .transform(Transformers.toJson())
                .handle(m -> System.out.println(m.getPayload()));
    }

    @Bean
    public Transformer toMap() {
        return new AbstractTransformer() {

            @Override
            protected Object doTransform(Message<?> message) throws Exception {
                Map<String, Object> map = new LinkedHashMap<>();
                Map<String, Object> headers = new LinkedHashMap<>(message.getHeaders());
                headers.remove(MessageHeaders.ID);
                headers.remove(MessageHeaders.TIMESTAMP);
                map.put("headers", headers);
                map.put("payload", message.getPayload());
                return map;
            }

        };

    }

    public static class Foo {

        String bar = "bar";

        public String getBar() {
            return this.bar;
        }

        public void setBar(String bar) {
            this.bar = bar;
        }

    }

}

result

{"headers":{"foo":"bar"},"payload":{"bar":"bar"}}

Upvotes: 0

Artem Bilan
Artem Bilan

Reputation: 121177

To convert the whole message to the JSON, you should do something like this:

.handle((p, h) -> MessageBuilder.withPayload(new GenericMessage<>(p, h)))
.transform(Transformers.toJson())

The trick is like Transformers.toJson() doesn't care about headers and transforms only payload. So, we have to hack it a bit placing the whole message to the payload.

Since ServiceActivator (ground floor of the .handle()) returns message as is if the result is Message<?> , we don't have choice unless provide MessageBuilder and Transformers.toJson() will have all the info for your use-case.

Upvotes: 2

Related Questions