具有groovy的ExpressionEvaluatingRequestHandlerAdvice

时间:2013-02-20 16:04:39

标签: spring-integration

是否可以将spring集成groovy脚本链接到ExpressionEvaluatingRequestHandlerAdvice bean上的成功/失败结果?目前我有这个配置删除有效载荷

<beans:bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
    <beans:property name="onSuccessExpression" value="new File(payload).delete()"/>
    <beans:property name="successChannel" ref="successChannel" />
    <beans:property name="onFailureExpression" value="new File(payload).delete()"/>
    <beans:property name="failureChannel" ref="failureChannel" />
</beans:bean>

但是我想使用各种Header详细信息来执行许多操作来删除有效负载,还可以重命名和更改文件权限。 groovy脚本可能看起来像

    <int-groovy:script>
    <![CDATA[
    def encryptedFile = new File(payload);
        encryptedFile.delete();
        def file = new File(headers['ORIGINAL_FILE']);
        def successFolder = new File(file.getParent(),'success');
        return file.renameTo(new File(successFolder, file.getName()));
        ]]>
    </int-groovy:script>
</int:transformer>

但我不确定如何将此配置链接到'successChannel'。

修改

好的,我连接了两个表达式来传递原始消息,并且groovy逻辑链接到变换器

<!-- handle ftp outcome -->
        <beans:bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <beans:property name="onSuccessExpression" value="payload"/>
            <beans:property name="successChannel" ref="successChannel"/>
            <beans:property name="onFailureExpression" value="payload"/>
            <beans:property name="failureChannel" ref="failureChannel"/>
        </beans:bean>
    </int-ftp:request-handler-advice-chain>
</int-ftp:outbound-channel-adapter>

<int:transformer input-channel="successChannel" output-channel="outputB">
    <int-groovy:script>
    <![CDATA[
        def encryptedFile = new File(payload);
        encryptedFile.delete();
        def file = new File(headers['ORIGINAL_FILE']);
        def successFolder = new File(file.getParent(),'success');
        return file.renameTo(new File(successFolder, file.getName()));
        ]]>
    </int-groovy:script>
</int:transformer>

但是如果我使用'payload'或'#root'就会得到这个异常

Caused by: org.springframework.integration.MessageHandlingException: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.io.File(org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException)
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:76)
    at org.springframework.integration.transformer.AbstractMessageProcessingTransformer.transform(AbstractMessageProcessingTransformer.java:56)
    at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:67)
    ... 56 more
Caused by: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.io.File(org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException)
    at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1459)
    at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1375)
    at org.codehaus.groovy.runtime.callsite.MetaClassConstructorSite.callConstructor(MetaClassConstructorSite.java:46)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:190)
    at groovy.lang.run(groovy.lang.Script:3)
    at org.springframework.scripting.groovy.GroovyScriptFactory.executeScript(GroovyScriptFactory.java:247)
    at org.springframework.scripting.groovy.GroovyScriptFactory.getScriptedObject(GroovyScriptFactory.java:185)
    at org.springframework.integration.groovy.GroovyScriptExecutingMessageProcessor.executeScript(GroovyScriptExecutingMessageProcessor.java:88)
    at org.springframework.integration.scripting.AbstractScriptExecutingMessageProcessor.processMessage(AbstractScriptExecutingMessageProcessor.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:69)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:84)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:102)
    at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:126)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:227)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:127)
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:73)
    ... 58 more

这似乎表明正在传递'ExpressionEvaluatingRequestHandlerAdvice'bean引用而不是文件名?

编辑 - 第2天

所以我根据Gary的评论更新了示例,并使用'inputMessage.payload'作为成功通道,并使用'payload.failedMessage'作为失败的通道。配置看起来像这样

<int-ftp:outbound-channel-adapter 
    id="ftpOutbound" 
    channel="inputB"        
    cache-sessions="false"
    remote-directory="/"
    session-factory="ftpClientFactory">
    <int-ftp:request-handler-advice-chain>
        <!-- handle three retry attempts -->
        <beans:bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
            <beans:property name="retryTemplate">
                <beans:bean class="org.springframework.retry.support.RetryTemplate">
                    <beans:property name="backOffPolicy">
                        <beans:bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
                            <beans:property name="initialInterval" value="5000" />
                            <beans:property name="multiplier" value="3" />
                        </beans:bean>
                    </beans:property>
                </beans:bean>
            </beans:property>
        </beans:bean>
        <!-- handle ftp outcome -->
        <beans:bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <beans:property name="onSuccessExpression" value="payload"/>
            <beans:property name="successChannel" ref="successChannel"/>
            <beans:property name="onFailureExpression" value="payload"/>
            <beans:property name="failureChannel" ref="failureChannel"/>
        </beans:bean>
    </int-ftp:request-handler-advice-chain>
