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

 

你可能感兴趣的:(apache,log4j,xml,bean,webservice)