【问题标题】:Message channels one or many?消息渠道一个还是多个?
【发布时间】:2015-12-29 16:47:36
【问题描述】:

我需要处理来自大约 30 个地址的电子邮件。我以一种方式实现这一点,即所有电子邮件都发送到DirectChannel,然后发送到Receiver。在Receiver 中,我可以了解消息来自什么地址,为此我创建了CustomMessageSource,它将javax.mail.Message 包装成我自己的类型,其中包含javax.mail.Message 和一些Enum。看起来这不是一个好的决定,因为我可以使用@Transformer,但如果我只有 1 个频道,我该如何使用它?

这是第一个问题。

第二个问题:

我应该为所有地址使用 ONE 频道和 ONE 接收器吗?或者更好地为每个邮件地址设置频道和接收者?我对 Spring 的理解并不深,无法感受其中的不同。

附言这个问题是Spring multiple imapAdapter的延续@

【问题讨论】:

    标签: email spring-boot spring-integration channel


    【解决方案1】:

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

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

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

    编辑

    我修改了对您上一个问题的回答,以在标题中使用 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

    而且这个更复杂一点;它从有效负载中提取 from 并将其放入标头中;您的用例不需要,因为您有完整的消息,但它说明了技术......

    @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);
    }
    

    【讨论】:

    • 再次感谢您的回答!所以如果我理解正确 - 我应该创建一个公共输出通道和许多输入通道?如果您可以为您的建议编写一些代码,那将是非常棒的,因为我是 Spring 的新手,不明白如何使用 @Header 以及我应该如何处理 input channel。看来我这里不需要@Transformer
    • 查看我的编辑;我不能继续为您编写代码,但我们确实认识到,在使用 Java 而不是 XML 配置组件时,文档有点简单;我们正在改进这方面的文档。
    • 在回复您的“我不需要@Transformer”评论时,标题丰富器是一种转换器。
    猜你喜欢
    • 1970-01-01
    • 2015-05-29
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-21
    相关资源
    最近更新 更多