【问题标题】:JAX-WS Handler Ignoring Fault Sub-elements忽略故障子元素的 JAX-WS 处理程序
【发布时间】:2013-01-09 22:51:10
【问题描述】:

我正在使用基于 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 的子元素应该是&lt;faultcode&gt;&lt;faultstring&gt;,而不是不同的命名空间&lt;fault&gt;。不幸的是,我无法让网络服务改变这一点。

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

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

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

【问题讨论】:

    标签: java web-services soap jax-ws soap-client


    【解决方案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);
    }
    

    【讨论】:

    • 一天结束时,我编写了一个 XSLT 和自定义 WSDL/XSD,在消息到达 WAS 之前将消息转换为安全设备中的正确 SOAP 错误。在 WAS 内部,我使用了自定义 WSDL/XSD 并正常处理了异常。
    【解决方案2】:

    如果您使用的是 JAX-WS,则可以使用 SOAP 错误。或者,您需要带有 @WebFault 注释的异常。你可以在Using SOAP Faults and Exceptions in Java JAX-WS Web Services - Eben Hewitt on Java 中找到一个很好的例子。

    查看returning null or throw exceptionHow to throw a custom fault on a JAX-WS web service?的答案

    例子:

    @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 中测试

    【讨论】:

    • 正如我所提到的,我无法控制响应消息。我正在运行客户端,而不是服务器。如果他们的自定义错误出现在 detail 元素中,这将不是问题。他们的错误是结构 env:Fault > abc:fault。我无法获取 abc:fault,因为 JAX-WS 将其从 SOAPHandler 中完全删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2011-01-05
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    相关资源
    最近更新 更多