WebService服务提供的接⼝,soap协议的报⽂中,参数必须符合顺序
问题的由来
项⽬的⼀个接⼝,是通过dubbo提供的配置,暴露出的⼀个webservice接⼝,可以看,其实也是委托给了cxf这个开源组件来做的。
因为提供给了其他⼚商调⽤,结果他们调⽤后⼀直失败,接⼝进来了,打印的两⾏都为空。
把报⽂要了过来,重新配置了命名空间,还有调整两个参数的顺序(他们原来是反的),就正常了。
对⽅的⼯作⼈员说,这两个参数的顺序为什么⼀定要按照顺序,我也只是说不按照顺序就会有问题。但还是好奇,就打断点进去看了下cxf是怎么处理的。
cxf对soap协议解析参数的源码
可以看出,dubbo的ws服务协议也是委托给了cxf下的ServletController处理;项⽬中⽤到的cxf是cxf-api.2.6.1.jar,是在
f.Para(DepthXMLStreamReader, DataReader, MessageContentsList, Iterator, Message),这个⽅法处理了(我再在cxf的官⽹的api中DocLiteralInInterceptor没有getPara这个⽅法,2.6,2.4,3.1各个版本都没看到)
private void getPara(DepthXMLStreamReader xmlReader,
DataReader<xmlstreamreader> dr,
MessageContentsList parameters,
Iterator<messagepartinfo> itr,
Message message) {
boolean hasNext = true;
while (itr.hasNext()) {
MessagePartInfo part = ();
if (hasNext) {
hasNext = NextElement(xmlReader);
}
Object obj = null;
if (hasNext) {
QName rname = Name();
while (part != null
&& !rname.ConcreteName())) {
if (XmlSchema() instanceof XmlSchemaElement) {
//TODO - should check minOccurs=0 and throw validation exception
//thing if the part needs to be here
parameters.put(part, null);
}
if (itr.hasNext()) {
part = ();
} else {
part = null;
}
}
if (part == null) {
return;
}
if (rname.ConcreteName())) {
obj = dr.read(part, xmlReader);
}
}
parameters.put(part, obj);
}
}
在这⾥,MessagePartInfo应该是从wsdl中解析出来的,就是定义好的参数,Qname rname是真实传过来的xml中读取出来的,这个时候,part指向的是arg0,但是while 第⼀次循环的时候,rname传过来的参数中的第⼀个值(因为顺序是反的,为arg1),rname不等于ConcreateName(),就直接把parameter.put(part, null)了;接着往下⾛,part取了arg1,这个时候rname也指向arg1,就把arg1的值read过来为obj,再放⼊parameter中;itr的两个元素已经循环完了,跳出while循环,真实过来过来的soap协议中的arg0的参数就被跳过去了。
<soapenv:envelope xmlns:soapenv="/soap/envelope/" xmlns:ser="">
<soapenv:header>
<soapenv:header>
<soapenv:body>
<ser:syncunitework>
<ser:arg1>arg1</ser:arg1>
<ser:arg0>arg0</ser:arg0>
</ser:syncunitework>
</soapenv:body>
</soapenv:header></soapenv:header></soapenv:envelope>
附上wsdl⽂件的关于接⼝⼊参的部分
<xsd:element name="sync" type="tns:sync">
<xsd:complextype name="sync">
<xsd:sequence>
<xsd:element minoccurs="0" name="arg0" type="xsd:string">
<xsd:element minoccurs="0" name="arg1" type="xsd:string">
</xsd:element></xsd:element></xsd:sequence>
</xsd:complextype>
顺序的规范
cxf 下⾯截取⼀下官⽅⽂档的描述
Apache CXF™ is an open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.
XML Schema
An XML Schema describes the structure of an XML document.
The XML Schema language is also referred to as XML Schema Definition (XSD).
XML Schema sequence Element
The sequence element specifies that the child elements must appear in a sequence. Each child element can occur from 0 to any number of times.
XML WSDL
WSDL stands for Web Services Description Language
WSDL is used to describe web services
WSDL is written in XML
WSDL is a W3C recommendation from 26. June 2007
总结
wsdl是webservice的描述,也是⽤到了xsd来约束,其中参数(即sync⽅法)的两个参数就是有顺序的,所以归根到底,是xsd的规范的约束。这⼀点也从问答⽹站stackoverflow的提问得到了印证。
<xsd:all> specifies that the child elements can appear in any order.
<xsd:sequence> specifies child elements can only appear in the order mentioned.
>调用webservice服务
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论