读书人

axis1.4 施用笔记

发布时间: 2012-10-31 14:37:32 作者: rapoo

axis1.4 使用笔记

引自http://ytsho.spaces.live.com/blog/cns!A3DC45268A88C509!215.entry

?

注意,axis安装包中少几个jar包,需要单独下载:

必需组件:
http://java.sun.com/products/javabeans/glasgow/jaf.html
可选组件:
http://java.sun.com/products/javamail/
http://xml.apache.org/security/
分别下载:jaf-1_1-fr.zip,javamail-1_4.zip,xml-security-bin-1_2_1.zip包,然后把jaf-1_1-fr.zip里的Activation.jar,javamail-1_4.zip里的mail.jar,xml-security-bin-1_2_1.zip里的xmlsec-1.2.1.jar,xalan.jar都放到你的axis应用的WEB-INF/lib下然后在校验Axis,看到页面提示全部安装成功。

?

2.3安装到Eclipse

如果你在项目中要用到axis,则你的项目应该包含axis的一些包。这里主要是在客户端编程中要用到。

?????????首先创建一个WEB项目,名称随便,??? 再把axis安装目录中的lib目录下的所有jar包都导入该项目,这样eclipse中的axis就安装好了,开发webservice就只要在这个项目里开发就行了,如果你在其他项目里开发的话,只要把jar都导过去就行了,简单吧!

安装就讲这么多。。基本上就没什么问题了。

?

3.开发web service

axis中发布服务主要有两种方式

即时发布JWS 定制发布WSDD

即时发布虽然很方便,但限制过大,一般不会用。最大限制就是不支持带包的类,这是初学者容易犯的一个错。具体就不讲了,下面通过讲解如何把我们项目的一个算法发布成web service来详细讲解定制发布。

?

    <deployment?xmlns="http://xml.apache.org/axis/wsdd/"?? ????xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> ?? ????<service?name="SN_AdvanceSearch"?provider="java:RPC"> ?? ????????<parameter?name="className"?value="cn.edu.tju.ikse.sn.advancedSearch.SemanticQueryOperate"/> ?? ????????<parameter?name="allowedMethods"?value="getAdvancedSearchList"/> ?? ????????<beanMapping?qname="myNSD:AdvanceSearch"?????xmlns:myNSD="urn:BeanService"?? ????????????languageSpecificType="java:cn.edu.tju.ikse.sn.advancedSearch.AdvanceSearch"/> ?? ????????<beanMapping?qname="myNSD:Serviceinfo"??xmlns:myNSD="urn:BeanService"?? ????????????languageSpecificType="java:cn.edu.tju.ikse.sn.hibernate.Serviceinfo"/> ?? ????</service> ?? </deployment>??
<deployment xmlns="http://xml.apache.org/axis/wsdd/"xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"><service name="SN_AdvanceSearch" provider="java:RPC"><parameter name="className" value="cn.edu.tju.ikse.sn.advancedSearch.SemanticQueryOperate"/><parameter name="allowedMethods" value="getAdvancedSearchList"/><beanMapping qname="myNSD:AdvanceSearch" xmlns:myNSD="urn:BeanService"languageSpecificType="java:cn.edu.tju.ikse.sn.advancedSearch.AdvanceSearch"/><beanMapping qname="myNSD:Serviceinfo"  xmlns:myNSD="urn:BeanService"languageSpecificType="java:cn.edu.tju.ikse.sn.hibernate.Serviceinfo"/></service></deployment>

?

第三行,就是给这个服务取一个名字,这样别人就能按照名字来获取服务了。这里我们取名为SN_AdvanceSearch

第四行,指定这个服务代表的具体类,要包括包名

第五行,指定这个服务允许别人访问的方法名,这里只让访问getAdvancedSearchList,如果改成*号,则这个类所有??? public的方法都能被客户端调用。

第六行,是重点,完成类型的映射,因为用到了用户自己定义的两个javaBean,因此需要映射。格式如第六行和第七行所示,qname="myNSD:AdvanceSearch" ,注意红色部分应该和你的javabean名一致,languageSpecificType也得注意下格式,java:表示这是一个java语言写的类,后面再加上具体的类。其它自定义类完全可以参考这个写法。

写完后我把这文档放在了D:\JavaTools\Tomcat 6.0\webapps\axis\WEB-INF目录下,下一步是如何把这个wsdd文档加到axis自己的配制文档server-config.wsdd里。