</int-ftp:outbound-channel-adapter>

<int:transformer input-channel="successChannel" output-channel="outputB">
    <int-groovy:script>
    <![CDATA[
        println('successChannel');
        def file = new File(inputMessage.headers['ORIGINAL_FILE']);
        def successFolder = new File(file.getParent(),'success');
        file.renameTo(new File(successFolder, file.getName()));

        def encryptedFile = inputMessage.payload;
        encryptedFile.delete();
        ]]>
    </int-groovy:script>
</int:transformer>

<int:transformer input-channel="failureChannel" output-channel="outputB">
    <int-groovy:script>
    <![CDATA[
        println('failChannel');
        def file = new File(payload.failedMessage.headers['ORIGINAL_FILE']);
        def failedFolder = new File(file.getParent(),'failed');
        file.renameTo(new File(failedFolder, file.getName()));

        def encryptedFile = payload.failedMessage.payload;
        encryptedFile.delete();
        ]]>
    </int-groovy:script>
</int:transformer>

但看起来建议处理程序被调用三次,而不是在第一次成功进行FTP传输后停止。我的'onSucessExpression'逻辑是不正确的?

2013-02-21 10:40:39,588 INFO  [org.springframework.integration.ftp.session.FtpSession] (main) File has been successfully transfered to: /SEPA.enc.writing
2013-02-21 10:40:39,591 INFO  [org.springframework.integration.ftp.session.FtpSession] (main) File has been successfully renamed from: /SEPA.enc.writing to /SEPA.enc
2013-02-21 10:40:39,591 DEBUG [org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice] (main) Unable to attempt conversion of Message payload types. Component 'org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice#2e1551b0' has no explicit ConversionService reference, and there is no 'integrationConversionService' bean within the context.
2013-02-21 10:40:39,594 DEBUG [org.springframework.integration.channel.DirectChannel] (main) preSend on channel 'successChannel', message: [Payload=C:\projects\spring-integration\src\test\resources\citi\SEPA.enc][Headers={timestamp=1361443239593, id=3adf23f7-c428-485a-9da5-839923a915fd}]
2013-02-21 10:40:39,594 DEBUG [org.springframework.integration.transformer.MessageTransformingHandler] (main) org.springframework.integration.transformer.MessageTransformingHandler@7219d6af received message: [Payload=C:\projects\spring-integration\src\test\resources\citi\SEPA.enc][Headers={timestamp=1361443239593, id=3adf23f7-c428-485a-9da5-839923a915fd}]
successChannel
2013-02-21 10:40:40,164 DEBUG [org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice] (main) Unable to attempt conversion of Message payload types. Component 'org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice#2e1551b0' has no explicit ConversionService reference, and there is no 'integrationConversionService' bean within the context.
2013-02-21 10:40:40,165 DEBUG [org.springframework.integration.channel.DirectChannel] (main) preSend on channel 'failureChannel', message: [Payload=org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException: Handler Failed][Headers={timestamp=1361443240165, id=596c3a78-493b-45bf-b9ca-c56dab15e318}]
2013-02-21 10:40:40,165 DEBUG [org.springframework.integration.transformer.MessageTransformingHandler] (main) org.springframework.integration.transformer.MessageTransformingHandler@4c4b11e9 received message: [Payload=org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException: Handler Failed][Headers={timestamp=1361443240165, id=596c3a78-493b-45bf-b9ca-c56dab15e318}]
failChannel
2013-02-21 10:40:45,218 DEBUG [org.springframework.integration.file.remote.handler.FileTransferringMessageHandler] (main) org.springframework.integration.file.remote.handler.FileTransferringMessageHandler#0 received message: [Payload=C:\projects\spring-integration\src\test\resources\citi\SEPA.enc][Headers={timestamp=1361443239551, id=73da6c1f-8658-4397-ab57-ea7591e284da, ORIGINAL_FILE=C:\projects\spring-integration\src\test\resources\citi\SEPA.xml}]
2013-02-21 10:40:45,218 DEBUG [org.springframework.integration.channel.DirectChannel] (main) preSend on channel 'successChannel', message: [Payload=C:\projects\spring-integration\src\test\resources\citi\SEPA.enc][Headers={timestamp=1361443245218, id=96c0ed36-0eb9-4bab-abff-84d63ff91d80}]
2013-02-21 10:40:45,218 DEBUG [org.springframework.integration.transformer.MessageTransformingHandler] (main) org.springframework.integration.transformer.MessageTransformingHandler@7219d6af received message: [Payload=C:\projects\spring-integration\src\test\resources\citi\SEPA.enc][Headers={timestamp=1361443245218, id=96c0ed36-0eb9-4bab-abff-84d63ff91d80}]
successChannel
2013-02-21 10:40:45,220 DEBUG [org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice] (main) Unable to attempt conversion of Message payload types. Component 'org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice#2e1551b0' has no explicit ConversionService reference, and there is no 'integrationConversionService' bean within the context.
2013-02-21 10:40:45,220 DEBUG [org.springframework.integration.channel.DirectChannel] (main) preSend on channel 'failureChannel', message: [Payload=org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException: Handler Failed][Headers={timestamp=1361443245220, id=a63c7877-29f6-46b2-96fc-35ad84589a82}]
2013-02-21 10:40:45,220 DEBUG [org.springframework.integration.transformer.MessageTransformingHandler] (main) org.springframework.integration.transformer.MessageTransformingHandler@4c4b11e9 received message: [Payload=org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException: Handler Failed][Headers={timestamp=1361443245220, id=a63c7877-29f6-46b2-96fc-35ad84589a82}]
failChannel
2013-02-21 10:41:00,227 DEBUG [org.springframework.integration.file.remote.handler.FileTransferringMessageHandler] (main) org.springframework.integration.file.remote.handler.FileTransferringMessageHandler#0 received message: [Payload=C:\projects\spring-integration\src\test\resources\citi\SEPA.enc][Headers={timestamp=1361443239551, id=73da6c1f-8658-4397-ab57-ea7591e284da, ORIGINAL_FILE=C:\projects\spring-integration\src\test\resources\citi\SEPA.xml}]
2013-02-21 10:41:00,227 DEBUG [org.springframework.integration.channel.DirectChannel] (main) preSend on channel 'successChannel', message: [Payload=C:\projects\spring-integration\src\test\resources\citi\SEPA.enc][Headers={timestamp=1361443260227, id=e16fb6be-e2c6-4c6e-bc99-e2e4fda9f735}]
2013-02-21 10:41:00,227 DEBUG [org.springframework.integration.transformer.MessageTransformingHandler] (main) org.springframework.integration.transformer.MessageTransformingHandler@7219d6af received message: [Payload=C:\projects\spring-integration\src\test\resources\citi\SEPA.enc][Headers={timestamp=1361443260227, id=e16fb6be-e2c6-4c6e-bc99-e2e4fda9f735}]
successChannel
2013-02-21 10:41:00,229 DEBUG [org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice] (main) Unable to attempt conversion of Message payload types. Component 'org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice#2e1551b0' has no explicit ConversionService reference, and there is no 'integrationConversionService' bean within the context.
2013-02-21 10:41:00,229 DEBUG [org.springframework.integration.channel.DirectChannel] (main) preSend on channel 'failureChannel', message: [Payload=org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException: Handler Failed][Headers={timestamp=1361443260229, id=187a95ad-ffdd-4151-9e02-e94e684f6dec}]
2013-02-21 10:41:00,229 DEBUG [org.springframework.integration.transformer.MessageTransformingHandler] (main) org.springframework.integration.transformer.MessageTransformingHandler@4c4b11e9 received message: [Payload=org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException: Handler Failed][Headers={timestamp=1361443260229, id=187a95ad-ffdd-4151-9e02-e94e684f6dec}]
failChannel
2013-02-21 10:41:00,242 INFO  [org.springframework.integration.endpoint.EventDrivenConsumer] (Thread-1) Removing {transformer} as a subscriber to the 'inputA' channel

1 个答案:

答案 0 :(得分:3)

onSuccessChannel上发送的邮件是AdviceMessage,其中包含payload中的表达式评估结果和inputMessage中的入站邮件。

只需使用"'foo'"作为onSuccessExpression

然后订阅<transformer/>successChannel

您可以使用payload.inputMessage来获取对该消息的引用。

或者,使用"#root"作为表达式,原始邮件将位于payload(以及inputMessage)。

编辑:

failureChannel上的消息是ErrorMessageMessageHandlingExpressionEvaluatingAdviceException payload。此例外有3个属性failedMessagecauseevalResult

请注意,在“成功”转换器中,这不起作用......

def file = new File(headers['ORIGINAL_FILE']);

因为headers引用AdviceMessage标题;你需要inputMessage.headers[...

在故障转换器上,您需要payload.failedMessage.headers[...