【问题标题】:How to move files using ExpressionEvaluatingRequestHandlerAdvice如何使用 ExpressionEvaluatingRequestHandlerAdvice 移动文件
【发布时间】:2023-03-17 14:35:01
【问题描述】:

在 ExpressionEvaluatingRequestHandlerAdvice 的手册中,它清楚地表明,A typical use case for this advice might be with an <ftp:outbound-channel-adapter/>, perhaps to move the file to one directory if the transfer was successful, or to another directory if it fails

但我无法弄清楚将有效负载从当前目录移动到另一个目录的表达式。

这个例子只是删除或重命名文件:

<bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
    <property name="onSuccessExpression" value="payload.delete()" />
    <property name="successChannel" ref="afterSuccessDeleteChannel" />
    <property name="onFailureExpression" value="payload.renameTo(new java.io.File(payload.absolutePath + '.failed.to.send'))" />
    <property name="failureChannel" ref="afterFailRenameChannel" />
</bean>

如何做到这一点?

编辑

按照 Gary 的建议,这是新的尝试:

设法将表达式更改为"T(java.nio.file.Files).move(payload.path, new java.io.File(new java.io.File('sent'), payload.name).path, T(java.nio.file.StandardCopyOption).REPLACE_EXISTING)", 但仍然收到错误Method move(java.lang.String,java.lang.String,java.nio.file.Standar‌​dCopyOption) cannot be found on java.nio.file.Files type

代码是,

@Bean
    @ServiceActivator(inputChannel = "toSftpChannel", adviceChain = "expressionAdvice")
    public MessageHandler uploadHandler() {
        SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
        handler.setRemoteDirectoryExpression(new LiteralExpression(outRemoteDirectory));
        handler.setFileNameGenerator(new FileNameGenerator() {

            @Override
            public String generateFileName(Message<?> message) {
                if (message.getPayload() instanceof File) {
                    return ((File) message.getPayload()).getName();
                } else {
                    throw new IllegalArgumentException("File expected as payload.");
                }
            }

        });
        return handler;
    }

    @MessagingGateway()
    public interface UploadGateway {

        @Gateway(requestChannel = "toSftpChannel")
        void upload(File file);

    }

@Bean
    public String onUploadSuccessExpression() {
        return "T(java.nio.file.Files).move(payload.path, new java.io.File(new java.io.File('sent'), payload.name).path, T(java.nio.file.StandardCopyOption).REPLACE_EXISTING)";
    }

@Bean
    public String onUploadFailedExpression() {
        return "payload";
    }

@Bean
    public Advice expressionAdvice() {
        ExpressionEvaluatingRequestHandlerAdvice expressionEvaluatingRequestHandlerAdvice = new ExpressionEvaluatingRequestHandlerAdvice();
        expressionEvaluatingRequestHandlerAdvice.setOnSuccessExpressionString(onUploadSuccessExpression());
        expressionEvaluatingRequestHandlerAdvice.setSuccessChannelName("uploadSuccessChannel");
        expressionEvaluatingRequestHandlerAdvice.setOnFailureExpressionString(onUploadFailedExpression());
        expressionEvaluatingRequestHandlerAdvice.setFailureChannelName("uploadFailedChannel");
        expressionEvaluatingRequestHandlerAdvice.setTrapException(true);
        expressionEvaluatingRequestHandlerAdvice.setPropagateEvaluationFailures(true);
        return expressionEvaluatingRequestHandlerAdvice;
    }

调用来自UploadGatewayupload 方法。

堆栈跟踪是,

"main@1" prio=5 tid=0x1 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.evaluateSuccessExpression(ExpressionEvaluatingRequestHandlerAdvice.java:241)
      at org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.doInvoke(ExpressionEvaluatingRequestHandlerAdvice.java:214)
      at org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice.invoke(AbstractRequestHandlerAdvice.java:70)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
      at com.sun.proxy.$Proxy81.handleRequestMessage(Unknown Source:-1)
      at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.doInvokeAdvisedRequestHandler(AbstractReplyProducingMessageHandler.java:127)
      at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:112)
      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.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:143)
      at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:135)
      at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:392)
      at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:481)
      at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:433)
      at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:424)
      at org.springframework.integration.gateway.GatewayCompletableFutureProxyFactoryBean.invoke(GatewayCompletableFutureProxyFactoryBean.java:65)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
      at com.sun.proxy.$Proxy87.upload(Unknown Source:-1)

【问题讨论】:

    标签: spring-boot spring-integration spring-integration-sftp


    【解决方案1】:

    如果新目录与旧目录在同一磁盘上,则在“onSuccessExpression”中,只需使用payload.renameTo(...),类似于示例在onFailureExpression 中的使用方式。

    `payload.renameTo(new java.io.File(new File('newDir'), payload.name))`
    

    使用有效负载的名称创建一个文件到目录newDir(必须存在)。

    如果您是 JDK 7 或更高版本,请使用...

    T(java.nio.file.Files).move(payload.path, new java.io.File(new File('newDir'), payload.name).path)

    ...改为。

    这将处理新目录位于不同磁盘上的情况(简单的File.renameTo() 不会)。

    如果您仍在使用 JDK 6 并且新目录可能在不同的磁盘上,您将需要使用 onSuccessExpression=payload 并向 successChannel 订阅服务激活器来操作文件本身,可能使用 Spring 的 FileCopyUtils .

    【讨论】:

    • 非常感谢。我鬼混并设法使用 ServiceActivator 工作,现在,将使用“移动”进行检查。
    • 我试过这个但得到错误,SpelEvaluationException: A problem occured whilst attempting to construct an object of type 'File' using arguments '(java.lang.String)'
    • 在调试应用程序时,我注意到一些可能的代码错误。它们是错误还是功能? 1、ExpressionEvaluatingRequestHandlerAdvice::evaluateSuccessExpression中,AdviceMessage发送到SuccessChannel后抛出异常。这会导致其中的异常有效负载。如果有异常,该方法不应该首先抛出异常吗? 2. 在同一个类中,propagateOnSuccessEvaluationFailures 默认为'false',不会抛出异常。这反而否定了FailChannel的目的。我在外部将其设置为“true”。你能解释一下这些背后的思考过程吗?
    • 设法将表达式更改为"T(java.nio.file.Files).move(payload.path, new java.io.File(new java.io.File('sent'), payload.name).path, T(java.nio.file.StandardCopyOption).REPLACE_EXISTING)"´,但仍然收到错误Method move(java.lang.String,java.lang.String,java.nio.file.StandardCopyOption) cannot be found on java.nio.file.Files type
    • 不要在 cmets 中放入扩展的附加信息;最好用更多信息编辑问题,然后添加简短评论以表明您已这样做。我不明白您的第 1 点。对于第 2 点,通常,错误处理程序会处理错误,调用者无需知道存在问题。如果存在,那么通常,错误处理程序流应该抛出一个新的异常,以向调用者指示错误处理程序已涉及。布尔值适用于您想要处理错误并将原始异常抛出给调用者的罕见实例。
    猜你喜欢
    • 1970-01-01
    • 2020-01-30
    • 2010-09-29
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 2020-10-18
    相关资源
    最近更新 更多