消息通道一个或多个?

时间:2015-10-01 15:02:16

标签: email spring-boot spring-integration channel

我需要处理来自大约30个地址的电子邮件。我实现这一点的方式是所有电子邮件都转到DirectChannel之后和Receiver之后。在Receiver我可以理解消息来自哪个地址,为此我创建CustomMessageSourcejavax.mail.Message包装到我自己的包含javax.mail.MessageEnum的类型中}。看起来这不是一个好的决定,因为我可以使用@Transformer,但如果我只有一个频道,我该如何使用呢?

这是第一个问题。

第二个问题:

我应该为所有地址使用 ONE 频道和 ONE 接收器吗?或者更好的是为每个邮件地址设置频道和接收器?我不太了解Spring,感受到差异。

P.S。这个问题是Spring multiple imapAdapter

的延续

1 个答案:

答案 0 :(得分:1)

在每个子上下文中,您可以添加标头扩充器以将自定义标头设置为来自适配器的URL;输出通道是共享服务的共享通道。

在服务中,使用void foo(Message emailMessage, @Header("myHeader") String url)

我通常建议使用单一服务,除非服务需要根据来源做完全不同的事情。

修改

我修改了您之前问题的答案,以使用标题中的网址增强原始邮件;每个实例都有自己的头文件,它们都将丰富的邮件路由到公共emailChannel

@Configuration
@EnableIntegration
public class GeneralImapAdapter {

    @Value("${imap.url}")
    String imapUrl;

    @Bean
    public static PropertySourcesPlaceholderConfigurer pspc() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    @InboundChannelAdapter(value = "enrichHeadersChannel", poller = @Poller(fixedDelay = "10000") )
    public MessageSource<javax.mail.Message> mailMessageSource(MailReceiver imapMailReceiver) {
        return new MailReceivingMessageSource(imapMailReceiver);
    }

    @Bean
    public MessageChannel enrichHeadersChannel() {
        return new DirectChannel();
    }

    @Bean
    @Transformer(inputChannel="enrichHeadersChannel", outputChannel="emailChannel")
    public HeaderEnricher enrichHeaders() {
        Map<String, ? extends HeaderValueMessageProcessor<?>> headersToAdd =
                Collections.singletonMap("emailUrl", new StaticHeaderValueMessageProcessor<>(this.imapUrl));
        HeaderEnricher enricher = new HeaderEnricher(headersToAdd);
        return enricher;
    }

    @Bean
    public MailReceiver imapMailReceiver() {
        MailReceiver receiver = mock(MailReceiver.class);
        Message message = mock(Message.class);
        when(message.toString()).thenReturn("Message from " + this.imapUrl);
        Message[] messages = new Message[] {message};
        try {
            when(receiver.receive()).thenReturn(messages);
        }
        catch (MessagingException e) {
            e.printStackTrace();
        }
        return receiver;
    }

}

...我修改了接收服务,以便它可以访问标题......

@MessageEndpoint
public class EmailReceiverService {

    @ServiceActivator(inputChannel="emailChannel")
    public void handleMessage(Message message, @Header("emailUrl") String url) {
        System.out.println(message + " header:" + url);
    }

}

...希望有所帮助。

编辑2

这个更复杂一点;它从有效载荷中拉出并将其放入标题中;您的用例不需要,因为您有完整的消息,但它说明了该技术......

@Bean
@Transformer(inputChannel="enrichHeadersChannel", outputChannel="emailChannel")
public HeaderEnricher enrichHeaders() {
    Map<String, HeaderValueMessageProcessor<?>> headersToAdd = new HashMap<>();
    headersToAdd.put("emailUrl", new StaticHeaderValueMessageProcessor<String>(this.imapUrl));
    Expression expression = new SpelExpressionParser().parseExpression("payload.from[0].toString()");
    headersToAdd.put("from", new ExpressionEvaluatingHeaderValueMessageProcessor<>(expression, String.class));
    HeaderEnricher enricher = new HeaderEnricher(headersToAdd);
    return enricher;
}

@ServiceActivator(inputChannel="emailChannel")
public void handleMessage(Message message, @Header("emailUrl") String url,
                                           @Header("from") String from) {
    System.out.println(message + " header:" + url + " from:" + from);
}