使用SOAP Web服务MULE构建自定义拦截器

时间:2013-05-15 12:59:06

标签: web-services soap mule interceptor

我正在使用Mule Community Edition 3.4。 我有一个UntilSuccessful组件的问题。该方案现已公开: 我有一个由UntilSuccessful组件组成的流,其中有一个SOAP组件向Web服务发出请求。在这个流程中也有一个ExcpetionStrategy。我遇到的问题是,当在UntilSuccessful内部发生异常时(即在SOAP组件中),ExcpetionStrategy无法处理它,因为它(抛出异常)由UntilSuccessful组件内的某些机制处理。 因为我需要在ExcpetionStrategy中处理Exception,所以我想构建一个自定义的出站拦截器(在SOAP组件内)拦截SOAP响应(抛出异常)并且能够抛出异常以触发ExcpetionStrategy。 任何人都可以帮我解决这个问题吗?我试图阅读文档,但它很稀疏,并没有很好地解释如何构建自定义出站异常。 我要做的是保存抛出Exception的名称(即如果服务器抛出NumberFormatException,我会将其名称保存在某处以便在ExceptionStrategy中使用它)

下面你可以看到一个mule配置文件片段:

<flow name="ProvaClient" doc:name="ProvaClient">
        <quartz:inbound-endpoint jobName="TalendJob" repeatInterval="5000" repeatCount="0" responseTimeout="10000" doc:name="Quartz">
            <quartz:event-generator-job>
                <quartz:payload>error</quartz:payload>
            </quartz:event-generator-job>
        </quartz:inbound-endpoint>
        <object-to-string-transformer doc:name="Object to String"/>
        <until-successful objectStore-ref="OS_Bean" maxRetries="2" secondsBetweenRetries="2" doc:name="Until Successful" deadLetterQueue-ref="myQueue">
            <processor-chain doc:name="Processor Chain: Wait For Web Service Response">
                <processor-chain doc:name="Processor Chain: Web Service">
                    <cxf:jaxws-client operation="getCode" clientClass="it.aizoon.prova.client.ProvaService" port="ProvaPort" enableMuleSoapHeaders="true" doc:name="SOAP">
                    </cxf:jaxws-client>
                      <http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="service/prova" method="POST" doc:name="HTTP"/>
                </processor-chain>
                <logger message="PAYLOAD: #[payload]" level="INFO" doc:name="Logger"/>
            </processor-chain>
        </until-successful>
        <catch-exception-strategy doc:name="Catch Exception Strategy">
           <!--   <processor ref="myExceptionHandler_id"/>  -->
            <logger message="EXCEPTION STRATEGY" level="INFO" doc:name="Logger"/>
        </catch-exception-strategy>
</flow>

在这里,您可以看到公开Web服务的服务器:

<flow name="provaServer" doc:name="provaServer">
        <http:inbound-endpoint exchange-pattern="request-response" doc:name="HTTP" host="localhost" path="service/prova" port="8081"/>
        <logger message="SERVER" level="INFO" doc:name="Logger"/>
        <cxf:jaxws-service serviceClass="it.aizoon.prova.Prova" doc:name="Process SOAP Request" />
        <component class="it.aizoon.prova.ProvaImpl" doc:name="Java"/>
</flow>

这里有ProvaImpl.java,即Web Service的实现。你怎么看,如果在getCode()函数中作为参数传递的字符串是错误的,抛出异常,我会认为它是由客户端中定义的异常策略管理的

@WebService(endpointInterface = "it.aizoon.prova.Prova",
                  serviceName = "Prova")
public class ProvaImpl implements Prova{

      @Override
      public String getCode(String code) throws NumberFormatException{
            // TODO Auto-generated method stub
            if(code.equals("error"))    throw new NumberFormatException();

            String str = "Andato a buon fine!";
            return str;
      }
}

1 个答案:

答案 0 :(得分:1)

我会改变方法,而不是使用拦截器。如果你需要调用异常策略而不首先触发直到成功的路由器,我会将你的cxf:jaxws-client等移动到私有流。引用Mule in Action第2版关于私人流程:

  

这种解耦允许定义处理和错误处理   私人流程的本地策略。

<flow name="ProvaClient" doc:name="ProvaClient">
    ...
    <until-successful objectStore-ref="OS_Bean"
        maxRetries="2" secondsBetweenRetries="2" doc:name="Until Successful"
        deadLetterQueue-ref="myQueue">
        <processor-chain doc:name="Processor Chain: Wait For Web Service Response">
            <processor-chain doc:name="Processor Chain: Web Service">
                <flow-ref name="externalCallFlow" />
            </processor-chain>
            <logger message="PAYLOAD: #[payload]" level="INFO" doc:name="Logger" />
        </processor-chain>
    </until-successful>

    ...
</flow>
<flow name="externalCallFlow">
    <cxf:jaxws-client operation="getCode"
        clientClass="it.aizoon.prova.client.ProvaService" port="ProvaPort"
        enableMuleSoapHeaders="true" doc:name="SOAP">
    </cxf:jaxws-client>
    <http:outbound-endpoint exchange-pattern="request-response"
        host="localhost" port="8081" path="service/prova" method="POST"
        doc:name="HTTP" />
    <catch-exception-strategy doc:name="Catch Exception Strategy">
        <!-- Handle exception here locally and return custom exception or error 
            message for the unil-successful router -->
    </catch-exception-strategy>
</flow>

然后,您可以在本地处理异常并返回自定义异常或错误                 使用以下属性捕获直到成功的路由器的消息:failureExpression =“exception-type:java.lang.NumberFormatException”

这是一个虚拟示例,我敲了一下抛出一个NumberFormatException,在异常策略中记录异常并重试:

<flow name="test" doc:name="test">
        <http:inbound-endpoint address="http://localhost:8081/test"
            doc:name="HTTP" />

        <until-successful objectStore-ref="OS_Bean"
            maxRetries="2" secondsBetweenRetries="2" doc:name="Until Successful">
            <processor-chain doc:name="Processor Chain: Wait For Web Service Response">
                <processor-chain doc:name="Processor Chain: Web Service">
                    <flow-ref name="externalCallFlow" doc:name="Flow Reference" />
                </processor-chain>
            </processor-chain>
        </until-successful>

    </flow>
    <flow name="externalCallFlow" doc:name="externalCallFlow">
        <scripting:component>
            <scripting:script engine="groovy">
                throw new java.lang.NumberFormatException();
                </scripting:script>
        </scripting:component>
        <default-exception-strategy>
            <processor-chain>
                <logger level="ERROR"
                    message="NumberFormatException Occurred : #[message.payload.getException().getCause()]" />
                <scripting:component>
                    <scripting:script engine="groovy">
                        throw message.payload.getException().getCause();
                </scripting:script>
                </scripting:component>
            </processor-chain>
        </default-exception-strategy>
    </flow>