首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在SftpOutboundGateway上启动GET时的SpelEvaluationException

在SftpOutboundGateway上启动GET时的SpelEvaluationException
EN

Stack Overflow用户
提问于 2021-10-13 09:53:40
回答 2查看 46关注 0票数 0

我有一个从SFTPOutboundGateway开始的Spring Integration流程。它应该从SFTP服务器获取一个文件。该文件包含JSON格式的Event对象。我的配置是:

代码语言:javascript
复制
@Bean
public DirectChannelSpec sftpGetInputChannel() {
    return MessageChannels.direct();
}

@Bean
public QueueChannelSpec remoteFileOutputChannel() {
    return MessageChannels.queue();
}

@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {
    PollerMetadata pollerMetadata = new PollerMetadata();
    pollerMetadata.setTrigger(new PeriodicTrigger(5000));
    return pollerMetadata;
}

@Bean
public IntegrationFlow sftpGetFlow(TransferContext context) {
    return IntegrationFlows.from("sftpGetInputChannel")
            .handle(Sftp.outboundGateway(sftpSessionFactory(context.getChannel()),
                            AbstractRemoteFileOutboundGateway.Command.GET, "payload")
                    .remoteDirectoryExpression(context.getRemoteDir())
                    .localDirectory(new File(context.getLocalDir()))
                    .localFilenameExpression(context.getLocalFilename())
                    )
            .channel("remoteFileOutputChannel")
            .transform(Transformers.fromJson(Event[].class))
            .get();
}

为了从SFTP服务器获取文件,我向网关的输入通道“sftpGetInputChannel”发送了一条消息:

代码语言:javascript
复制
boolean sent = sftpGetInputChannel.send(new GenericMessage<>(env.getRemoteDir() + "/" + env.getRemoteFilename()));

当尝试解释给定的文件名时,会抛出SpelEvaluationExceptionremoteDirremoteFilename这两个字段都属于String类型

代码语言:javascript
复制
org.springframework.messaging.MessageHandlingException: error occurred in message handler [bean 'sftpGetFlow.sftp:outbound-gateway#0' for component 'sftpGetFlow.org.springframework.integration.config.ConsumerEndpointFactoryBean#0'; defined in: 'class path resource [com/harry/potter/job/config/SftpConfiguration.class]'; from source: 'bean method sftpGetFlow']; nested exception is org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1001E: Type conversion problem, cannot convert from org.springframework.messaging.support.GenericMessage<?> to java.lang.String
        at org.springframework.integration.support.utils.IntegrationUtils.wrapInHandlingExceptionIfNecessary(IntegrationUtils.java:192)
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:79)
        at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106)
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:570)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:520)
        at com.harry.potter.job.MyTask.getFile(MyEventsTask.java:170)
        at com.harry.potter.job.myTask.runAsTask(MyEventsTask.java:112)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
        at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
        at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:836)
Caused by: org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1001E: Type conversion problem, cannot convert from org.springframework.messaging.support.GenericMessage<?> to java.lang.String
        at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:448)
        at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.doGet(AbstractRemoteFileOutboundGateway.java:680)
        at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.handleRequestMessage(AbstractRemoteFileOutboundGateway.java:584)
        at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:134)
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:62)
        ... 21 common frames omitted
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1001E: Type conversion problem, cannot convert from org.springframework.messaging.support.GenericMessage<?> to java.lang.String
        at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:75)
        at org.springframework.expression.common.ExpressionUtils.convertTypedValue(ExpressionUtils.java:57)
        at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:377)
        at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.generateLocalFileName(AbstractRemoteFileOutboundGateway.java:1316)
        at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.get(AbstractRemoteFileOutboundGateway.java:1081)
        at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.lambda$doGet$6(AbstractRemoteFileOutboundGateway.java:681)
        at org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway$$Lambda$30183/0x0000000000000000.doInSession(Unknown Source)
        at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:439)
        ... 25 common frames omitted
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.messaging.support.GenericMessage<?>] to type [java.lang.String]
        at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322)
        at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195)
        at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:70)
        ... 32 common frames omitted

我做错了什么?

EN

回答 2

Stack Overflow用户

发布于 2021-10-13 10:59:55

好吧,问题不在获取文件的消息中,而是在网关的配置中:

代码语言:javascript
复制
.localFilenameExpression(context.getLocalFilename())

仅仅将本地文件名设置为表达式是不允许的,因为点--通常是文件名的一部分--是一个SpEL分隔符,用于将bean与方法名分开。因此,该表达式变得无效。

可能的表达式为:

代码语言:javascript
复制
.localFilenameExpression("#remoteFileName")
票数 0
EN

Stack Overflow用户

发布于 2021-10-13 14:20:49

查看其JavaDocs:

代码语言:javascript
复制
/**
 * Specify a SpEL expression for local files renaming after downloading.
 * @param localFilenameExpression the SpEL expression to use.
 * @return the Spec.
 */
public S localFilenameExpression(String localFilenameExpression) {

下面是它的工作原理的一些代码片段:

代码语言:javascript
复制
private String generateLocalFileName(Message<?> message, String remoteFileName) {
    if (this.localFilenameGeneratorExpression != null) {
        EvaluationContext evaluationContext = ExpressionUtils.createStandardEvaluationContext(getBeanFactory());
        evaluationContext.setVariable("remoteFileName", remoteFileName);
        return this.localFilenameGeneratorExpression.getValue(evaluationContext, message, String.class);
    }
    return remoteFileName;
}

您可以提供的表达式应该以某种方式位于当前下载的远程文件的上下文中。不确定您的静态context.getLocalFilename()是什么。您可以基于请求消息和该remoteFileName变量上下文构建本地文件名。

欲了解更多信息,请访问:https://docs.spring.io/spring-integration/docs/current/reference/html/sftp.html#configuring-with-the-java-dsl-3

那里的示例如下:

代码语言:javascript
复制
.localDirectoryExpression("'myDir/' + #remoteDirectory")
.localFilenameExpression("#remoteFileName.replaceFirst('sftpSource', 'localTarget')"))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69553333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档