编写完配置发布文件之后,cmd打开windows的控制台,进入:%TOMCAT_HOME%\webapps\axis\WEB-INF 目录下键入如下命令:
java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient snAdvancedSearch.wsdd

之后控制台返回Processing file deploy.wsdd 和Done processing 这两段话即说明发布成功。(注意tomcat得开着)。

当然了为了操作方便也可以写个批处理文件wsdd.bat:

?

Java代码 axis1.4 施用笔记
    set?Axis_Lib=D:\JavaTools\axis-1_4\lib???? ?? set?Java_Cmd=java?-Djava.ext.dirs=%Axis_Lib%???? ?? set?Axis_Servlet=http://localhost:8080/axis/servlet/AxisServlet???? ?? %Java_Cmd%?org.apache.axis.client.AdminClient?-l%Axis_Servlet%?snAdvancedSearch.wsdd? ?? pause??
set Axis_Lib=D:\JavaTools\axis-1_4\lib    set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib%    set Axis_Servlet=http://localhost:8080/axis/servlet/AxisServlet    %Java_Cmd% org.apache.axis.client.AdminClient -l%Axis_Servlet% snAdvancedSearch.wsdd pause

?

最终效果都是一样的,此时在server-config.wsdd会有如下代码段:

Java代码 axis1.4 施用笔记
    <service?name="SN_AdvanceSearch"?provider="java:RPC"> ?? ?<parameter?name="allowedMethods"?value="getAdvancedSearchList"/> ?? ?<parameter?name="className"?value="cn.edu.tju.ikse.sn.advancedSearch.SemanticQueryOperate"/> ?? ?<beanMapping?languageSpecificType="java:cn.edu.tju.ikse.sn.advancedSearch.AdvanceSearch"?qname="ns2:AdvanceSearch"?xmlns:ns2="urn:BeanService"/> ?? ?<beanMapping?languageSpecificType="java:cn.edu.tju.ikse.sn.hibernate.Serviceinfo"?qname="ns3:Serviceinfo"?xmlns:ns3="urn:BeanService"/> ?? </service>??
 <service name="SN_AdvanceSearch" provider="java:RPC">  <parameter name="allowedMethods" value="getAdvancedSearchList"/>  <parameter name="className" value="cn.edu.tju.ikse.sn.advancedSearch.SemanticQueryOperate"/>  <beanMapping languageSpecificType="java:cn.edu.tju.ikse.sn.advancedSearch.AdvanceSearch" qname="ns2:AdvanceSearch" xmlns:ns2="urn:BeanService"/>  <beanMapping languageSpecificType="java:cn.edu.tju.ikse.sn.hibernate.Serviceinfo" qname="ns3:Serviceinfo" xmlns:ns3="urn:BeanService"/> </service>

?

和原来的wsdd文件差不多。对着看就明白了。。如果熟悉了可以直接在server-config.wsdd中加上上面这段代码就行了。此时访问http://localhost:8080/axis/servlet/AxisServlet就能看到你发布的服务了,可以查看对应的wsdl文档。

服务端任务基本就完成了。。最后别忘记把服务端对应的class文件拷到D:\JavaTools\Tomcat 6.0\webapps\axis\WEB-INF\classes目录下。由于我们这是一个web工程也是发布在Tomcat中,我是直接把发布的工程中的WEB-INF下的classes文件夹全部拷到axis下对应目录。(似乎还要把lib下的jar包也拷到axis对应的lib目录下)

?

3.2 客户端的开发

客户端就是写程序怎么调用这个web服务了。留到下一节讲吧。。写得太多了。

?

    set?Axis_Lib=D:\JavaTools\axis-1_4\lib???? ?? set?Java_Cmd=java?-Djava.ext.dirs=%Axis_Lib% ?? %Java_Cmd%?org.apache.axis.wsdl.Java2WSDL?? ?? ???-osn_advanceSearch.wsdl? ?? ???-lhttp://localhost:8080/axis/services/SN_AdvanceSearch? ?? ???-n"urn:BeanService"? ?? ???-p"cn.edu.tju.ikse.sn.advancedSearch"?"urn:BeanService"????cn.edu.tju.ikse.sn.advancedSearch.SemanticQueryOperate ?? pause??
