将原始文件添加为流中的标题

时间:2019-02-01 08:59:55

标签: spring-integration

我有一个处理方法的集成流程。将文件从FTP服务器拉到本地后,此方法读取csv文件,例如:foo.csv并创建一个新文件bar.csv,然后将bar.csv再次ftpd传输到FTP服务器,我正在考虑更改的解决方案假设foo.csv的名称为foo_10012019.csv,然后将其再次发送到FTP服务器到下游的History文件夹中,然后从本地删除它,我该怎么做?我看到我们可以使用FileHeaders.ORIGINAL_FILE,但是不确定如何使用它,我创建了一条建议,该建议将删除流的负载,但是负载是新生成的文件bar.csv,我可以在其中使用相同的流吗出站发送原始文件并将其名称更改为FTP服务器?函数名称是localToFtpFlow,我正在使用它发送新文件bar.csv

下面是我的代码。

@Configuration
@EnableIntegration
@ComponentScan
public class FTIntegration {

public static final String TIMEZONE_UTC = "UTC";
public static final String TIMESTAMP_FORMAT_OF_FILES = "yyyyMMddHHmmssSSS";
public static final String TEMPORARY_FILE_SUFFIX = ".part";
public static final int POLLER_FIXED_PERIOD_DELAY = 5000;
public static final int MAX_MESSAGES_PER_POLL = 100;


private DataSource dataSource;

//private static final Logger LOG = LoggerFactory.getLogger(FTIntegration.class);
private static final Logger LOG1 = Logger.getLogger(FTIntegration.class);
private static final String CHANNEL_INTERMEDIATE_STAGE = "intermediateChannel";

private static final String OUTBOUND_CHANNEL = "outboundChannel";

/* pulling the server config from postgres DB*/

private final BranchRepository branchRepository;

@Autowired
private CSVToCSVNoQ csvToCSVNoQ;

public FTIntegration(BranchRepository branchRepository) {
    this.branchRepository = branchRepository;
}

@Bean
public Branch myBranch() {
    return new Branch();
}

/**
 * The default poller with 5s, 100 messages, RotatingServerAdvice and transaction.
 *
 * @return default poller.
 */
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
    return Pollers
            .fixedDelay(POLLER_FIXED_PERIOD_DELAY)
            .maxMessagesPerPoll(MAX_MESSAGES_PER_POLL)
            .transactional()
            .get();
}

/**
 * The direct channel for the flow.
 *
 * @return MessageChannel
 */
@Bean
public MessageChannel stockIntermediateChannel() {
    return new DirectChannel();
}

/**
 * Get the files from a remote directory. Add a timestamp to the filename
 * and write them to a local temporary folder.
 *
 * @return IntegrationFlow
 */

@Bean
public PropertiesPersistingMetadataStore store() {
    PropertiesPersistingMetadataStore store = new PropertiesPersistingMetadataStore();
    return store;
}

