Spring 整合 | Java DSL

Spring Integration | Java DSL

我想发送文件到 SFTP 服务器。我已经为它创建了一个出站流程

@Bean
public IntegrationFlow sftpOutboundFlow() {
    return IntegrationFlows
            .from("toSftpChannel")
            .handle(Sftp.outboundAdapter(this.smileCachedSftpSessionFactory, FileExistsMode.REPLACE)
                    .charset(Charset.forName(fileEncoding)).remoteFileSeparator("/")
                    .remoteDirectory(remoteDirectory).fileNameExpression("payload.getName()")
                    .autoCreateDirectory(true).useTemporaryFileName(true).temporaryFileSuffix(".tranferring"))
            .get();
}

现在,当我尝试使用以下代码向此流发送消息时:

this.toSftpChannel.send(MessageBuilder.withPayload("This is test message.")
            .setHeader(FileHeaders.FILENAME, "testFile.txt").build());

我收到以下错误:

org.springframework.messaging.MessageDeliveryException: Error handling message for file [String payload -> String payload]; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1004E:(pos 8): Method call: Method getName() cannot be found on java.lang.String type
at org.springframework.integration.file.remote.RemoteFileTemplate.doInSession(RemoteFileTemplate.java:249)
at org.springframework.integration.file.remote.RemoteFileTemplate.doInSession(RemoteFileTemplate.java:211)
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:336)
at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:211)
at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:201)
at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:193)
at org.springframework.integration.file.remote.handler.FileTransferringMessageHandler.handleMessageInternal(FileTransferringMessageHandler.java:110)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:286)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:245)
at com.sapient.lufthansa.smilereportuploader.config.TestSftpConnectionIT.testSftpOutboundFlowSuccess_SendString(TestSftpConnectionIT.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=14=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1004E:(pos 8): Method call: Method getName() cannot be found on java.lang.String type
at org.springframework.expression.spel.ast.MethodReference.findAccessorForMethod(MethodReference.java:211)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:125)
at org.springframework.expression.spel.ast.MethodReference.access[=14=]0(MethodReference.java:49)
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:330)
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:164)
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:152)
at org.springframework.integration.file.DefaultFileNameGenerator.generateFileName(DefaultFileNameGenerator.java:76)
at org.springframework.integration.file.remote.RemoteFileTemplate.doInSession(RemoteFileTemplate.java:233)
... 44 more

请注意,当我将文件传递给如下发送方法时,一切都很顺利:

File file = new File(this.fakeSftpServer.getSourceLocalDirectory(), "testFile.txt");
file.createNewFile();

this.toSftpChannel.send(MessageBuilder.withPayload(file).build());

我无法理解它的原因。请帮我解决这个问题。

"payload.getName()"

如错误所述,字符串上没有 属性 名称。

当您有一个字符串负载时,您需要以其他方式提供文件名。

经过一些研究,我能够解决这个问题。我在发送消息时将文件名发送为 FILE_NAME header。

this.toSftpChannel.send(MessageBuilder.withPayload(fileContent).setHeader("FILE_NAME", filename)
                    .build());

在我使用的流程中

.fileNameExpression("headers.get('FILE_NAME')") 

获取发送的名称,效果很好。