如何使用ExpressionEvaluatingRequestHandlerAdvice移动文件

时间:2017-12-10 20:08:41

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

在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>

如何实现这一目标?

修改

根据加里的建议,这是新的尝试:

管理将表达式更改为"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;
    }

调用来自upload的{​​{1}}方法。

堆栈跟踪是,

UploadGateway

1 个答案:

答案 0 :(得分:0)

如果新目录与旧目录位于同一磁盘上,则在“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来操作文件本身,可能使用春天的FileCopyUtils