public IntegrationFlow fileInboundFlowFromFTPServer(Branch myBranch) throws IOException {

    final FtpInboundChannelAdapterSpec sourceSpecFtp = Ftp.inboundAdapter(createNewFtpSessionFactory(myBranch))
            .preserveTimestamp(true)
            //.patternFilter("*.csv")
            .maxFetchSize(MAX_MESSAGES_PER_POLL)
            .remoteDirectory(myBranch.getFolderPath())
            .regexFilter("FEFOexport" + myBranch.getBranchCode() + ".csv")
            .deleteRemoteFiles(true)
            .localDirectory(new File(myBranch.getBranchCode()))
            .temporaryFileSuffix(TEMPORARY_FILE_SUFFIX)


            /*.localFilenameExpression(new FunctionExpression<String>(s -> {
                final int fileTypeSepPos = s.lastIndexOf('.');
                return DateTimeFormatter
                        .ofPattern(TIMESTAMP_FORMAT_OF_FILES)
                        .withZone(ZoneId.of(TIMEZONE_UTC))
                        .format(Instant.now())
                        + "_"
                        + s.substring(0,fileTypeSepPos)
                        + s.substring(fileTypeSepPos);
            }))*/;

    // Poller definition
    final Consumer<SourcePollingChannelAdapterSpec> stockInboundPoller = endpointConfigurer -> endpointConfigurer
            .id("stockInboundPoller")
            .autoStartup(true)
            .poller(poller());

    IntegrationFlow flow = IntegrationFlows
            .from(sourceSpecFtp, stockInboundPoller)

            .transform(File.class, p -> {
                // log step
                LOG1.info("flow=stockInboundFlowFromAFT, message=incoming file: " + p);
                return p;
            })
            .handle(m -> {
                try {
                    this.csvToCSVNoQ.writeCSVfinal("test", myBranch.getBranchCode() + "/final" + myBranch.getBranchCode() + ".csv", myBranch.getBranchCode() + "/FEFOexport" + myBranch.getBranchCode() + ".csv");
                    LOG1.info("Writing final file .csv " + m);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            })
            .get();

    return flow;
}

@Bean
public IntegrationFlow stockIntermediateStageChannel() {
    IntegrationFlow flow = IntegrationFlows
            .from(CHANNEL_INTERMEDIATE_STAGE)
            .transform(p -> {
                //log step
                LOG1.info("flow=stockIntermediateStageChannel, message=rename file: " + p);

                return p;
            })
            //TODO
            .channel(new NullChannel())
            .get();

    return flow;

}

/*
* Creating the outbound adaptor to send files from local to FTP server
*
* */


public IntegrationFlow localToFtpFlow(Branch myBranch) {

    return IntegrationFlows.from(Files.inboundAdapter(new File(myBranch.getBranchCode()))
                    .filter(new ChainFileListFilter<File>()
                            .addFilter(new RegexPatternFileListFilter("final" + myBranch.getBranchCode() + ".csv"))
                            // .addFilter(new RegexPatternFileListFilter("FEFOexport"+ myBranch.getBranchCode() +".csv"))
                            .addFilter(new FileSystemPersistentAcceptOnceFileListFilter(metadataStore(dataSource), "foo"))),//FileSystemPersistentAcceptOnceFileListFilter
            e -> e.poller(Pollers.fixedDelay(10_000)))
 .enrichHeaders(h ->h.header("file_originalFile","FEFOexport" + 
myBranch.getBranchCode() + ".csv",true))

            .transform(p -> {
                LOG1.info("Sending file " + p + " to FTP branch " + myBranch.getBranchCode());

                return p;
            })
            .log()
            .handle(Ftp.outboundAdapter(createNewFtpSessionFactory(myBranch), FileExistsMode.REPLACE)
                    .useTemporaryFileName(true)
                    .autoCreateDirectory(false)
                    .remoteDirectory(myBranch.getFolderPath()), e -> e.advice(expressionAdvice()))

            .get();
}

@Bean
public Advice expressionAdvice() {
    ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
    //advice.setSuccessChannelName("success.input");
    advice.setOnSuccessExpressionString("payload.delete() + ' was successful'");
    //advice.setFailureChannelName("failure.input");
    advice.setOnFailureExpressionString("payload + ' was bad, with reason: ' + #exception.cause.message");
    advice.setTrapException(true);
    return advice;
}

public DefaultFtpSessionFactory createNewFtpSessionFactory(Branch branch) {
    final DefaultFtpSessionFactory factory = new DefaultFtpSessionFactory();
    factory.setHost(branch.getHost());
    factory.setUsername(branch.getUsern());
    factory.setPort(branch.getFtpPort());
    factory.setPassword(branch.getPassword());
    return factory;
}

@Bean
public ConcurrentMetadataStore metadataStore(final DataSource dataSource) {
    return new JdbcMetadataStore(dataSource);
}
}

@Bean
public IntegrationFlow success(){
    return f -> f.transform("payload.inputMessage.headers['file_originalFile']")

            .handle(Ftp.outboundAdapter( createNewFtpSessionFactory(), FileExistsMode.REPLACE)
                    .useTemporaryFileName(true)
                    .autoCreateDirectory(false)
                    .remoteDirectory("/ftp/erbranch/edms/fefo/History")

            .get());

                          // f.handle(System.out::println);
}

