[英]Validator error on a JAX-WS service implemented with Apache CXF
我正在使用Apache CXF开发JAX-WS服务,该服务从两个来源获取其类型定义。 XSD模式文件在... / types /命名空间中定义了各种类型,并且存在带有JAXB注释的匹配Java类。 端点在Java接口中定义,并在... / service /名称空间内带有@WebService相关的批注。 WSDL由Apache CXF生成,它使用XSD模式文件中的类型定义以及为@WebService端点获取的请求/响应消息和参数生成的类型定义。
我在... / service /名称空间内遇到了有关Apache CXF生成的类型之一的以下验证器错误。
Caused by: org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 10; cvc-elt.1: Cannot find the declaration of element 'ser:subscriberId'.
端点在... / service /名称空间中的定义如下:
@WebService(name="gatewayService",
targetNamespace="http://www.mydomain.com/gateway/schema/service/")
public interface GatewayEndpoint {
// ...
@WebMethod(operationName="addService")
@XmlElement(required=true) public Response addService(
@XmlElement(required=true) @WebParam(name="subscriberId") long subscriberId,
@XmlElement(required=true) @WebParam(name="service") Service service)
throws GatewayException;
// ...
}
JAX-WS端点在spring配置文件中定义如下:
<!-- Apache CXF endpoint -->
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<jaxws:endpoint id="gatewayndpoint" implementor="#gatewayEndpointImpl" address="/gateway">
<jaxws:schemaLocations>
<jaxws:schemaLocation>classpath:/schemas/gateway_schema.xsd</jaxws:schemaLocation>
</jaxws:schemaLocations>
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>
gateway_schema.xsd包含各种complexType定义,其中... / types /名称空间中的Service定义:
<xs:complexType name="Service">
<xs:sequence>
<xs:element name="name">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="deviceLimit" type="xs:int"/>
<xs:element maxOccurs="unbounded" minOccurs="0" name="subscription" nillable="true" type="gateway:Subscription"/>
<xs:element maxOccurs="unbounded" minOccurs="0" name="package" nillable="true" type="gateway:Package"/>
</xs:sequence>
</xs:complexType>
匹配的JAXB注释类为:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Service")
public class Service {
@XmlElement(required=true)
private String name;
private int deviceLimit;
@XmlElement(name="subscription", nillable=true)
private List<Subscription> subscriptions;
@XmlElement(name="package", nillable=true)
private List<Package> packages;
//.. getters and setters
}
一切都打包在war文件中,部署后生成的WSDL如下所示:
<?xml version="1.0" ?>
<wsdl:definitions
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://www.mydomain.com/gateway/schema/service/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ns2="http://schemas.xmlsoap.org/soap/http"
xmlns:ns1="http://www.mydomain.com/gateway/schema/services/"
name="GatewayService"
targetNamespace="http://www.mydomain.com/gateway/schema/service/">
<wsdl:types>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:gateway="http://www.mydomain.com/gateway/schema/types/"
elementFormDefault="qualified"
targetNamespace="http://www.mydomain.com/gateway/schema/types/"
version="1.0">
<!--
Various type definitions available in the gateway_schema.xsd
Among them the typ:Service definition
-->
</xs:schema>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.mydomain.com/gateway/schema/services/"
xmlns:ns0="http://www.mydomain.com/gateway/schema/types/"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://www.mydomain.com/gateway/schema/services/">
<xsd:import namespace="http://www.mydomain.com/gateway/schema/types/"></xsd:import>
<!--
Definitions generated by Apache CXF
-->
<xsd:element name="addService" type="tns:addService"></xsd:element>
<xsd:complexType name="addService">
<xsd:sequence>
<xsd:element name="subscriberId" type="xsd:long"></xsd:element>
<xsd:element name="service" type="ns0:Service"></xsd:element>\
</xsd:sequence>
</xsd:complexType>
<!-- .... -->
</xsd:schema>
</wsdl:types>
<wsdl:message name="addService">
<wsdl:part element="tns:addService" name="parameters"></wsdl:part>
</wsdl:message>
<!... rest of messages, portTypes, bindings and wsdl:service -->
</wsdl:definitions>
SoapUI为此服务生成的请求是这样的:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://www.mydomain.com/gateway/schema/service/" xmlns:typ="http://www.mydomain.com/gateway/schema/types/">
<soapenv:Header/>
<soapenv:Body>
<ser:addService>
<ser:subscriberId>100</ser:subscriberId>
<ser:service>
<typ:name>12345678</typ:name>
<typ:deviceLimit>1</typ:deviceLimit>
<!--Zero or more repetitions:-->
<typ:subscription name="a"/>
<!--Zero or more repetitions:-->
<typ:package name="b"/>
</ser:service>
</ser:addService>
</soapenv:Body>
</soapenv:Envelope>
验证器以关于SubscriberId元素的验证错误为响应:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Unmarshalling Error: cvc-elt.1: Cannot find the declaration of element 'ser:subscriberId'.</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
对于我来说很奇怪,对于与方法调用参数相对应的生成类型之一,验证器失败,这很简单。 任何人都暗示可能是什么问题?
Apache CXF版本是2.7.10,我正在使用Java 1.7,所以我想它正在使用其中的任何JAXB实现。
您遇到名称空间问题...在wsdl中,对于addService / subscriberId元素,您具有名称为“ http://www.mydomain.com/gateway/schema/services/ ”的名称空间,但是您正在发送“ http:/ /www.mydomain.com/gateway/schema/service/ “。 注意最后没有“ s”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.