2016-12-16 71 views
1

我一直在使用Java構建Spring集成服務電子郵件DSL。 此服務必須具有恢復策略才能重試發送電子郵件,但我沒有成功。 簡要故事:應用程序收到一個Payload和Header並嘗試發送到電子郵件服務器。它嘗試3次,如果失敗,它會創建一個帶有消息頭和消息體的新文件。得到errorHandler並寫入文件後如何得到原始消息

如何獲取原始消息(Header and Payload)並將該信息對放入json文件中,以防未能發送電子郵件?

謝謝。

這是我的豆類和服務:

/** 
* ################# 
* MESSAGE ENDPOINTS 
* ################# 
*/ 

@Bean(name = PollerMetadata.DEFAULT_POLLER) 
public PollerMetadata poller() { 
    return Pollers    
      .fixedRate(NumberUtils.createLong(QUEUE_RATE)) 
      .maxMessagesPerPoll(NumberUtils.createLong(QUEUE_CAPACITY)) 
      .errorHandler(e -> LOG.error("Exception : " + e.getMessage())) 
      .get(); 
} 


@Bean 
public MessageChannel recoveryChannel() { 
    return MessageChannels.direct().get(); 
} 


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

@Bean 
public RetryPolicy retryPolicy() { 
    final Map<Class<? extends Throwable>, Boolean> map = 
      new HashMap<Class<? extends Throwable>, Boolean>() { 
       { 
        put(MailSendException.class,true); 
        put(RuntimeException.class, true); 
       } 
       private static final long serialVersionUID = -1L; 
      }; 
    final RetryPolicy ret = new SimpleRetryPolicy(3, map, true); 
    return ret; 
} 

@Bean 
public RetryTemplate retryTemplate() { 
    final RetryTemplate ret = new RetryTemplate(); 
    ret.setRetryPolicy(retryPolicy()); 
    ret.setThrowLastExceptionOnExhausted(false); 
    return ret; 
} 

@Bean 
public Advice retryAdvice() { 
    final RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice();  
    advice.setRetryTemplate(retryTemplate()); 
    RecoveryCallback<Object> recoveryCallBack = new ErrorMessageSendingRecoverer(recoveryChannel()); 

    advice.setRecoveryCallback(recoveryCallBack); 
    return advice; 
} 


private MailSendingMessageHandlerSpec mailOutboundAdapter(){ 
    MailSendingMessageHandlerSpec msmhs = 
      Mail.outboundAdapter(emailServerHost()) 
      .port(serverPort()) 
      .credentials(MAIL_USER_NAME, MAIL_PASSWORD) 
      .protocol(emailProtocol()) 
      .javaMailProperties(p -> p 
        .put("mail.debug", "true") 
        .put("mail.smtp.ssl.enable",enableSSL()) 
        .put("mail.smtp.connectiontimeout", 5000) 
        .put("mail.smtp.timeout", 5000)); 
    return msmhs; 
} 

@Bean 
public FileWritingMessageHandler fileOutboundAdapter(){ 
    FileWritingMessageHandler fwmhs = Files 
      .outboundAdapter(new File("logs/errors/")) 
      .autoCreateDirectory(true) 
      .get();  

    return fwmhs; 
} 


/** 
* ################ 
* FLOWS 
* ################ 
*/ 


@Bean 
public IntegrationFlow smtp(){ 

    return IntegrationFlows.from("mail.input") 
      .channel(MessageChannels.queue()) 
      .handle(this.mailOutboundAdapter(), 
        e -> e.id("smtpOut") 
          .advice(retryAdvice()) 
        ) 
      .get(); 
} 

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

} 

回答

1

在錯誤信息的有效載荷MessagingException。它有兩個屬性causefailedMessage

失敗的消息是失敗時的消息,包含標頭和有效負載。

+0

我在errorFlow()方法中的有效載荷只有MessageException: –

+1

對,所以你需要在.transform(Transformers.toJson())之前添加一個trasformer'.transform(「payload.failedMessage」)'。 –

+0

非常感謝。作品! –