javax.xml.ws.soap.SOAPFaultException:解组错误:从AXIS迁移到CXF后出现意外元素(uri:“”,local:“fault”)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javax.xml.ws.soap.SOAPFaultException:解组错误:从AXIS迁移到CXF后出现意外元素(uri:“”,local:“fault”)相关的知识,希望对你有一定的参考价值。
问题
我正在尝试将我的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>
这使得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,unmarshaller期望fault元素具有某些命名空间声明,但它没有一个。
任何人都可以建议该客户端有什么问题,以及如何避免错误?
测试解决方案
有很多类似的问题,但并非所有解决方案都适用于我,因为我无法在服务器端进行任何更改(至少出于向后兼容性原因),并且不了解更改WSDL。因此,仅在客户端限制(包括其(重新)生成)。我已经根据类似的问题尝试了几种可能的解决方案:
- 使用默认名称空间声明添加package-info.class - 没有任何变化;
- 强制为生成的Fault和/或Fault_Exception类设置空命名空间 - 在构造异常对象期间在CXF例程中使用NullPointerException(参见下面的EDIT部分);
- 使用SAX XmlFilter - 无法找到将其嵌入CXF生成的例程的方法。
附加信息
CXF为异常生成了类,其faultInfo(没有任何更改)如下所示: 故障类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"faultcode",
"faultstring",
"faultactor",
"detail"
})
@XmlRootElement(name = "fault")
public class Fault {
@XmlElement(required = true)
protected String faultcode;
...
Fault_Exception类:
@WebFault(name = "fault", targetNamespace = "http://some.namespace.org")
public class Fault_Exception extends Exception {
private Fault fault;
public Fault_Exception() {
super();
}
...
一些WSDL摘录。 WSDL错误消息声明:
<wsdl:message name="Fault">
<wsdl:part name="fault" element="fault"/>
</wsdl:message>
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操作描述示例:
<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根元素:
<?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/">
可以提供更多附加信息。 提前致谢!
编辑:
在“调查”期间,我发现NullPointerException(我在“Tested Solutions”中提到过)并不是我错误行为的结果。这是CXF的一个错误:
这两张票都以“已修复”的分辨率关闭,但在评论中,用户报告他们仍然可以捕获此错误。似乎开发人员没有涵盖CXF处理自定义异常的所有情况,并且由于某些原因它有时会导致
org.apache.cxf.interceptor.ClientFaultConverter processFaultDetail INFO:创建异常时发生异常:null 显示java.lang.NullPointerException
有没有人遇到过这个问题?
这似乎是服务不符合其自身合同的情况。虽然您可能无法控制服务,但这值得与服务提供商讨论。
客户抱怨的错误元素是第一个'detail'元素的直接子元素。
根据异常消息,'detail'的第一个子元素应该是(假设目标命名空间'http://some.namespace.org')AnsBonusAutopayStatus或AnsBonusAutopaySubscribe而不是{} fault元素。
如果您能够在操作和wsdl类型的故障声明周围提供更多的wsdl,则可以提供额外的静态分析。
以上是关于javax.xml.ws.soap.SOAPFaultException:解组错误:从AXIS迁移到CXF后出现意外元素(uri:“”,local:“fault”)的主要内容,如果未能解决你的问题,请参考以下文章