2013-05-31 52 views
1

我有一個關於Mule 3.3.1 CE中的Web服務的問題。我有一個Web服務公開了三個操作和一個實現這些操作的類。這些操作可以返回結果(肯定)或異常(AuthExeception,ValidateExeception等)。 感謝SOAP Mule組件,當我提出Java異常時,框架能夠在SOAP Fault中編組java異常,但是如果我想要將SOAP Fault返回給客戶端,並使用Mule中的異常策略處理異常(即發送電子郵件),騾的行爲,這不是我能指望的。 換句話說,當我舉起一個AuthException時,流控制會傳遞給定義的異常策略,並且我不再能夠將SOAP Fault(AuthException)發送回客戶端。如何處理Mule中的SOAP Web服務中的異常策略

問題是:我怎樣才能發回SOAP響應並處理異常策略?

這裏下面則存在例外策略與記錄器組件簡單地實現騾子xml文件的一個片段:

<flow name="esb_consignmentFlow1" doc:name="esb_consignmentFlow1"> 
     <http:inbound-endpoint exchange-pattern="request-response" host="${conn.host}" port="8081" doc:name="HTTP" path="sgb/consignment" /> 
     <cxf:jaxws-service doc:name="Process SOAP Request" serviceClass="com.suzuki.sales.webservice.ProcessTriggerPortType"/> 
     <component class="it.aizoon.suzuki.service.implementation.TriggerConsignmentOperationsImplementation" doc:name="triggerConsignmentOperationsImpl"/> 
     <catch-exception-strategy doc:name="Catch Exception Strategy"> 
      <flow-ref name="ErrorHandling" doc:name="Flow Reference"/> 
     </catch-exception-strategy> 
</flow> 

<flow name="ErrorHandling" doc:name="ErrorHandling" > 
     <logger level="INFO" doc:name="Logger"/> 
</flow> 

我讀過一些關於處理策略,但我不知道這是否是正確的方法。 非常感謝您的幫助。

回答

2

這裏下面還有我的flow.xml

<?xml version="1.0" encoding="UTF-8"?> 

<mule xmlns:smtp="http://www.mulesoft.org/schema/mule/smtp" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf" xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:http="http://www.mulesoft.org/schema/mule/http" 
     xmlns="http://www.mulesoft.org/schema/mule/core" 
     xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" 
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd 
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd 
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd 
http://www.mulesoft.org/schema/mule/smtp http://www.mulesoft.org/schema/mule/smtp/current/mule-smtp.xsd 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd 
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd "> 
    <spring:beans> 
     <spring:bean id="consignmentProperty" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
      <!-- In questo modo riesco a definire un file di property esterno che non è in una locazione hard-coded --> 
      <spring:property name="ignoreUnresolvablePlaceholders" value="true"/> 
      <spring:property name="locations"> 
       <spring:list> 
        <spring:value>classpath:esb_consignment.properties</spring:value> 
        <spring:value>classpath:connections.properties</spring:value> 
        <spring:value>classpath:email.properties</spring:value> 
        <!-- L'ultimo nella lista è il più generico perché sovrascrive le properties --> 
       </spring:list> 
      </spring:property> 
     </spring:bean> 
     <spring:bean id="outfaultInterceptor" class="it.aizoon.suzuki.service.interceptors.CustomSoapFaultOutInterceptor"> 
      <spring:property name="outputQueue" value="ErrorHandler"/> 
     </spring:bean> 
    </spring:beans> 

    <flow name="TriggerConsignmentInterceptorService" doc:name="TriggerConsignmentInterceptorService"> 
     <http:inbound-endpoint exchange-pattern="request-response" host="${conn.host}" port="${conn.port}" doc:name="HTTP" path="sgb/consignment" /> 
     <cxf:jaxws-service doc:name="Process SOAP Request" serviceClass="com.suzuki.sales.webservice.ProcessTriggerPortType"> 
      <cxf:outFaultInterceptors> 
       <spring:ref bean="outfaultInterceptor"/> 
      </cxf:outFaultInterceptors>   
     </cxf:jaxws-service> 
     <component class="it.aizoon.suzuki.service.implementation.TriggerConsignmentOperationsImplementation" doc:name="triggerConsignmentOperationsImpl"/> 
    </flow> 
    <flow name="ErrorHandler" doc:name="ErrorHandler"> 
     <vm:inbound-endpoint exchange-pattern="one-way" path="ErrorHandler" doc:name="Error Handler"/> 
     <logger message="PAYLOAD: #[message.payload]" level="INFO" doc:name="Payload"/> 
     <set-payload value="Tipo di Eccezione: #[message.payload]" doc:name="Set Payload"/> 
     <smtp:outbound-endpoint host="${smtp.host}" 
           from="${email.fromAddress}" 
           to="${email.toAddress}" 
           subject="${email.subject}" 
           responseTimeout="10000" 
           doc:name="Email Notification"/> 
     <logger message="EMAIL SENT" level="INFO" doc:name="Result"/> 
     <catch-exception-strategy doc:name="Catch Exception Strategy"> 
      <logger message="ERRORE INVIO EMAIL" level="INFO" doc:name="Logger"/> 
     </catch-exception-strategy> 
    </flow> 

