一:开发背景
webservice通讯时经常会遇到命名空间不符的情况,比如全系统统一使用一套规范,但是某些系统提供的服务命名不是很统一,由其提供的wsdl文件生成的客户端的命名空间也随之不统一,因此就需要调用方开发客户端时修改命名空间。
1:全系统统一使用的命名空间
?
?
2:其他系统提供的webservice服务
?
?
由以上两图可见,其他系统提供的服务文件的命名空间少了一层【请求类的命名空间】,而且属性的命名空间也不标准
在 http://blog.csdn.net/tangmingxin0529/article/details/79310256 这篇文章中有客户端代码的生成过程介绍。
二:客户端命名空间修改
1:请求类的命名空间修改
Stub类中有webservice服务的调用方法,其参数类的类定义处既有请求类的命名空间设置。
public static class ReqS00000000001 implements
org.apache.axis2.databinding.ADBBean{
public static final javax.xml.namespace.QName MY_QNAME=
new javax.xml.namespace.QName(
"http://127.0.0.1:8888/UPB","ReqS00000000001","ns1")
}
从最初的客户端代码可见,请求类的命名空间为UPB,这里需要先将其修改为
public static class ReqS00000000001 implements
org.apache.axis2.databinding.ADBBean{
public static final javax.xml.namespace.QName MY_QNAME=
new javax.xml.namespace.QName(
"http://127.0.0.1:8888/UPB/wsdl","ReqS00000000001","tns")
}
这样请求类的命名空间暂时变成了wsdl,并且命名空间会由两个变成3个
2:返回类的命名空间修改
最初的返回类命名空间也为UPB,这样在调用服务返回是会报Unexpected subelement RspS00000000001异常
while(!reader.isEndElement()){
if(reader.isStartElement()){
if(reader.isStartElement()&& new javax.xml.namespace.QName(
"http://127.0.0.1:8888/UPB","RspS00000000001").equals(reader.getName())){
object.setRspS00000000001(RspS00000000001Type.Factory.parse(reader));}
返回类的命名空间修改并不在其类的定义处修改,而是在
public static class Factory{
public static RspS00000000001 parse(javax.xml.stream.XMLStreamReader reader){
这个方法中进行修改的,Factory会进行命名空间的校验及字段的校验
public static class Factory{
public static RspS00000000001 parse(javax.xml.stream.XMLStreamReader reader){
......
while(!reader.isEndElement()){
if(reader.isStartElement()){
if(reader.isStartElement()&& new javax.xml.namespace.QName(
"http://127.0.0.1:8888/UPB/wsdl","RspS00000000001").equals(reader.getName())){
object.setRspS00000000001(RspS00000000001Type.Factory.parse(reader));}
......
3:截止目前,请求类和返回类的命名空间都已经进行了修改,但是这只能在原有的两层命名空间上加上第三个命名空间,并不是最终的统一样式
private org.apache.axiom.soap.SOAPEnvelope toEnvelope(
org.apache.axiom.soap.SOAPFactory factory,
.......ReqS00000000001 param,
boolean optimizeContent) throws org.apache.axis2.AxisFault{
try{
org.apache.axiom.soap.SOAPEnvelope emptyEnvelope=factory.getDefaultEnvelope();
//-------------------手动添加---------------------
emptyEnvelope.declareNamespace(
"http://127.0.0.1:8888/UPB/wsdl","tns";
emptyEnvelope.declareNamespace(
"http://127.0.0.1:8888/UPB","s"
);
//-------------------手动添加---------------------
添加这几行代码之后,所以的命名空间为wsdl都是转换成tns,所以属性的命名空间upb都会转换成s。现在即为全系统统一的标准soap报文格式。