本站首页    管理页面    写新日志    退出

The Neurotic Fishbowl

axis初步手记
狂飙的蜗牛 发表于 2006/6/21 13:51:05

这些天稍微玩了一下Axis,以前做WebServices都使用JBuilder,感觉做WebServices如此简单,现在自己手动做,原来也是如此简单。高兴之余写一个简单的初学手册,就算是学习成果吧。当然对Axis理解的还不很深,所以错误之处望指点。 Axis是一个实现WebService的Framework,Apache Web Services Project(http://ws.apache.org )的一个之项目,现在这个项目有很多之项目 Axis(http://ws.apache.org/axis/ )是其中一员,还有XML-RPC(这个也是我比较喜欢的东东J)。 现在Axis主要由两个版本一个是Axis一个是Axis2。两个好象有比较多的不同,我这里说的是Axis,过几天演技一下Axis2,然后再写一篇吧。 好了现在开始做个WebService 吧: 第一步当然是先去Axis主页下载一个来啦。下Release就行,最新的是1.2.1,source好象没有打包的只有CVS的。下来以后解压缩,主要有以下文件夹 Docs 顾名思义,这里放的是文档,其实Axis的文档作的很好,我就是按照它的User Guide一步步做下来的。 Lib 运行Axis时要用到的jar包,要完全正常运行还缺两个mail.jar activation.jar 这两个是javaMail包,到处都能弄到。 Samples Axis自带的例子包括很多种应用 Webapps  Axis是发布到Servlet Container中的,要把Axis集成到你的项目中,就把这个文件夹里的内容合并到你的项目中就行了。 还有一个xmls文件夹,放得是一些可能用到的xml例子。   第二步,建一个项目,Web项目,用Eclipse或者Idea都可以啊。如果你非要用记事本类的东西,我也不拦着你。 把Axis中的Webapps\axis文件夹下的东西统统Copy到你的Web文件夹下。其实有些东西是没用的,比如classes文件夹里的东西都可以去掉了,还有那几个jws文件也没有用。虽然axis最方便的发布WebServices的方法是把你的.java改成.jws的放到Web发布文件夹下的根目录下,但是这种方法没有什么适用价值。然后运行以下Tomcat(或者其他的Application Server)。然后浏览一下你的刚刚发布的这个项目,如果正常的话就可以看到Axis的默认画面,500)this.width=500'>这个页面不是必须的,在真正项目开发中可以把它去掉或换个名字。点击List连接进入已经发布的WebServices列表。500)this.width=500'>开始时应该只有AdminService和Version。后面两个就是我们在下面要做的WebServices。   第三步,如果上面的一切正常,就可以正式开始做WebServices了。首先做一个Services实现类。Calc.java有两个方法plus和subtract。这个Service所用到的数据类型都是基本类型。 public class Calc {    public int plus(int a,int b){        return a+b;    }    public int substract(int a,int b){        return a-b;    }} 然后在WEB-INF目录下加入一个server-config.wsdd。这是WebServices的发布描述文件,作用类似于web.xml。它有自己的格式,但是具体的标记是什么样子的,在Axis的文档中没有详细的一一列出,只是提到了常用的一些。在axis的源码中有一些wsdd的XSD文件,如果你用的是IDEA可以把这些XSD映射到uri,这样编辑器就有提示了。 下面这我们本文中的server-config.wsdd的样子: <?xml version="1.0" encoding="UTF-8"?><deployment name="defaultClientConfig"            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"            xmlns:handler="http://xml.apache.org/axis/wsdd/providers/handler" xmlns="http://xml.apache.org/axis/wsdd/">    <globalConfiguration name="defaultClientConfig">        <requestFlow name="RequestFlow1">            <handler name="Handler1" type="java:org.apache.axis.handlers.JWSHandler">                <parameter name="scope" value="session"/>            </handler>            <handler name="Handler2" type="java:org.apache.axis.handlers.JWSHandler">                <parameter name="scope" value="request"/>                <parameter name="extension" value=".jwr"/>            </handler>        </requestFlow>    </globalConfiguration>    <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>    <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>    <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>    <transport name="http">        <requestFlow name="RequestFlow1">            <handler name="Handler1" type="URLMapper"/>            <handler name="Handler2" type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>        </requestFlow>    </transport>    <transport name="local">        <responseFlow name="ResponseFlow1">            <handler name="Handler1" type="LocalResponder"/>        </responseFlow>    </transport>    <service name="AdminService" provider="java:MSG">        <parameter name="allowedMethods" value="AdminService"/>        <parameter name="enableRemoteAdmin" value="false"/>        <parameter name="className" value="org.apache.axis.utils.Admin"/>        <namespace>http://xml.apache.org/axis/wsdd/</namespace>    </service>    <service name="Version" provider="java:RPC">        <parameter name="allowedMethods" value="getVersion"/>        <parameter name="className" value="org.apache.axis.Version"/>    </service>    <service name="CalcService" provider="java:RPC">        <parameter name="allowedMethods" value="*"/>        <parameter name="className" value="org.mstar.ws.Calc"/>        <parameter name="scope" value="request"/>    </service>    <service name="FooService" provider="java:RPC">        <parameter name="allowedMethods" value="*"/>        <parameter name="className" value="org.mstar.ws.FooService"/>        <parameter name="scope" value="session"/>        <typeMapping encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"                     xmlns:ns1="http://ws.mstar.org"                     qname="ns1:FooBean"                     languageSpecificType="java:org.mstar.ws.FooBean"                     serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"                     deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"                     name="FooBean"/>        <requestFlow name="requestFlow1">            <handler name="Handler1" type="java:org.mstar.ws.FooHandler"/>        </requestFlow>        <responseFlow>            <handler name="Handler1" type="java:org.mstar.ws.FooHandler"/>        </responseFlow>    </service></deployment> 这个文件比Axis自带的那些deploy.wsdd要多很多东西,在Axis的文档中它使用命令来把对deploy.wsdd进行发布的。在我的例子中是直接把server-config.wsdd写好放到WEB-INF下。所以要把Service上面那些东西加上,否则系统不能正常运行。     <service name="CalcService" provider="java:RPC">        <parameter name="allowedMethods" value="*"/>        <parameter name="className" value="org.mstar.ws.Calc"/>        <parameter name="scope" value="request"/>    </service> 是Calc的发布描述。其中scope属性默认是request所以不写也可以。其他parameter看名字就知道干什么的了。这样你在List页面中就可以查看CalcService的WSDL了。第四步就是写客户端程序了。 WSClient.java try {            String endpoint = "http://localhost:8080/ws/services/CalcService";            Service service = new Service();            Call call = service.createCall();            call.setTargetEndpointAddress(endpoint);            call.setOperationName(new QName("http://ws.mstar.org", "plus"));            Object[] params = new Object[2];            params[0] = 10;            params[1] = 20;            Integer result = (Integer) call.invoke(params);            System.out.println("Result:  " + result);        } catch (Exception e) {            e.printStackTrace();        } 这是动态的调用WebService的方法,并不需要根据WSDL生成客户端存根。但是对于Service中有复合类型的时候就不可以了。下一个例子讲的就是如何做客户端存根。如果这个例子能够正常运行就可以了。 第五步做一个稍微复杂一点的例子,对于WebServices不能仅仅对简单类型的数据进行操作,也应该能对复杂类型进行操作。下面的例子就是: 先要一个复杂类型的类 public class FooBean {    private String foo1;    private Integer foo2;    private Boolean foo3;    public FooBean(String foo1, Integer foo2, Boolean foo3) {        this.foo1 = foo1;        this.foo2 = foo2;        this.foo3 = foo3;}…. Setter and Getter} 然后是一个有FooBean的Service public class FooService {    public FooBean getFooBean(String foo1,Integer foo2,Boolean foo3){        return new FooBean(foo1+"(Remote)",foo2+10,!foo3);    }} 很简单,就是返回一个FooBean,在参数上做了一些手脚J。 然后在server-config.wsdd中加入描述 <service name="FooService" provider="java:RPC">        <parameter name="allowedMethods" value="*"/>        <parameter name="className" value="org.mstar.ws.FooService"/>        <parameter name="scope" value="session"/>        <typeMapping encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"                     xmlns:ns1="http://ws.mstar.org"                     qname="ns1:FooBean"                     languageSpecificType="java:org.mstar.ws.FooBean"                     serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"                     deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"                     name="FooBean"/></service> 这里多了typeMapping标记用来描述复杂数据类型FooBean。对入复杂类型的序列化可以是自定义的,在serializer deserializer属性中改。那个xmlns,要留意一下,因为在客户端生成存根时的AntTask中要写一些Mapping,来确定那些xmlns映射到哪些package。当然这些也可以在WSDL中找到。而WSDL中的xmlns也是在这里定义的。 下面也各客户端。由于这次的Service中有复杂类型所以要根据WSDL生成这些复杂类型和Service的存根。取得WSDL的方法可以使用java2WSDL来做,但那样太麻烦,其实在List页面中用右键-另存为就可以了。然后写一个ant文件 <?xml version="1.0" encoding="UTF-8"?><project default="GenJavaSub" basedir=".">    <taskdef name="wsdl2java" classname="org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask"/>    <target name="GenJavaSub">        <property name="output.dir" value="src"/>        <property name="generated.dir" value="src/org/mstar/wsclient/generated"/>        <property name="wsdl.url" value="wsdl/FooService.wsdl"/>        <delete dir="${generated.dir}"/>        <mkdir  dir="${generated.dir}"/>        <wsdl2java all="true" debug="false" helperGen="true"            noimports="false"            output="${output.dir}"            serverside="false"            skeletonDeploy="false"            typeMappingVersion="1.1"            url="${wsdl.url}"            verbose="false"            noWrapped="false">            <mapping namespace="http://ws.mstar.org" package="org.mstar.wsclient.generated"/>            <mapping namespace="http://localhost:8080/ws/services/FooService" package="org.mstar.wsclient.generated"/>        </wsdl2java>    </target></project> 这里上面的东西比较好理解,在下面的mapping中一定要注意,因为每个Service和ComplexType都有自己的xmlns,这里就是把xmlns映射到指定的package 比如 把http://ws.mstar.org 映射到org.mstar.wsclient.generated包。这些namespace可以在wsdl文件中找到。运行ant就会看见在src中的org.mstar.wsclient.generated中多了几个java文件。接下在我们就可以用这几个类了。还有一点要注意wsdl2java 的output属性要指向src,而不是generated文件夹。 客户端调用就相对容易多了   FooServiceService serviceLocator = new FooServiceServiceLocator();try {FooService service = serviceLocator.getFooService();    FooBean fooBean = service.getFooBean("fooBean", 10, true);System.out.println(fooBean);} catch (ServiceException e) {    e.printStackTrace();} catch (RemoteException e) {    e.printStackTrace();} 运行客户端看看!   做简单的WebService就基本上这样了。但这样的Webservice还远远不能用户真正的项目中,还有很多问题没有解决,比如安全问题,有状态会话问题等等。这些问题很多可以通过Hanlder来解决,他有点类似于FilterServlet。具体的东西我还有没有研究,axis在这方面的资料就很少了。研究明白以后再写一篇吧。

阅读全文(2084) | 回复(-1) | 编辑 | 精华

 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)

 
 



The Neurotic Fishbowl

.: 公告


Bloginess

«November 2025»
1
2345678
9101112131415
16171819202122
23242526272829
30

.: 我的分类(专题)

首页(31)
原创(9)
Ajax技术(1)
随笔(1)
web Server技术(6)


In the Bowl

.: 最新日志

NewsBar真的能赚钱吗?
学习蜡烛图
2009-02-19(汇市报道)
2009-2-18
正式进入汇市
jsp上传图片
一个MM搞笑的Google搜索记录
两头猪的精典对白
一个未婚男人的自述
寂寞而高贵的武士-----野蛮人(一)


.: 最新回复

回复:axis2安装步骤
回复:axis2安装步骤
回复:安装序列号集锦
回复:七大人物套装的背景知识
回复:一个未婚男人的自述
回复:2009-02-19


The Fishkeeper
blog名称:狂飙的蜗牛
日志总数:31
评论数量:19
留言数量:0
访问次数:159629
建立时间:2006年6月13日



Text Me

.: 留言板

签写新留言


Other Fish in the Sea

.: 链接


 pandaboss.bolg.sohu.com




站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 1.266 second(s), page refreshed 144793652 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号