</mule> 

這裏下面有其處理SOAP響應和異常策略都

package it.aizoon.suzuki.service.interceptors; 

import javax.xml.bind.UnmarshalException; 
import org.apache.cxf.interceptor.Fault; 
import org.apache.cxf.message.Message; 
import org.apache.cxf.phase.AbstractPhaseInterceptor; 
import org.apache.cxf.phase.Phase; 
import org.mule.DefaultMuleMessage; 
import org.mule.api.MuleContext; 
import org.mule.api.MuleEvent; 
import org.mule.api.MuleException; 
import org.mule.api.client.MuleClient; 
import org.mule.api.context.MuleContextAware; 
import org.mule.module.cxf.CxfConstants; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import com.suzuki.sales.webservice.AuthenticationFailedException; 
import com.suzuki.sales.webservice.ValidationFailedException; 

public class CustomSoapFaultOutInterceptor extends AbstractPhaseInterceptor implements MuleContextAware{ 

    private static final Logger logger = LoggerFactory.getLogger(CustomSoapFaultOutInterceptor.class); 

    private String outputQueue; 
    private MuleContext context; 


    public CustomSoapFaultOutInterceptor() { 
     // TODO Auto-generated constructor stub 
     super(Phase.MARSHAL); 
    } 

    @Override 
    public void setMuleContext(MuleContext context) { 
     // TODO Auto-generated method stub 
     this.context = context; 
    } 

    @Override 
    public void handleMessage(Message message) throws Fault { 
     // TODO Auto-generated method stub 
     MuleClient client = context.getClient(); 
     MuleEvent event = (MuleEvent) message.getExchange().get(CxfConstants.MULE_EVENT); 
     DefaultMuleMessage muleMessage = (DefaultMuleMessage) event.getMessage(); 

     Throwable genericExec = message.getContent(Exception.class).getCause(); 
     Throwable exception = null; 

     if(genericExec instanceof ValidationFailedException){ 
      exception = (ValidationFailedException) genericExec; 

     }else if(genericExec instanceof AuthenticationFailedException){ 
      exception = (AuthenticationFailedException) genericExec; 

     }else if(genericExec instanceof UnmarshalException){ 
      exception = (UnmarshalException) genericExec; 
     } 


     try { 

      muleMessage.setPayload(exception); 
      client.send("vm://" + getOutputQueue(), muleMessage); 

     } catch (MuleException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public String getOutputQueue() { 
     return outputQueue; 
    } 

    public void setOutputQueue(String outputQueue) { 
     this.outputQueue = outputQueue; 
    } 

    public MuleContext getContext() { 
     return context; 
    } 

    public void setContext(MuleContext context) { 
     this.context = context; 
    } 
} 
+0

這裏是我的解決方案 –

0

Mule抑制異常策略之外的異常。

對於您想要處理異常以及將其作爲回覆發送的場景,將提供一個自定義轉換器來準備帶有異常的soap故障,然後在異常策略流程中將其設置爲有效負載。

<flow name="ErrorHandling" doc:name="ErrorHandling" > 
    <logger level="INFO" doc:name="Logger"/> 
    <custom-transformer class="com.example.service.ErrorTransformer"></custom-transformer> 
</flow> 

和一個變壓器來準備錯誤信息。

@Override 
public Object transformMessage(MuleMessage message, String outputEncoding) 
     throws TransformerException { 

    String exceptionMessage = message.getExceptionPayload().getException().getCause().getMessage() ;   

    String outputMessage = "<soap:Fault xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">  " + 
      " <faultcode>soap:Server</faultcode> " + 
      "<faultstring>" + exceptionMessage + "</faultstring>  " + 
      "</soap:Fault>"; 

    return outputMessage; 
} 

注意:這是一個採樣變壓器。根據您的情況自定義它。

+0

首先謝謝你的答覆攔截。我會知道是否用你的解決方案發送了SOAP響應,如果是,在哪裏?換句話說,如果我使用變換器來構建SOAP響應...發送的響應在哪裏?我需要一個SOAP和一個HTTP組件,對吧? –

+0

這是一個以字符串形式準備的SOAP錯誤體。這將作爲您的http:入站端點的回覆發回。 – user1760178

+0

我用了一個outFaultInterceptor。通過這種方式,我可以捕獲異常,使用client.send()API並將消息寫入VM隊列中。因此,主要流程發回肥皂響應,並且SMTP組件發送電子郵件 –