0

我正在使用基于 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>and <faultstring>,而不是不同的命名空间<fault>。不幸的是,我无法让 Web 服务改变这一点。

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

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

不理会这个将导致带有 NullPointerException 的 WebServiceException,因为 JAX-WS 找不到故障代码。

4

2 回答 2

1

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

我使用 SAXHandler 解析了 Handler#handleFault 方法中的原始 SOAP 消息,以检索 abc:fault 消息。然后我将 abc:fault > faultcode 和 faultstring 写入了 soapenv:Fault faultcode 和 faultstring。然后我的应用程序处理 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);
}
于 2013-01-27T17:39:12.357 回答
0

如果您使用的是 JAX-WS,则可以使用 SOAP 错误。或者,您需要带有@WebFault注释的异常。您可以在使用 Java JAX-WS Web 服务中的 SOAP 错误和异常 - Eben Hewitt on Java中找到一个很好的示例。

请参阅返回 null 或抛出异常的答案以及如何在 JAX-WS Web 服务上抛出自定义错误?

例子:

@WebService
public class CalculatorWS {

    public String factorial(int n) throws FactorialException {
        if (n < 0) {
            throw new FactorialException("Negative number!",     // faultstring
                                         "The number n = " + n); // detail
        }
        return BigIntegerMath.factorial(n).toString();
    }

}

和:

public class FactorialException extends Exception {

    String detail;

    public FactorialException(String message, String detail) {
        super(message);
        this.detail = detail;
    }

    public String getFaultInfo() {
        return detail;
    }

}

如果请求是:

<soapenv:Envelope ... >
   <soapenv:Header/>
   <soapenv:Body>
      <test:factorial>
         <arg0>-1</arg0>
      </test:factorial>
   </soapenv:Body>
</soapenv:Envelope>

回应是:

<soapenv:Envelope ... >
   <soapenv:Body>
      <soapenv:Fault>
         <faultcode>soapenv:Server</faultcode>
         <faultstring>Negative number!</faultstring>
         <detail>
            <ns2:FactorialExceptionBean xmlns:ns2="http://...">
                The number n = -1
            </ns2:FactorialExceptionBean>
         </detail>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

(在 Websphere 7 中测试)

于 2013-01-26T00:32:31.913 回答