Spring集成:FTP出站网关文件移动&获取

时间:2017-09-14 05:25:04

标签: spring-integration

我的要求是从FTP下载文件(例如:FTP Dir" A")进行验证并执行一些操作。一旦处理完毕,同一个文件必须移动" A"到FTP Dir" B"。

尝试下面一次

@ServiceActivator(inputChannel = "jsonHttpOutBoundChannel",outputChannel = "testChannel")
    public void handler() {
        FtpOutboundGateway ftpOutboundGateway = new FtpOutboundGateway(ftpSessionFactory.getFTPSessionFactory(), "mv");
        Message message1 = MessageBuilder.withPayload(false)
                .setHeader("file_renameTo", "/FTP/success")
                .setHeader("file_remoteFile", "category.xml")
                .setHeader("file_remoteDirectory","/FTP/process")
                .build();
        ftpOutboundGateway.handleMessage(message1);
    }

获得

Caused by: java.lang.NullPointerException
    at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.getRemoteFilename(AbstractRemoteFileOutboundGateway.java:1046)
    at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.doMv(AbstractRemoteFileOutboundGateway.java:629)
    at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.handleRequestMessage(AbstractRemoteFileOutboundGateway.java:526)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at au.com.fluentretail.ftp.integration.serviceactivators.FTPServiceActivator.handler(FTPServiceActivator.java:69)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:113)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129)
    at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49)
    at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:347).

使用AbstractRemoteFileOutboundGateway尝试RemoteFileTemplate,

@Bean
   @ServiceActivator(inputChannel = "jsonHttpOutBoundChannel")
   public MessageHandler gatewayHandler() throws IOException {    

       Expression expression = new LiteralExpression("/processing");
       Expression fileExpression = new LiteralExpression("category.xml");
       RemoteFileTemplate remoteFileTemplate = new RemoteFileTemplate(ftpSessionFactory.getFTPSessionFactory());
       remoteFileTemplate.setRemoteDirectoryExpression(expression);
       remoteFileTemplate.setFileNameExpression(fileExpression);

       AbstractRemoteFileOutboundGateway ftpOutboundGateway = new FtpOutboundGateway(remoteFileTemplate, "get");
       ftpOutboundGateway.setLocalDirectoryExpression(new LiteralExpression(CONSTANTS.ftpErrorPath));

       ftpOutboundGateway.setRequiresReply(false);
       return ftpOutboundGateway;
   }

仍面临同样的问题。

2017-09-14 15:55:25.058 ERROR 14648 --- [ask-scheduler-1] o.s.integration.handler.LoggingHandler   : org.springframework.messaging.MessageHandlingException: error occurred in message handler [gatewayHandler]; nested exception is java.lang.NullPointerException, failedMessage=GenericMessage [payload=, headers={file_renameTo=/success, file_originalFile=/processing/category.xml, id=68fd370f-eb77-66a5-3462-e8f50c0c068c, file_remoteDirectory=/processing, file_remoteFile=category.xml, timestamp=1505384725042}]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:139)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:236)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:185)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:236)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:185)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212)
    at org.springframework.integration.splitter.AbstractMessageSplitter.produceOutput(AbstractMessageSplitter.java:159)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:236)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:185)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:236)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:185)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.endpoint.SourcePollingChannelAdapter.handleMessage(SourcePollingChannelAdapter.java:210)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:272)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:58)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:190)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:186)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:353)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:344)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
    at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.getRemoteFilename(AbstractRemoteFileOutboundGateway.java:1046)
    at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.doGet(AbstractRemoteFileOutboundGateway.java:564)
    at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.handleRequestMessage(AbstractRemoteFileOutboundGateway.java:520)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    ... 81 more

这里和这里似乎是常见的问题。

有人可以帮助我吗? 提前谢谢。

编辑Caused by: java.lang.IllegalArgumentException: BeanFactory must not be null在代码下面抛出,它已经是一个bean了。 即使使用sessionFactory而不是RemoteFileTemplate

,也会抛出此异常
@Bean
    @ServiceActivator(inputChannel = "finalProcessChannel")
    public MessageHandler finalProcessHandler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                String fileName = message.getHeaders().get("file_name").toString();
                message = MessageBuilder.createMessage("",createHeaders(message,CONSTANTS.ftpProcessingPath,CONSTANTS.ftpSuccessPath));
                RemoteFileTemplate fileTemplate = new RemoteFileTemplate(ftpSessionFactory.getFTPSessionFactory());
                FtpOutboundGateway ftpOutboundGateway = new FtpOutboundGateway(fileTemplate, "mv","'"+CONSTANTS.ftpProcessingPath+"/"+fileName+"'");
                ftpOutboundGateway.setOutputChannelName("outputChannel");
                ftpOutboundGateway.handleMessage(message);
            }
        };
    }

编辑:要返回FtpOutboundGateway,我需要Message Header / String中的文件名,以便使用表达式初始化构造函数。并使用@Bean将Message作为参数传递给required a bean of type 'org.springframework.messaging.Message' that could not be foundrequired a bean of type 'java.lang.String' that could not be found

前:

  @Bean
    @ServiceActivator(inputChannel = "finalProcessChannel")
    public FtpOutboundGateway finalProcessHandler(Message message) {
        String fileName = message.getHeaders().get("file_name").toString();
        return new FtpOutboundGateway(ftpSessionFactory.getFTPSessionFactory(), "mv", "'" + CONSTANTS.ftpProcessingPath + fileName + "'") {
            @Override
            protected Object handleRequestMessage(Message<?> requestMessage) {
                requestMessage = MessageBuilder.createMessage("", createHeaders(requestMessage, CONSTANTS.ftpProcessingPath, CONSTANTS.ftpSuccessPath));
                setOutputChannelName("outputChannel");
                return super.handleRequestMessage(requestMessage);
            }
        };
    }

编辑:动态表达

@Bean
    @ServiceActivator(inputChannel = "finalProcessChannel")
    public FtpOutboundGateway finalProcessHandler() {
        return new FtpOutboundGateway(ftpSessionFactory.getFTPSessionFactory(), "mv","'"+CONSTANTS.ftpProcessingPath+"/"+"headers['file_name']"+"'"){
            @Override
            protected Object handleRequestMessage(Message<?> requestMessage) {
                requestMessage = MessageBuilder.createMessage("", createHeaders(requestMessage, CONSTANTS.ftpProcessingPath, CONSTANTS.ftpSuccessPath));
                setOutputChannelName("outputChannel");
                return super.handleRequestMessage(requestMessage);
            }
        };
    }

1 个答案:

答案 0 :(得分:0)

您没有正确使用网关;您不应为每个请求创建新网关。

网关必须是@Bean,以便框架正确初始化它。

@ServiceActivator(...)
@Bean
public FtpOutboundGateway gateway() {
    ...
}

然后向服务的inputChannel发送消息。

修改

我们应该防止NPE,但问题是构造函数(在第二个示例中)设置远程文件路径表达式(使用网关)。使用该构造函数,您需要再次添加表达式...

        AbstractRemoteFileOutboundGateway ftpOutboundGateway = new FtpOutboundGateway(remoteFileTemplate, "get", "/processing/category.xml");

我会远离采用RemoteFileTemplate的构造函数;使用会话工厂的那些。

我将针对这些问题打开JIRA问题。