You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Integration 4.3 SFTP出站适配器:如何通过ExpressionEvaluatingRequestHandlerAdvice调用方法更新数据库

解决Spring Integration SFTP出站适配器成功后更新数据库的问题

看来你选对了方案用ExpressionEvaluatingRequestHandlerAdvice处理SFTP发送后的逻辑,但代码里有几个关键细节需要调整,我帮你梳理下:

问题分析

你当前的代码错误地把表达式求值后的结果字符串传给了setOnSuccessExpressionString,而不是直接传入SpEL表达式本身。另外,手动注册函数的方式完全没必要——Spring SpEL本身就支持直接调用容器内的Bean方法,这会让代码简洁很多。

修正后的实现

假设你的更新方法(mymethod)所在的类是Spring管理的Bean(比如当前配置类已经加了@Configuration注解),可以这样修改:

@Bean
public ExpressionEvaluatingRequestHandlerAdvice afterPut() {
    ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
    
    // 直接用SpEL调用当前Bean的mymethod,传入header中的transmissionId
    advice.setOnSuccessExpressionString("@this.mymethod(headers['transmissionId'])");
    
    // 控制是否传播更新失败的异常:true=更新失败则SFTP操作也标记为失败;false=忽略更新失败,保留SFTP成功状态
    advice.setPropagateEvaluationFailures(true);
    return advice;
}

// 这个方法所在的类必须是Spring Bean(比如当前类加了@Configuration)
public void mymethod(String id) {
    try {
        TransmissionQueue abc = transmissionQueueDataService.findById(Integer.parseInt(id));
        abc.setStatus("COMPLETED");
        transmissionQueueDataService.saveTransmissionQueue(abc);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

关键说明

  1. SpEL调用Bean方法:

    • @this在SpEL中代表当前Bean实例(这里就是你的配置类)。如果更新方法在单独的Service Bean里(比如叫transmissionStatusService),只需要把表达式改成@transmissionStatusService.updateStatus(headers['transmissionId'])即可,Spring会自动从容器中找到这个Bean。
    • 不需要手动创建StandardEvaluationContext或注册函数,Spring会自动使用容器的BeanResolver处理Bean引用。
  2. 表达式设置:

    • setOnSuccessExpressionString需要传入的是SpEL表达式字符串,而不是表达式求值后的结果,所以直接写调用方法的表达式就可以,不需要提前解析求值。
  3. 绑定Advice到SFTP适配器:
    别忘了把这个Advice绑定到你的SFTP出站处理器上,否则它不会生效:

@Bean
@ServiceActivator(inputChannel = "sftpOutboundChannel")
public MessageHandler sftpOutboundHandler() {
    SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
    handler.setRemoteDirectoryExpression(new SpelExpressionParser().parseExpression("headers['remoteDirectory']"));
    
    // 将我们的成功处理Advice添加到处理器的Advice链中
    handler.setAdviceChain(Collections.singletonList(afterPut()));
    
    return handler;
}
  1. Header检查:
    确保transmissionId确实存在于发送消息的Headers中,否则会抛出找不到参数的异常。如果是在发送前设置的Header,确认它被正确传递到了SFTP出站适配器。

内容的提问来源于stack exchange,提问作者Lalit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:50:43