我正在使用通过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);
}