2013-05-15 2 views
0

J'utilise Mule Community Edition 3.4. J'ai un problème avec le composant UntilSuccessful. Le scénario est maintenant exposé: J'ai un flux composé par un composant UntilSuccessful dans lequel il y a un composant SOAP qui fait une demande à un service Web. Dans ce flux il y a aussi une ExcpetionStrategy. Le problème que j'ai est que lorsqu'une exception se produit à l'intérieur de UntilSuccessful (c'est-à-dire dans le composant SOAP) l'ExcpetionStrategy n'est pas capable de le gérer car elle (Exception levée) est gérée par un mécanisme dans le composant UntilSuccessful. Parce que j'ai besoin de gérer l'Exception dans ExcpetionStrategy, j'ai pensé à construire un intercepteur sortant personnalisé (dans le composant SOAP) qui intercepte la réponse SOAP (une exception si elle est levée) et qui est capable de lancer une Exception pour déclencher l'ExcpetionStrategy. Quelqu'un pourrait-il m'aider avec ce problème? J'ai essayé de lire la documentation mais elle est éparse et n'explique pas très bien comment créer une exception sortante personnalisée. Ce que je à faire est de sauver quelque part le nom d'exception jeté (par exemple si le serveur jeté un NumberFormatException, je sauverais son nom quelque part afin de l'utiliser dans le ExceptionStrategy)Création d'un intercepteur personnalisé avec le service Web SOAP MULE

Ci-dessous vous pouvez voir un extrait de mule fichier de configuration:

<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> 

ici vous pouvez voir le serveur qui expose un service 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> 

Et là, il y a la ProvaImpl.java, la mise en œuvre du service Web. Comment vous pouvez le voir, si la chaîne passée en argument en fonction getCode() est une erreur, une exception dans jeté et je qu'il est géré par la stratégie d'exception définie dans le client

@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; 
     } 
} 

Répondre

1

je changerais l'approche plutôt que d'utiliser un intercepteur. Si vous avez besoin d'invoquer la stratégie d'exception sans d'abord déclencher le routeur until-succesful, je déplacerais votre cxf: jaxws-client etc. vers un flux privé. Pour citer Mule en 2e édition d'action sur les flux privés:

Ce découplage permet de définir le traitement traitement et les erreurs stratégies qui sont locales au flux privé.

<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> 

Vous pouvez ensuite gérer les exceptions localement et renvoyer un message personnalisé exception ou erreur pour le routeur jusqu'à ce qu'ils soient réussi à attraper en utilisant l'attribut suivant: failureExpression = « type d'exception: java.lang.NumberFormatException »

Voici un exemple fictif, je frappai à jeter un NumberFormatException, connectez-vous à l'exception de la stratégie d'exception et une nouvelle tentative:

<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> 
+0

d'abord vous remercier de la re réponse. Si getCode() renvoie une exception comme NumberFormatException, comment puis-je définir comme charge utile ce nom d'exception dans le message de la stratégie d'exception? Mon but est d'envoyer un mail avec l'exception levée. Je ne veux pas obtenir le SOAPFaultException, mais le NumberFormatException –

+0

Mis à jour la réponse avec la façon de définir la charge utile de l'exception, etc. –

+0

Désolé Ryan, où est la mise à jour? –