set Axis_Lib=D:\JavaTools\axis-1_4\lib    set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib%%Java_Cmd% org.apache.axis.wsdl.Java2WSDL     -osn_advanceSearch.wsdl    -lhttp://localhost:8080/axis/services/SN_AdvanceSearch    -n"urn:BeanService"    -p"cn.edu.tju.ikse.sn.advancedSearch" "urn:BeanService"    cn.edu.tju.ikse.sn.advancedSearch.SemanticQueryOperatepause

?-O:指定生成的wsdl文件名

-l:指定生成服务的访问地址

-n:指定名字空间

-p:指定名字空间与包的对应关系

最后指定具体的java类即你要发布的类。

这个工具最适用的环境:服务端根据业务需要写完暴露的接口后就可以用这个工具生成wsdl文件了,而不必要自己动手写wsdl文件,理论上就可以根据这个wsdl文档发布这个服务了。客户端一般是不会调用这个方法的。。因为客户端一般拿不到类文件~~放在这里讲是告诉大家有这么一个好用的工具。

?

3.2.2 WSDL2java

?

????? 这个工具是根据wsdl文件生成对应的调用类。这个在客户端是很有用的。当你只能从服务端拿到wsdl文档而不能拿到任何的代码或类文件时就得靠它了!这个工具会根据wsdl文档的定义生成一些对应的类,如复杂类型定义就会生成对应的javaBean..

编辑一个WSDL2Java.bat,Axis_Lib为axis.jar路径。内容如下:

Java代码 axis1.4 施用笔记
    set?Axis_Lib=D:\JavaTools\axis-1_4\lib???? ?? set?Java_Cmd=java?-Djava.ext.dirs=%Axis_Lib%???? ?? set?Output_Path=D:\JavaTools\eclipse3.2\workplace\axisTest\src??? ?? set?Package=cn.edu.tju.ikse.sn.advancedSearch?? ?? %Java_Cmd%?org.apache.axis.wsdl.WSDL2Java?-o%Output_Path%?-p%Package%?http://localhost:8080/axis/services/SN_AdvanceSearch?wsdl ?? pause??
set Axis_Lib=D:\JavaTools\axis-1_4\lib    set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib%    set Output_Path=D:\JavaTools\eclipse3.2\workplace\axisTest\src   set Package=cn.edu.tju.ikse.sn.advancedSearch  %Java_Cmd% org.apache.axis.wsdl.WSDL2Java -o%Output_Path% -p%Package% http://localhost:8080/axis/services/SN_AdvanceSearch?wsdlpause

?

应该不用解释吧。。很容易看懂,主要是调用WSDL2Java 根据服务端发布的服务生成对应的接口。

????? 倒数第二行是应用wsdl2java这个工具,最后是指定wsdl文件的位置,这个文件可以是本地的wsdl文件,也可以是网络上的wsdl文件。

??????再解释下第三行,第三行是我客户端项目的源文件路径,这样通过工具生成的代码直接加到项目里了,省些复制粘贴的麻烦。刷新下项目,在包cn.edu.tju.ikse.sn.advancedSearch? 下就能看到六个java文件:

AdvanceSearch.java//自定义类型,wsdl中的复杂类型定义都会生成对应的javaBean

Serviceinfo.java//这也是一个自定义类型。。一开始没生成这们。。后面的注意事项里会讲到原因。

SemanticQueryOperate.java,//这是一个接口,描述服务器端能干什么。对应于wsdl中的wsdl:portType

SemanticQueryOperateService.java,//这是一个接口.相当于wsdl中的wsdl:service结点

SemanticQueryOperateServiceLocator.java,实现了SemanticQueryOperateService接口.
这个类的作用是直接与服务器端通信,建立与服务器端的连接,实例化stub.然后客户端就可以通过stub与服务器通信了.

SN_AdvanceSearchSoapBindingStub.java.这个类实现了SemanticQueryOperate接口,作为服务器在客户端的存根,也就是一个stub.在客户端,对服务器的所有调用,本质上都是对stub的调用

?

3.2.3 客户端编码

?

客户端编码主要有两种方式:

第一种方法是利用wsdl2java生成的stub类来进行调用,这种方式的好处是调用简单,不需要服务端的支持 第二种方法是不通过stub类来进行调用,这种方式完全由用户控制调用的所有参数。

实际使用中应该多用第一种方式,代码写起来简单。下面分别进行讲述。

先讲第二种方式吧,看代码:

