javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: 从 AXIS 迁移到 CXF 后意外的元素 (uri:"", local:"fault")

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26252200/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 02:06:06  来源:igfitidea点击:

javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: unexpected element (uri:"", local:"fault") after migrating from AXIS to CXF

javaxmlweb-serviceswsdlcxf

提问by Toparvion

The Problem

问题

I am trying to migrate my web service clientfrom Apache AXIS-1to Apache CXF. The web service itself runs om AXIS-1 and is out of my control.
I generated all the CXF artifacts and the client has been working well until any fault is thrown by the service. The faulty XML looks like:

我正在尝试将我的 Web 服务客户端Apache AXIS-1迁移到Apache CXF。Web 服务本身在 AXIS-1 上运行,不受我的控制。
我生成了所有 CXF 工件,并且客户端一直运行良好,直到服务抛出任何错误。错误的 XML 看起来像:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <soapenv:Fault>
      <faultcode>soapenv:Server</faultcode>
      <faultstring>Remote error processing component card request</faultstring>
      <detail>
        <fault>
          <faultcode>:-303</faultcode>
          <faultstring>Remote error processing component card request</faultstring>
          <faultactor>remote_service</faultactor>
          <detail>
            <common-detail>
              <code>-303</code>
              <message>Remote error processing component card request</message>
            </common-detail>
          </detail>
        </fault>
      </detail>
    </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>

This makes the CXF generated client fall with exception:

这使得 CXF 生成的客户端出现异常:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"fault"). 
Expected elements are <{http://some.namespace.org}AnsBonusAutopayStatus>,<{http://some.namespace.org}AnsBonusAutopaySubscribe>,
...
<{http://some.namespace.org}fault>
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:603)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:244)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:239)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:116)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1009)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:446)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:427)
    at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:71)
    at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:137)
    at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:240)
    at com.sun.xml.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:123)
...

AFAIU from this stacktrace, unmarshaller expects the faultelement to have certain namespace declaration but it comes without one.

来自此堆栈跟踪的 AFAIU,解组器希望故障元素具有特定的命名空间声明,但它没有。

Can anyone suggest what is wrong with that client and how to avoid the error?

任何人都可以建议该客户有什么问题以及如何避免错误?

Tested Solutions

经过测试的解决方案

There are a lot of similar questions but not all the solutions are applicable for me because I can't change anything on the server side (at least for backward compatibility reasons) and changing the WSDL is also not appreciated. Thus changes are restricted in client side only (including its (re)generation). I've tried several possible solutions based on similar questions:

有很多类似的问题,但并非所有解决方案都适用于我,因为我无法在服务器端更改任何内容(至少出于向后兼容性的原因)并且更改 WSDL 也不受欢迎。因此,更改仅限于客户端(包括其(重新)生成)。我已经根据类似的问题尝试了几种可能的解决方案:

  • adding package-info.classwith default namespace declaration - nothing changes;
  • force setting empty namespace for generated Faultand/or Fault_Exceptionclasses - NullPointerExceptionin CXF routines during constructing the exception object (see EDIT section below);
  • using SAX XmlFilter- couldn't find a way to embed it into CXF generated routines.
  • 添加具有默认命名空间声明的package-info.class- 没有任何变化;
  • 在构造异常对象期间强制为生成的Fault和/或Fault_Exception类设置空命名空间- CXF 例程中的NullPointerException(请参阅下面的编辑部分);
  • 使用SAX XmlFilter- 找不到将其嵌入 CXF 生成的例程的方法。

Additional Info

附加信息

CXF generated classes for exception and its faultInfo (without any of my changes) look like:
Faultclass:

CXF 生成的异常类及其故障信息(没有我的任何更改)如下所示:
故障类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "faultcode",
    "faultstring",
    "faultactor",
    "detail"
})
@XmlRootElement(name = "fault")
public class Fault {

    @XmlElement(required = true)
    protected String faultcode;
...

Fault_Exceptionclass:

Fault_Exception类:

@WebFault(name = "fault", targetNamespace = "http://some.namespace.org")
public class Fault_Exception extends Exception {

    private Fault fault;

    public Fault_Exception() {
        super();
    }
...

Some WSDL excerpts. WSDL Faultmessage declaration:

一些 WSDL 摘录。 WSDL 错误消息声明:

  <wsdl:message name="Fault">
    <wsdl:part name="fault" element="fault"/>
  </wsdl:message>

XSD faultelement:

XSD 故障要素:

<xs:element name="fault">
<xs:annotation>
  <xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
<xs:complexType>
  <xs:sequence>
    <xs:element name="faultcode">...</xs:element>
    <xs:element name="faultstring">...</xs:element>
    <xs:element name="faultactor">...</xs:element>
    <xs:element minOccurs="0" name="detail">...</xs:element>
  </xs:sequence>
</xs:complexType>
</xs:element>

WSDL operation descriptionexample:

WSDL 操作描述示例:

<wsdl:operation name="BonusConversionState">
  <wsdl:input name="BonusConversionStateRequest" message="tns:BonusConversionStateRequest"/>
  <wsdl:output name="BonusConversionStateResponse" message="tns:BonusConversionStateResponse"/>
  <wsdl:fault name="Fault" message="tns:Fault"/>
</wsdl:operation>

WSDL root element:

WSDL 根元素:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://some.namespace.org" 
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
                  xmlns:tns="http://some.namespace.org" 
                  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

More additional info can be provided.
Thanks in advance!

可以提供更多附加信息。
提前致谢!

EDIT:

编辑:

During "investigation" I've found out that NullPointerException(that I mentioned in "Tested Solutions") is not a consequence of my faulty actions. It's a bug of CXF:

在“调查”期间,我发现NullPointerException(我在“测试解决方案”中提到的)不是我错误操作的结果。这是CXF的一个错误:

Both tickets are closed with resolution "Fixed", but in comments users report they still catch this bug. It seems that developers did not cover all the cases where custom exceptions are handled by CXF and for some reasons it sometimes leads to

两张票都以“已修复”分辨率关闭,但在评论中,用户报告他们仍然发现了这个错误。似乎开发人员并未涵盖 CXF 处理自定义异常的所有情况,并且由于某些原因有时会导致

org.apache.cxf.interceptor.ClientFaultConverter processFaultDetail
INFO: Exception occurred while creating exception: null
java.lang.NullPointerException

org.apache.cxf.interceptor.ClientFaultConverter processFaultDetail
INFO:创建异常时发生异常:null
java.lang.NullPointerException

Has anybody ever faced this problem too?

有没有人也遇到过这个问题?

回答by dcbyers

This appears to be a case of the service not complying with its own contract where the fault is concerned. While you may not have control of the service, this is worth a discussion with the service provider.

这似乎是服务不遵守与故障有关的自己的合同的情况。虽然您可能无法控制服务,但这值得与服务提供商讨论。

The fault element your client is complaining about is the immediate child of the first 'detail' element.

您的客户抱怨的错误元素是第一个“详细信息”元素的直接子元素。

Based on the exception message, the first child element of 'detail' is expected to be (assuming target namespace 'http://some.namespace.org') either AnsBonusAutopayStatus or AnsBonusAutopaySubscribe and not the {}fault element.

根据异常消息,“detail”的第一个子元素预计为(假设目标命名空间为“ http://some.namespace.org”)AnsBonusAutopayStatus 或 AnsBonusAutopaySubscribe,而不是故障元素。{}

If you are able to provide a bit more of the wsdl around the fault declaration in the operation and the wsdl types additional static analysis can be provided.

如果您能够在操作中的错误声明周围提供更多的 wsdl,并且 wsdl 类型可以提供额外的静态分析。