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(); } }
关键说明
SpEL调用Bean方法:
@this在SpEL中代表当前Bean实例(这里就是你的配置类)。如果更新方法在单独的Service Bean里(比如叫transmissionStatusService),只需要把表达式改成@transmissionStatusService.updateStatus(headers['transmissionId'])即可,Spring会自动从容器中找到这个Bean。- 不需要手动创建
StandardEvaluationContext或注册函数,Spring会自动使用容器的BeanResolver处理Bean引用。
表达式设置:
setOnSuccessExpressionString需要传入的是SpEL表达式字符串,而不是表达式求值后的结果,所以直接写调用方法的表达式就可以,不需要提前解析求值。
绑定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; }
- Header检查:
确保transmissionId确实存在于发送消息的Headers中,否则会抛出找不到参数的异常。如果是在发送前设置的Header,确认它被正确传递到了SFTP出站适配器。
内容的提问来源于stack exchange,提问作者Lalit
相关产品推荐
相关产品推荐

