Spring integration Spring集成邮件:在所有数据库插入后发送电子邮件
您好,我有一个集成流,它逐行分割一个文件,将每一行转换为一个POJO,然后通过JDBC出站网关将该POJO插入数据库 我想能够发送一个单一的电子邮件一旦文件的过程已经完成。 我目前在jdbcOutboundGateway之后发送到smtpFlow频道,但这是在每次插入db之后发送一封电子邮件 这是我当前的DSL流Spring integration Spring集成邮件:在所有数据库插入后发送电子邮件,spring-integration,spring-integration-dsl,spring-integration-ftp,spring-integration-jdbc,Spring Integration,Spring Integration Dsl,Spring Integration Ftp,Spring Integration Jdbc,您好,我有一个集成流,它逐行分割一个文件,将每一行转换为一个POJO,然后通过JDBC出站网关将该POJO插入数据库 我想能够发送一个单一的电子邮件一旦文件的过程已经完成。 我目前在jdbcOutboundGateway之后发送到smtpFlow频道,但这是在每次插入db之后发送一封电子邮件 这是我当前的DSL流 IntegrationFlow ftpFlow() { return IntegrationFlows.from( ftpSource(), spec
IntegrationFlow ftpFlow() {
return IntegrationFlows.from(
ftpSource(), spec -> spec.poller(Pollers.fixedDelay(5, TimeUnit.SECONDS)))
.split(splitFile())
.transform(this::transformToIndividualScore)
.handle(jdbcOutboundGateway(null))
.channel("smtpFlow")
.get();
如何使此流在jdbcOutboundGateway
中处理完所有文件后只发送一封电子邮件
这是我的splitFile()
方法
@Bean
FileSplitter splitFile() {
FileSplitter fs = new FileSplitter(true, false);
fs.setFirstLineAsHeader("IndividualScore");
return fs;
@Transformer
private IndividualScore transformToIndividualScore(String payload) {
String[] values = payload.split(",");
IndividualScore is = new IndividualScore();
is.setScorecardDate(values[0]);
is.setVnSpId(values[1]);
is.setPrimaryCat(values[2]);
is.setSecondaryCat(values[3]);
is.setScore(Integer.parseInt(values[4]));
is.setActual(values[5]);
return is;
}
下面是我的转换为IndividualScore
方法
@Bean
FileSplitter splitFile() {
FileSplitter fs = new FileSplitter(true, false);
fs.setFirstLineAsHeader("IndividualScore");
return fs;
@Transformer
private IndividualScore transformToIndividualScore(String payload) {
String[] values = payload.split(",");
IndividualScore is = new IndividualScore();
is.setScorecardDate(values[0]);
is.setVnSpId(values[1]);
is.setPrimaryCat(values[2]);
is.setSecondaryCat(values[3]);
is.setScore(Integer.parseInt(values[4]));
is.setActual(values[5]);
return is;
}
在句柄之后添加
.aggregate()
,将拆分结果重新组合成一条消息。这是我的问题的解决方案(某种程度上)
在我的filespliter
上将迭代器标记为false
,现在允许排序头
更新的splitFile()
如下所示
@Bean
FileSplitter splitFile() {
FileSplitter fs = new FileSplitter(false, false);
fs.setFirstLineAsHeader("IndividualScore");
fs.setApplySequence(true);
return fs;
}
我的直觉告诉我,默认的.aggregate()
发布策略必须是消息头sequenceSize
==聚合的消息列表
创建filespliter
时,将iterator
设置为true
时,sequenceSize
设置为0
,这将永远不会满足默认.aggregate()的发布策略
但是,这使得filespliter
使用列表
将文件的所有行存储在内存中。聚合器还在内存中存储另一个ArrayList
行
有没有更好的解决方案来创建一个自定义聚合器来处理END
FileMarker
以允许使用迭代器来拆分文件?借助@ArtemBilan
我能够使用publishsubscribebchannel()
和chain 2subscribe()
方法,下面是新的IntegrationFlow
@Bean
IntegrationFlow ftpFlow() {
return IntegrationFlows.from(
ftpSource(), spec -> spec.poller(Pollers.fixedDelay(5, TimeUnit.SECONDS)))
.publishSubscribeChannel(channel -> channel
.subscribe(
a -> a
.split(splitFile())
.transform(this::transformToIndividualScore)
.handle(jdbcMessageHandler(null)))
.subscribe(
b -> b
.transform(this::transformToSuccessEmail)
.handle(emailHandler()))
)
.get();
另一种方法是使用带有split()
和jdbcOutboundGateway()
的publishSubscribeChannel()
作为一个订阅者子流,使用Mail.outboundAdapter()
作为另一个订阅者子流。确实不可能一次完成所有文件的请求:只是没有一个标志来检查所有文件是否完成。如果在处理现有文件的过程中出现新文件,该怎么办?。。考虑将逻辑更改为基于每个文件的基础。或者正如Gary所说:使用一些聚合器策略,在一些文件或超时后发出电子邮件消息;抱歉,我误解了这个问题-聚合器将为每个文件发送一封邮件,而不是为每个插入发送一封邮件;您需要@ArtemBilan对所有文件的一条消息的建议。当我在.handle(jdbcOutboundGateway(null))
之后删除.aggregate()
时,它没有完成流程,只是挂起。@ArtemBilan是的!这对我来说现在有意义了。我对集成非常陌生,它是一个很好的框架。我将很快更新我的代码并发布一条新的消息和解决方案。