我正在使用通过SOAP的JAX-WS实现Web服务客户端。其错误代码以以下方式返回:

<?xml version = '1.0' encoding = 'UTF-8'?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
   <env:Header>
      <!-- header stuff goes here -->
   </env:Header>
   <env:Body>
      <env:Fault>
        <abc:fault xmlns:abc="http://example.com/abc">
           <abc:faultcode>12345</abc:faultcode>
           <abc:faultstring>Error message goes here</abc:faultstring>
        </abc:fault>
     </env:Fault>
   </env:Body>
</env:Envelope>


据我所知,这不是处理SOAP错误的正确方法。 env:Fault的子元素应为<faultcode><faultstring>,而不是不同的命名空间<fault>。不幸的是,我无法使Web服务对此进行更改。

我希望我能够在SOAPHandler中解析此消息并将其转换为常规错误,然后再传递给我的其余代码,但是,当我在较早的Handler中记录该消息时,我发现Fault元素完全空的。 <abc:fault>不见了!

我在WebSphere 7上使用JAX-WS,并且尝试在系统属性中将“ jaxws.payload.highFidelity”设置为true。关于如何获取原始消息的任何线索?

如果不这样做,将导致带有NullPointerException的WebServiceException,因为JAX-WS找不到故障代码。

最佳答案

因此,我找到了问题的答案。 WebSphere 7使用Axis2。 Axis2的MessageContext提供了一个名为“ TRANSPORT_IN”的属性,其中包含ByteArrayInputStream。顾名思义,TRANSPORT_IN包含接收到的确切SOAP消息。

我使用SAXHandler检索Handler#handleFault方法中的原始SOAP消息,以检索abc:fault消息。然后,我将abc:fault>故障代码和故障字符串写入soapenv:Fault故障代码和故障字符串。然后,我的应用程序将SOAPFaultException当作普通的异常处理。

我仍然乐于接受任何更好的答案,因为这感觉就像是回旋的方式。

处理程序代码:

public boolean handleFault(SOAPMessageContext context) {
    SOAPMessage m = context.getMessage();
    if(m != null) {
        SOAPBody body = m.getSOAPBody();
        SOAPFault fault = body.getFault();
        setAbcFault(fault, context);
    }
}

private void setAbcFault(SOAPFault fault, MessageContext context) {
    ByteArrayInputStream bis = (ByteArrayInputStream)context.get("TRANSPORT_IN");
    // do sax parsing on the input stream
    fault.setFaultCode(abcFaultCodeQName);
    fault.setFaultString(abcFaultString);
}

10-06 02:50