Java代码 axis1.4 施用笔记
    public?static?void?testadvancesearch()?{ ?? ????????//设置服务连接路径 ?? ????????String?url?=?"http://127.0.0.1:8989/axis/services/SN_AdvanceSearch"; ?? ????????//下面是构建服务的输入参数 ?? ????????AdvanceSearch?search?=?new?AdvanceSearch(); ?? ????????search.setDomain("Biology"); ?? ????????search.setServiceName("getENTRYbyScientificName");//getENTRYbyScientificName ?? ?? ????????try?{ ?? ????????????Service?service?=?new?Service();//构建一个服务 ?? ????????????Call?call?=?(Call)?service.createCall(); ?? ????????????//注册javaBean?注意和server-config.wsdd保持一致 ?? ????????????QName?qn?=?new?QName("urn:BeanService",?"Serviceinfo"); ?? ????????????call.registerTypeMapping(Serviceinfo.class,?qn, ?? ????????????????????new?org.apache.axis.encoding.ser.BeanSerializerFactory( ?? ????????????????????????????Serviceinfo.class,?qn), ?? ????????????????????new?org.apache.axis.encoding.ser.BeanDeserializerFactory( ?? ????????????????????????????Serviceinfo.class,?qn)); ?? ????????????//创建调用*/???????????? ?? ????????????call.setTargetEndpointAddress(new?java.net.URL(url)); ?? ????????????//调用服务器的方法 ?? ????????????call.setOperationName(new?QName("SemanticQueryOperate", ?? ????????????????????"getAdvancedSearchArrayList")); ?? ????????????//设定返回类型 ?? ????????????//call.setReturnClass(ArrayList.class);?//call.invoke(new?Object[]{"haha"}); ?? ????????????//设定传入参数 ?? ????????????//call.addParameter("userpara",?XMLType.XSD_ANYTYPE,?ParameterMode.IN);????????? ?? ????????????//System.out.println(new?Object[]{userPar}); ?? ????????????//接受结果 ?? ????????????Object[]?result?=?(Object[])?call.invoke(new?Object[]?{?search?}); ?? ????????????if?(result?!=?null?&&?result.length?>?0)?{ ?? ????????????????for?(int?i?=?0;?i?<?result.length;?i++)?{ ?? ????????????????????Serviceinfo?serviceinfo?=?(Serviceinfo)?result[i]; ?? ????????????????????System.out.println(serviceinfo.getCatagoryName() ?? ????????????????????????????+?serviceinfo.getAffiliation()); ?? ????????????????} ?? ????????????} ?? ?? ????????}?catch?(ServiceException?e)?{ ?? ????????????e.printStackTrace(); ?? ????????}?catch?(MalformedURLException?e)?{ ?? ????????????e.printStackTrace(); ?? ????????}?catch?(RemoteException?e)?{ ?? ????????????e.printStackTrace(); ?? ????????} ?? ????}??
public static void testadvancesearch() {//设置服务连接路径String url = "http://127.0.0.1:8989/axis/services/SN_AdvanceSearch";//下面是构建服务的输入参数AdvanceSearch search = new AdvanceSearch();search.setDomain("Biology");search.setServiceName("getENTRYbyScientificName");//getENTRYbyScientificNametry {Service service = new Service();//构建一个服务Call call = (Call) service.createCall();//注册javaBean 注意和server-config.wsdd保持一致QName qn = new QName("urn:BeanService", "Serviceinfo");call.registerTypeMapping(Serviceinfo.class, qn,new org.apache.axis.encoding.ser.BeanSerializerFactory(Serviceinfo.class, qn),new org.apache.axis.encoding.ser.BeanDeserializerFactory(Serviceinfo.class, qn));//创建调用*/call.setTargetEndpointAddress(new java.net.URL(url));//调用服务器的方法call.setOperationName(new QName("SemanticQueryOperate","getAdvancedSearchArrayList"));//设定返回类型//call.setReturnClass(ArrayList.class);//call.invoke(new Object[]{"haha"});//设定传入参数//call.addParameter("userpara", XMLType.XSD_ANYTYPE, ParameterMode.IN);//System.out.println(new Object[]{userPar});//接受结果Object[] result = (Object[]) call.invoke(new Object[] { search });if (result != null && result.length > 0) {for (int i = 0; i < result.length; i++) {Serviceinfo serviceinfo = (Serviceinfo) result[i];System.out.println(serviceinfo.getCatagoryName()+ serviceinfo.getAffiliation());}}} catch (ServiceException e) {e.printStackTrace();} catch (MalformedURLException e) {e.printStackTrace();} catch (RemoteException e) {e.printStackTrace();}}

?

?上面代码已经注释得差不多了。就不具体解释了。

再看第一种方式的调用:

Java代码 axis1.4 施用笔记
    public?static?void?testadvancesearchstub()?throws?ServiceException?{ ?? ????????//?创建你要对话的服务 ?? ????????SemanticQueryOperateService?service?=?new?SemanticQueryOperateServiceLocator(); ?? ???????? ?? ????????SemanticQueryOperate?client?=?service.getSN_AdvanceSearch(); ?? ????????//构建服务的输入参数 ?? ????????AdvanceSearch?search?=?new?AdvanceSearch(); ?? ????????search.setDomain("Biology"); ?? ????????search.setServiceName("dna");//getENTRYbyScientificName????? ?? ????????Object[]?retValue?=?null; ?? ????????try?{ ?? ????????????//调用服务,获得结果 ?? ????????????retValue?=?client.getAdvancedSearchArrayList(search); ?? ????????????System.out.println("start"); ?? ????????????if?(retValue?!=?null?&&?retValue.length?>?0)?{ ?? ????????????????for?(int?i?=?0;?i?<?retValue.length;?i++)?{ ?? ????????????????????Serviceinfo?serviceinfo?=?(Serviceinfo)?retValue[i]; ?? ????????????????????System.out.println(serviceinfo.getCatagoryName() ?? ????????????????????????????+?serviceinfo.getAffiliation()); ?? ????????????????} ?? ????????????} ?? ????????}?catch?(RemoteException?e)?{ ?? ????????????//?TODO?Auto-generated?catch?block ?? ????????????e.printStackTrace(); ?? ????????} ?? ????}??
public static void testadvancesearchstub() throws ServiceException {// 创建你要对话的服务SemanticQueryOperateService service = new SemanticQueryOperateServiceLocator();SemanticQueryOperate client = service.getSN_AdvanceSearch();//构建服务的输入参数AdvanceSearch search = new AdvanceSearch();search.setDomain("Biology");search.setServiceName("dna");//getENTRYbyScientificNameObject[] retValue = null;try {//调用服务,获得结果retValue = client.getAdvancedSearchArrayList(search);System.out.println("start");if (retValue != null && retValue.length > 0) {for (int i = 0; i < retValue.length; i++) {Serviceinfo serviceinfo = (Serviceinfo) retValue[i];System.out.println(serviceinfo.getCatagoryName()+ serviceinfo.getAffiliation());}}} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}

?通过代码可以看出第一种方式比较简单,把配置和调用分开了。也不具体讲了,基本上看着代码就知道是什么意思。下一小节再讲这种方式的好处和需要注意的地方。

?

    QName?qn?=?new?QName("urn:BeanService",?"AbstractServiceinfo"); ?? _call.registerTypeMapping(AbstractServiceinfo.class,?qn, ?? ????????????????new?org.apache.axis.encoding.ser.BeanSerializerFactory( ?? ????????????????????????AbstractServiceinfo.class,?qn), ?? ????????????????new?org.apache.axis.encoding.ser.BeanDeserializerFactory( ?? ????????????????????????AbstractServiceinfo.class,?qn));??
QName qn = new QName("urn:BeanService", "AbstractServiceinfo");_call.registerTypeMapping(AbstractServiceinfo.class, qn,new org.apache.axis.encoding.ser.BeanSerializerFactory(AbstractServiceinfo.class, qn),new org.apache.axis.encoding.ser.BeanDeserializerFactory(AbstractServiceinfo.class, qn));

?格式基本如上所示。

要记住当你的方法需要传入自定义类型的参数或返回自定义类型时,一定要在wsdd文档中注册,在客户端编程时也要注册。?

客户端采取第二种方式时的映射注册可以看3.2.3的代码,采取第一种方式时也要注册,需要找到服务对应的存根类SN_AdvanceSearchSoapBindingStub,在这个类里有各个方法对应的调用配置,找到需要注册的方法,加上上面的映射就行了。格式都是一样的!

?

2.当返回类型类似于ArrayList<Serviceinfo>时

对于这样的返回类型,axis都会把返回值转成Object[],别想着直接把结果转成ArrayList,有时会出问题

下面是一个典型的用法:方法的返回值是ArrayList<Serviceinfo>,用下面的方法遍历就行了。

Java代码 axis1.4 施用笔记
    Object[]?result?=?(Object[])?call.invoke(new?Object[]?{?search?}); ?? ????????????if?(result?!=?null?&&?result.length?>?0)?{ ?? ????????????????for?(int?i?=?0;?i?<?result.length;?i++)?{ ?? ????????????????????Serviceinfo?serviceinfo?=?(Serviceinfo)?result[i]; ?? ????????????????????System.out.println(serviceinfo.getCatagoryName() ?? ????????????????????????????+?serviceinfo.getAffiliation()); ?? ????????????????} ?? ????????????}??
Object[] result = (Object[]) call.invoke(new Object[] { search });if (result != null && result.length > 0) {for (int i = 0; i < result.length; i++) {Serviceinfo serviceinfo = (Serviceinfo) result[i];System.out.println(serviceinfo.getCatagoryName()+ serviceinfo.getAffiliation());}}

?对于java中的set也一样,都会转成Object[],如下面的方法:

Map<Integer, Set<Integer>> composition(UserParameter userparameter)得到返回值时就应该这样处理:

Java代码 axis1.4 施用笔记
    Map<Integer,?Object[]>?result=(Map)?call.invoke(new?Object[]{userPar}); ?? ???????????????? ?? ????????????for?(Iterator<Integer>?iter?=?result.keySet().iterator();?iter ?? ????????????????????.hasNext();)?{ ?? ????????????????Integer?key?=?iter.next(); ?? ????????????????Object[]?obj?=?result.get(key); ?? ????????????????if(obj?!=?null?&&?obj.length?>?0)?{? ?? ??????????????????????for(int?i?=?0;?i?<?obj.length;?i?++)?{? ?? ??????????????????????????Integer?serviceinfo?=?(Integer)?obj[i];? ?? ????????????????????????System.out.println(serviceinfo);?????????????????? ?? ????????????????????????}? ?? ????????????????}?????????
Map<Integer, Object[]> result=(Map) call.invoke(new Object[]{userPar});for (Iterator<Integer> iter = result.keySet().iterator(); iter.hasNext();) {Integer key = iter.next();Object[] obj = result.get(key);if(obj != null && obj.length > 0) {   for(int i = 0; i < obj.length; i ++) {   Integer serviceinfo = (Integer) obj[i];     System.out.println(serviceinfo);  } }

?注意对应于Set<Integer>的返回值是Object[]类型,通过循环来遍历,如果直接转型就会出现异常。

?

3.自定义类型一定要可以序列化,也就是要实现java.io.Serializable接口。如果你的方法准备发布成web服务最好把输入和输出都打包成javaBean,axis对javaBean的处理还是很自动的。

?

4.需要在服务端和客户端传递的javaBean当然在两端的工程里都应该有相似的代码,否则就会出现一方不能解析!如果客户端不能直接拿到javaBean的代码,可以借助wsdl2java生成的类中就应该会有对应的javaBean,直接拿过来用就行,当然,下一步采取哪种方式调用服务都是随意的。可见wsdl2java还是很有用的。

?

5.这点一定要看:血的教训

如果你的服务中返回值都是类似于List<Serviceinfo> getServiceinfoList(...)这样的集合类型,而没有一个类似于Serviceinfo getServiceinfo(..)这样的方法,发布成服务后,在对应的wsdl中就不会出现Serviceinfo的复杂类型对应的,也就是说你用wsdl2java是不能生成Serviceinfo对应的javaBean的。。调用的时候也就会出错。解决方法是在服务端可以加上一个什么也不做的public方法,如:

Java代码 axis1.4 施用笔记
    public?Serviceinfo?doNothing(){ ?? ????????Serviceinfo?info=new?Serviceinfo();? ?? ????????return?info; ?? ????}??
public Serviceinfo doNothing(){Serviceinfo info=new Serviceinfo();return info;}

?这样。wsdl文档中就会有对Serviceinfo的类型定义了。

这一步很重要啊。。当时在这徘徊了好久。。一定不要以为你在wsdd中有了beanMapping定义,就会在wsdl中出现对应类型定义,一定要在你的public方法的输入或返回值用到这个bean时才会在

读书人网 >软件架构设计

热点推荐