2012-06-19 14 views
7

Tôi mới làm quen với Spring-WS và từ từ thu hút đầu tôi. Ngay bây giờ, tôi đang viết một máy khách đơn giản để giao tiếp với một WS hiện có. Tôi đang sử dụng WebServiceTemplate và phương thức marshalSendAndReceive. Mọi thứ đều hoạt động tốt.Làm thế nào để unmarshal một lỗi SOAP trong một FaultMessageResolver?

Tuy nhiên, khi lỗi SOAP xảy ra, WST sẽ đưa ra một SoapFaultClientException. Tôi nhận thấy rằng tôi có thể tạo FaultMessageResolver của riêng mình để kiểm tra những gì có trong lỗi SOAP. Tuy nhiên, khi tôi cố gắng unmarshal các WebServiceMessage trong FaultMessageResolver của tôi, tôi nhận được thông báo lỗi sau:

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

Rõ ràng, unmarshaller của tôi không được cấu hình đúng cách. Tôi có phải tạo ra mô hình lỗi JAXB bản thân mình bằng cách sử dụng xjc để sau đó có thể unmarshal lỗi? Tôi hơi ngạc nhiên rằng điều này không tồn tại.

Có cách nào tốt hơn để thêm thông tin lỗi tùy chỉnh của tôi từ bên trong xà phòng của tôi: phản hồi lỗi không? Lỗi của tôi trông giống như sau và tôi đang cố gắng trích xuất/truy cập mục 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> 

Cảm ơn!

Eric

Trả lời

4

Dựa trên những lỗi mà bạn đang nhận được, có vẻ như bạn đang cố gắng để unmarshall nguồn XML bắt đầu với nút <soap:Fault>. Nếu không thấy mã Java của bạn, điều này có nghĩa là bạn có thể đang cố gắng hủy hợp nhất nguồn từ message.getSoapBody().getFault()

Bạn thực sự cần đi sâu hơn để đến nút <ns14:serviceErrors>. Bạn sẽ có thể để có được điều này bằng cách đường dẫn sau ... có lẽ không phải tất cả cùng một lúc :)

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

Cảm ơn. Đó là khá nhiều những gì tôi đã làm. Nhưng điều đó chỉ nhận được một thông tin lỗi tại một thời điểm, mà tôi nghĩ là khá lạ. Tôi đã có thể mong đợi một số hệ thống cho phép tôi unmarhsal tất cả các lỗi vào một danh sách hoặc mảng lỗi. –

2

Tôi đang sử dụng org.springframework.ws.client.core.WebServiceTemplate. Tôi gặp phải vấn đề tương tự với Fault unmarshalling. Tôi đã giải quyết vấn đề này bằng cách đặt thuộc tính WebServiceTemplatecheckConnectionForFault thành false. Vì vậy, trong trường hợp của tôi nó có khả năng gây ra bởi các máy chủ không trở về tình trạng 500 cho lỗi.

Sau đó, spring-ws phân tích cú pháp lỗi và chuyển nó đến mặc định FaultMessageResolver và tôi nhận được thông thường SoapFaultClientException để bắt.

Nhưng điều đó đã cho tôi chỉ được thông báo của lỗi vì vậy tôi cũng đã thêm một tùy chỉnh FaultMessageResolver và trích xuất các thông điệp dọc theo dòng giống nhau:

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()); 

Các marshaller là giống như một sử dụng cho WebserviceTemplate.

Các vấn đề liên quan