首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

axis1.4与应用集成(续),解决Arraylist<>的有关问题

2012-09-21 
axis1.4与应用集成(续),解决Arraylist...的问题前言:上一篇介绍了手动写客户端的axis1.4的应用实例,那个

axis1.4与应用集成(续),解决Arraylist<...>的问题

前言:上一篇介绍了手动写客户端的axis1.4的应用实例,那个例子是没有问题的,但细心的同志们会发现,生成的wsdl文件是有问题的,比较刺眼的关键字是 ArrayOf_xsd_anyType 这个表明根本不认识list,而且list里放入的对象也没有在该WSDL文件里描述,这样带来的问题就是如果只根据WSDL文件来生成客户端,比如用axis1.4的wsdl2java命令

D:\develop_tools\axis-1_4\lib>java -cp .;axis.jar;jaxrpc.jar;saaj.jar;wsdl4j-1.5.1.jar;commons-discovery-0.2.jar;commons-logging-1.0.4.jar;log4j-1.2.8
.jar org.apache.axis.wsdl.WSDL2Java http://localhost:8091/bjchannel/services/EsopWBService1?wsdl

示例如上,的话,生成的类明显少了一个,就是list里放入的MenuNodeInterface类,这个在WSDL里根本没有体现

而且奇怪的是假如用list的话,如果添加了list的add方法,比如public void addMenuNodeInterface(MenuNodeInterface obj){list.add(obj);}(伪代码)的话,在生成的WSDL里就会有MenuNodeInterface的体现,但集合还是没有。这个看看AXIS的源码就明白了.

?

关于这个问题,首先参看axis1.4的官方文档user-guide.pdf,这个我在附件里上传上来,查看里面的

1.6.3里的1.6.3.1项,说的很清楚,由于LIST这些集合类和其他语言不通用,所以需要当作CUSTOM类自己做映射在service-config.xml里,那就麻烦了,加入实现类是ArrayList的话,还需要把相应的jar包加进来做映射;

所以后面有一句关键的:The most reliable way to send aggregate objects is to use arrays

有感觉没,对了,就是用[]数组来代替接口里需要的属性和返回值。

废话不说了,上代码

1:返回结果类

package com.asiainfo.boss.channel.channelservices;import java.io.Serializable;public class EsopResult1 implements Serializable{/** * seriaId */private static final long serialVersionUID = -1922115715606536898L;/** * 0:成功   1:失败 */private Short returnCode=1;//一般不用语言特定的集合类,统一用数组代替//private List<MenuNodeInterface> sysMenuNodeList;private MenuNodeInterface[] sysMenuNodeList;private String errorMsg;//public EsopResult1(){//sysMenuNodeList=new ArrayList<MenuNodeInterface>();//sysMenuNodeList.add(new MenuNodeInterface());////}//public EsopResult1(){sysMenuNodeList=new MenuNodeInterface[]{new MenuNodeInterface()};}public Short getReturnCode() {return returnCode;}public void setReturnCode(Short returnCode) {this.returnCode = returnCode;}//public List<MenuNodeInterface> getSysMenuNodeList() {//return sysMenuNodeList;//}////public void setSysMenuNodeList(List<MenuNodeInterface> sysMenuNodeList) {//this.sysMenuNodeList = sysMenuNodeList;//}//如果用list的话,还不光需要有list的set和get方法,还必须有addlist的方法,这样生成的wsdl才能包含list里的内容对象//不过即使这样,还是会有问题,总之用数组代替就对了public MenuNodeInterface[] getSysMenuNodeList() {return sysMenuNodeList;}public void setSysMenuNodeList(MenuNodeInterface[] sysMenuNodeList) {this.sysMenuNodeList = sysMenuNodeList;}public String getErrorMsg() {return errorMsg;}public void setErrorMsg(String errorMsg) {this.errorMsg = errorMsg;}}

?

?

2:手动客户端调用测试类

package com.asiainfo.boss.channel.channelservices;import javax.xml.namespace.QName;import javax.xml.rpc.ParameterMode;import org.apache.axis.client.Call;import org.apache.axis.client.Service;import org.apache.axis.encoding.XMLType;import org.apache.axis.encoding.ser.BeanDeserializerFactory;import org.apache.axis.encoding.ser.BeanSerializerFactory;public class EsopWBClient1 {public static void main(String...args){getResult();}public static void getResult(){try {               String endpoint = "http://localhost:8091/bjchannel/services/EsopWBService1";               Long opId = new Long(1009);               Long orgId = new Long(1000);                              Service service = new Service();               Call call = (Call) service.createCall();               QName qn = new QName("urn:EsopWBService1","EsopResult1");             QName qn1 = new QName("urn:EsopWBService1","MenuNodeInterface");             //注册 bean               call.registerTypeMapping(EsopResult1.class, qn,                        new BeanSerializerFactory(EsopResult1.class, qn),                        new BeanDeserializerFactory(EsopResult1.class, qn));              call.registerTypeMapping(MenuNodeInterface.class, qn1,                        new BeanSerializerFactory(MenuNodeInterface.class, qn1),                        new BeanDeserializerFactory(MenuNodeInterface.class, qn1));                call.setTargetEndpointAddress(new java.net.URL(endpoint));               call.setOperationName(new QName("EsopWBService1","qryMenuNodeInfoList"));//            Object[] sss=new Object[2];//            sss[0]=i1;//            sss[1]=i2;            //EsopResult1 ret = (EsopResult1) call.invoke("qryMenuNodeInfoList",new Object[]{i1,i2});            //以下两个参数必须加,不然后报数组越界异常,因为源码里的operation为的params需要手动设置            //invoke只负责往里传递数,不管原来方法参数的初始化,以下两句表明调用的方法需要初始化两个参数            call.addParameter("opId", XMLType.XSD_LONG, ParameterMode.IN);            call.addParameter("orgId", XMLType.XSD_LONG, ParameterMode.IN);            EsopResult1 ret = (EsopResult1) call.invoke(new Object[]{opId,orgId});                          System.out.println("the operation result following:");               System.out.println("ErrorMsg = " + ret.getErrorMsg());               System.out.println("ReturnCode = " + ret.getReturnCode());   //            这是用list做属性的客户端写法,没有问题,问题只会出现在wsdl的生成上,因为手写客户端在前面手动//            注册了list里的内容对象,所以会取到,但是生成的wsdl里是没有的,所以依赖wsdl的wsdl2java生成的//            客户端程序就有问题了。//            System.out.println("MenuNodeList().size() = " + ret.getSysMenuNodeList().size());//            List<MenuNodeInterface> reList=ret.getSysMenuNodeList();                        //以下是数组形式的调用            System.out.println("MenuNodeList().length = " + ret.getSysMenuNodeList().length);            MenuNodeInterface[] reList=ret.getSysMenuNodeList();                        for(MenuNodeInterface mni : reList){            System.out.println("菜单名称:"+mni.getS_Caption());            }                     } catch (Exception e) {               e.printStackTrace();           }       }   }

?

?

?

其他的类参照上一篇文章,没有修改

配置文件也没有任何变化

?

OK,附件是我用wsdl2java生成的客户端类,和自己写的测试调用类,打包上传了,老规矩,代码里的报名和有些配置名字自己修改,我就不去除了

?

参考文章

http://forums.sun.com/thread.jspa?threadID=5405862

http://www.javalobby.org/java/forums/t84343.html

?

1 楼 KimShen 2010-10-20   WebService使用经验告诉我们,你定义的对象越复杂你维护的成本也巨大.尤其是List,Map,Set这种特殊的数据结构.你会死的很难看

热点排行