异常时的 Spring Integration 电子邮件重新投递

Posted

技术标签:

【中文标题】异常时的 Spring Integration 电子邮件重新投递【英文标题】:Spring Integration Email Redelivery on Exception 【发布时间】:2017-01-14 08:27:51 【问题描述】:

我有一个网络服务,通过 GET Http 方法,用户请求一个人对象。这个人被发送到一个 JMS 队列,然后在 Spring Integration 的帮助下,我将它发送到一个虚假的电子邮件地址 (https://papercut.codeplex.com/)。我用 Spring Integration Java DSL 编写了代码。我想问一下:

    是否有更灵活的方式发送电子邮件?

    如果抛出异常,如何借助 Spring Integration 重新投递邮件? (例如 5 次,如果未发送,则处理异常并停止程序) 这是我的代码:

网络服务

     public Person findById(Integer id) 
        Person person = jpaPersonRepository.findOne(id);
        jmsTemplate.convertAndSend("testQueue", person);
        return jpaPersonRepository.findOne(id);
     

Java 配置

    @Configuration
    @EnableIntegration
    @ComponentScan
    public class JavaConfig 
        private static final String DEFAULT_BROKER_URL = "tcp://localhost:61616";
        private static final String DEFAULT_QUEUE = "testQueue";

    @Bean
    public ActiveMQConnectionFactory connectionFactory() 
         ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
         connectionFactory.setBrokerURL(DEFAULT_BROKER_URL);
         return connectionFactory;
    

    @Bean
    public JmsTemplate jmsTemplate() 
        JmsTemplate template = new JmsTemplate();
        template.setConnectionFactory(this.connectionFactory());
        template.setDefaultDestinationName(DEFAULT_QUEUE);
        return template;
    

    @Bean
    public DefaultMessageListenerContainer defaultMessageListenerContainer() 
        DefaultMessageListenerContainer defaultMessageListenerContainer = new DefaultMessageListenerContainer();
        defaultMessageListenerContainer.setDestinationName(DEFAULT_QUEUE);
        defaultMessageListenerContainer.setConnectionFactory(this.connectionFactory());
        return defaultMessageListenerContainer;


    @Bean(name="inputChannel")
    public DirectChannel directChannel() 
        return new DirectChannel();
    

   @Bean
   public IntegrationFlow orders() 
        return IntegrationFlows
        .from(Jms.messageDrivenChannelAdapter(defaultMessageListenerContainer()))
            .transform(new ObjectToStringTransformer())
            .enrichHeaders(p -> p.header(MailHeaders.TO, "Papercut0@test.com"))
        .handle(Mail.outboundAdapter("127.0.0.1")
                   .credentials("test","test").port(25)
                   .javaMailProperties(p -> p.put("mail.debug", "true")), 
                    e -> e.id("sendMailEndpoint"))
        .get();


【问题讨论】:

【参考方案1】:

是否有更灵活的方式发送电子邮件?

抱歉,问题不清楚。你有足够的短代码来做到这一点。 Mail.outboundAdapter() 及其所有流畅的 API。什么应该更灵活?

如果抛出异常,如何借助 Spring Integration 重新投递邮件?

为此,Spring Integration 建议使用RequestHandlerRetryAdviceMail.outboundAdapter() 可以配置为:

@Bean
public Advice retryAdvice() 
    RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice();
    RetryTemplate retryTemplate = new RetryTemplate();
    SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
    retryPolicy.setMaxAttempts(5);
    retryTemplate.setRetryPolicy(retryPolicy);
    advice.setRetryTemplate(retryTemplate);
    advice.setRecoveryCallback(new ErrorMessageSendingRecoverer(emailErrorChannel()));
    return advice;
 

...

.handle(Mail.outboundAdapter("127.0.0.1")
               .credentials("test","test").port(25)
               .javaMailProperties(p -> p.put("mail.debug", "true")), 
                e -> e.id("sendMailEndpoint")
                      .advice(retryAdvice())) // HERE IS THE TRICK!

请参阅它的 JavaDocs 和 Reference Manual。

【讨论】:

谢谢!你的回答很清楚。 .advice(retryAdvice()) 尤其对我帮助很大。

以上是关于异常时的 Spring Integration 电子邮件重新投递的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Integration:在异常时不发送Tcp服务器响应

如何在处理过程中引发异常的 Spring Integration 中路由消息?

Spring Integration and AMQP:如何优雅地处理反序列化异常?

使用Spring BOOT集成测试JPA存储库时的NoSuchMethodError(getMetaModel)

JAVA - Spring Integration Flow Transaction + com.atomikos.icatch.HeurHazardException:启发式异常

没有控制器时的 Spring Boot 异常处理