前面提到用cxf对.net进行调用时的命名空间的问题,由于当时时间比较紧,没细致地进行总结,这次对这个命名空间进行一个较为细致的总结一下.
有两种类型的命名空间,一是targetNamespace,另外一个是namespace,其实他们都是用来进行名称区分的.targetNamespace一般进行整个wsdl的名称区分,所以一般是在对应的接口中进行声明,比如:
@WebService(targetNamespace= "http://soap.interfaces.ssa.huawei.com")
publicinterface ICorePlat {}
而namespace一般用来对复杂的参数进行命名的,而复杂的参数在java中通常就是bean了,在bean的同一个目录可以建立一个叫package-info.java的类,在该类中通过注解的方式加入namespace,示例如下:
@javax.xml.bind.annotation.XmlSchema(namespace= "http://soap.interfaces.ssa.huawei.com", elementFormDefault =javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.feinno.gdp.promgr.ws.client;
那么如果有多个namespace怎么办呢?这就需要多建几个目录,分别加入package-info.java文件就行了.
这个package-info.java的多少与wsdl文档中的参数类型以及你所需要的调用的接口有关.
比如一个wsdl文档中有10个方法,你可能只需要一个方法,则如果这个方法有复杂的参数,则可能就只需要建立一个package-info.java就行了,而如果都是标准的参数的话,这个就可以不用建立了.
比如针对下面的sendSMS就去,从字面上也看出其是一个复杂的的参数类型,在第一个参数是的type=”s1:InfoHeader”,从这个可以看见,s1指向了另外的一个命名空间,所以需要对InfoHeader这个bean的目录中建立一个package-info.java这样的类文件,将命名空间进行写入即可.
<s:element name="sendSMS">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="in0" nillable="true" type="s1:InfoHeader" />
<s:element minOccurs="1" maxOccurs="1" name="in1" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="in2" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="in3" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="in4" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="in5" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="in6" nillable="true" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
上面s1所表示的命名空间可以在wsdl文档的声明中找到,示例如下:
xmlns:s1="http://bean.interfaces.iiss.huawei.com"
所以在InfoHeader目录对应的package-info.java中就可以将命名空间写为: http://bean.interfaces.iiss.huawei.com就可以了.
另外在你的接口处也需要一个package-info.java这样的类文件,里面将命名空间与接口对应的targetNamespace一样即可,比如我这里的接口类叫:
@WebService(targetNamespace = "http://soap.interfaces.ssa.huawei.com")
publicinterface ICorePlat{}
在这个ICorePlat接口类的同一个目录加入如下的package-info.java包,其里面的内容与targetNamespace一样,示例如下:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://soap.interfaces.ssa.huawei.com", elementFormDefault =javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.feinno.gdp.promgr.ws.client;
另外,本来jaxb中支持类直接用注解的方式添加命名空间,不过不知道为什么cxf却偏偏未用这种方式,而是通过package-info.java这种形式进行处理.不晓得算不算是他的一个不足啊!