Spring Integration | Java DSL

2019-09-14 12:36发布

问题:

I want to send a file to SFTP server. I have created a outbound flow for it

@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();
}

Now when i am trying to send a message to this flow using the below code:

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

I get the below error:

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$1.doInSession(RemoteFileTemplate.java:249)
at org.springframework.integration.file.remote.RemoteFileTemplate$1.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$1.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$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.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$000(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$1.doInSession(RemoteFileTemplate.java:233)
... 44 more

Please note everything works like a charm when i pass a file to the send method like below:

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

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

I am unable to understand the cause for it. Please help me to resolve this.

回答1:

"payload.getName()"

Like the error says, there's no property name on a String.

When you have a String payload you need to supply the file name some other way.



回答2:

After some research, I was able to fix this. I sent the filename as FILE_NAME header while sending the message.

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

In the flow i used

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

to get the sent name and it worked perfectly.