2019-02-04 09:39:39.523  INFO 11748 --- [ask-scheduler-3] o.s.i.file.FileReadingMessageSource      : Created message: [GenericMessage [payload=BEY\finalBEY.csv, headers={file_originalFile=BEY\finalBEY.csv, id=6df10c36-262e-3c8a-7ebf-121ecb4c8bf8, file_name=finalBEY.csv, file_relativePath=finalBEY.csv, timestamp=1549265979523}]]
2019-02-04 09:39:39.525  INFO 11748 --- [ask-scheduler-3] o.s.integration.handler.LoggingHandler   : GenericMessage [payload=BEY\finalBEY.csv, headers={file_originalFile=BEY\finalBEY.csv, id=b6ec5ecc-f746-978d-51a1-62c3b0b8c60b, file_name=finalBEY.csv, file_relativePath=finalBEY.csv, timestamp=1549265979524}]
2019-02-04 09:39:40.618  INFO 11748 --- [ask-scheduler-3] o.s.integration.ftp.session.FtpSession   : File has been successfully transferred to: /ftp/erbranch/EDMS/FEFO/finalBEY.csv.writing
2019-02-04 09:39:41.052  INFO 11748 --- [ask-scheduler-3] o.s.integration.ftp.session.FtpSession   : File has been successfully renamed from: /ftp/erbranch/EDMS/FEFO/finalBEY.csv.writing to /ftp/erbranch/EDMS/FEFO/finalBEY.csv
AdviceMessage [payload=true was successful, headers={id=54f13c8b-ec50-6389-e5ea-c399184d1c41, timestamp=1549265981055}, inputMessage=GenericMessage [payload=BEY\finalBEY.csv, headers={file_originalFile=BEY\finalBEY.csv, id=b6ec5ecc-f746-978d-51a1-62c3b0b8c60b, file_name=finalBEY.csv, file_relativePath=finalBEY.csv, timestamp=1549265979524}]]

调试后:

2019-02-06 12:54:23.708 DEBUG 4060 --- [ask-scheduler-3] i.h.ExpressionEvaluatingMessageProcessor : SpEL Expression evaluation failed with EvaluationException.

org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'inputMessage' cannot be found on object of type 'java.lang.String' - maybe not public or not valid?
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:217) ~[spring-expression-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:104) ~[spring-expression-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:91) ~[spring-expression-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:58) ~[spring-expression-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) ~[spring-expression-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:116) ~[spring-expression-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:371) ~[spring-expression-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:169) ~[spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:128) ~[spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor.processMessage(ExpressionEvaluatingMessageProcessor.java:105) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.transformer.AbstractMessageProcessingTransformer.transform(AbstractMessageProcessingTransformer.java:90) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:89) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:158) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:181) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:160) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.evaluateSuccessExpression(ExpressionEvaluatingRequestHandlerAdvice.java:248) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.doInvoke(ExpressionEvaluatingRequestHandlerAdvice.java:214) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice.invoke(AbstractRequestHandlerAdvice.java:70) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at com.sun.proxy.$Proxy126.handleMessage(Unknown Source) [na:na]
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:181) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:160) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:426) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:336) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:227) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:158) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:181) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:160) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108) [spring-messaging-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.integration.endpoint.SourcePollingChannelAdapter.handleMessage(SourcePollingChannelAdapter.java:220) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:277) [spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.lambda$run$0(AbstractPollingEndpoint.java:378) ~[spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.lambda$execute$0(ErrorHandlingTaskExecutor.java:53) ~[spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) ~[spring-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51) ~[spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:372) ~[spring-integration-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_131]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_131]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_131]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[na:1.8.0_131]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_131]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_131]
    at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_131]

1 个答案:

答案 0 :(得分:0)

由于代码没有缩进,因此很难阅读-您可以使用适当的缩进重新发布代码吗?另外,显示从success.input通道消耗的积分流-这是将执行辅助操作的地方。

发送到成功频道的消息是AdviceMessage;因此该流将具有一个带有payload.inputMessage.headers['file_originalMessage']之类的转换器,然后可以将其发送到FTP。