2012-06-19 12 views
7

Sono nuovo alla Spring-WS, e lentamente mi avvolge la testa. In questo momento sto scrivendo un semplice client per comunicare con un WS esistente. Sto usando il metodo WebServiceTemplate e il metodo marshalSendAndReceive. Tutto funziona beneCome annullare un errore SOAP in un errore FaultMessageResolver?

Tuttavia, quando si verifica un errore SOAP, il WST genera una SoapFaultClientException. Ho notato che posso creare il mio FaultMessageResolver per verificare cosa è contenuto nell'errore SOAP. Tuttavia, quando cerco di unmarshalling il WebServiceMessage nel mio FaultMessageResolver, ricevo il seguente messaggio di errore:

JAXB unmarshalling exception; nested exception is javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Fault"). Expected elements are .... 

Ovviamente, la mia unmarshaller non è configurato correttamente. Devo generare il modello di errore JAXB io stesso usando xjc per poter quindi annullare l'errore? Sono un po 'sorpreso che questo non esista già.

Esiste un modo migliore di aggiungere le informazioni di errore personalizzate dall'interno del mio sapone: risposta all'errore? Il mio errore è simile al seguente e sto cercando di estrarre/accedere all'elemento serviceErrors.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
     <soap:Fault> 
     <faultcode>soap:Server</faultcode> 
     <faultstring>Blaze Data Error</faultstring> 
     <detail> 
      <ns14:serviceErrors xmlns="http://www.nb.com/ClientServices/LendingSimulation/CalculateProfitabilityRequest" xmlns:ns13="http://www.nb.com/fw/errorMgmt" xmlns:ns14="http://www.nb.com/ClientServices/LendingSimulation/V1" > 
       <ns13:faultstring>ServiceExecutionError</ns13:faultstring> 
       <ns13:serviceError> 
        <ns13:errorCode>C10F1013</ns13:errorCode> 
        <ns13:errorType>B</ns13:errorType> 
        <ns13:errorMessage>Unable to retreive additional data</ns13:errorMessage> 
        <ns13:fieldName>Message error received from PHClient : [An unexpected error code was received : system=PH context=[empty]]</ns13:fieldName> 
        <ns13:systemId>Calculator</ns13:systemId> 
        <ns13:time>2012-06-19 14:45:10.151-0400</ns13:time> 
       </ns13:serviceError> 
      </ns14:serviceErrors> 
     </detail> 
     </soap:Fault> 
    </soap:Body> 
</soap:Envelope> 

Grazie!

Eric

risposta

4

Sulla base l'errore che stai ricevendo, sembra che si sta tentando di unmarshall sorgente XML partire dal nodo <soap:Fault>. Senza vedere il tuo codice Java, significa che probabilmente stai cercando di rimuovere l'origine da message.getSoapBody().getFault()

In realtà devi andare più in profondità per arrivare al nodo <ns14:serviceErrors>. Si dovrebbe essere in grado di arrivare a questo per il seguente percorso ... forse non tutti in una volta :)

message.getSoapBody().getFault().getFaultDetail().getDetailEntries().next() 
+0

Grazie. Questo è praticamente ciò che ho finito per fare. Ma questo ottiene solo un errore informazioni alla volta, che ho pensato fosse piuttosto strano. Mi sarei aspettato qualche sistema per consentirmi di eliminare tutti i difetti in una lista o in una serie di errori. –

2

sto usando org.springframework.ws.client.core.WebServiceTemplate. Mi sono imbattuto nello stesso problema con Fault unmarshalling. Ho risolto questo problema impostando WebServiceTemplate proprietà checkConnectionForFault a false. Quindi nel mio caso è probabile che il server non abbia restituito lo stato 500 per l'errore.

Quindi spring-ws ha analizzato l'errore e lo ha passato al valore predefinito FaultMessageResolver e ho ottenuto un regolare SoapFaultClientException da catturare.

Ma questo mi ha fatto solo il messaggio del guasto così ho dovuto aggiungere anche un costume FaultMessageResolver ed estrarre il messaggio sulla stessa linea:

SoapFaultDetail faultDetail = ((SoapMessage) message).getSoapBody().getFault().getFaultDetail(); 
Iterator<SoapFaultDetailElement> detailEntries = faultDetail.getDetailEntries(); 
StringBuilder errorMessage = new StringBuilder(); 

while (detailEntries.hasNext()) { 
    SoapFaultDetailElement detailElement = detailEntries.next(); 
    Node node = ((DOMResult) detailElement.getResult()).getNode(); 
    CustomServiceFault serviceFault = (CustomServiceFault) marshaller.unmarshal(new DOMSource(node)); 
    errorMessage.append(serviceFault.getErrorCode() + ": " + serviceFault.getErrorMessage()); 
} 
throw new CustomException(errorMessage.toString()); 

Il marshaller è lo stesso di quello utilizzato per il WebserviceTemplate.

Problemi correlati