挠痒痒的专栏

彪悍的人生不需要解释

用户操作
[即时聊天] [发私信] [加为好友]
蔡晖ID:chnic
1152次访问,排名2万外好友3人,关注者7
彪悍的人生不需要解释
chnic的文章
原创 8 篇
翻译 0 篇
转载 0 篇
评论 3 篇
挠痒痒的公告
写Blog主要为了沉淀一下自己的所学。这里的博文都是从我的另一博客copy来的。http://chnic.javaeye.com
最近评论
chnic:不好意思,源代码blog上面都有的。
你可以自己copy. 我基本上是在一份源代码上做的所有东西。
wsdd 还有一些相关文件早就改的面目全非了。
你照着我的步骤一步一步来 不会出错的。
singlesword2007:写的不错!深入而且易懂,期待下一篇!
allisgone:可以发一个完整的例子给我吗?发到邮箱里,谢了
文章分类
收藏
    相册
    存档
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 利用AXIS开发Webservice(二) —— WSDD的一些高级特性收藏

    新一篇: 利用AXIS开发Webservice(三) —— 如何传递JavaBean和你的对象 | 旧一篇: 利用AXIS开发Webservice(一) —— 如何发布自己的webservice

    第一篇介绍了AXIS的两种发布方式,和一些基本的应用。这一篇说一下一些高级应用。 开篇之前先把上篇的一个遗漏补充上,上篇只讲了怎么发布一个webservice,但是如何取消没有却没有提。其实取消一个已经发布的webservce 也是非常简单的,我们就拿上篇的HelloWorld来做例子吧。 

    发布webservice的时候我们有一个deploy.wsdd文件,当然在取消发布的时候就会有一个undeploy.wsdd文件。这个文件的内容也很简单,xml的代码如下。

    <undeployment xmlns="http://xml.apache.org/axis/wsdd/">
     
    <service name="HelloWorld"/>
    </undeployment>

    编写完这个xml文件之后,把它同样copy到%TOMCAT_HOM\webapps\axis\WEB-INF目录下,然后CMD打开控制台,在控制台输入一个我们很熟悉的命令

        java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient undeploy.wsdd

    运行之后得到如下结果说明取消发布成功

    Processing file undeploy.wsdd       
    <Admin>Done processing</Admin>

    说完取消发布之后就来说一下AXIS的一些高级特性,AXIS在编写deploy.wsdd这个文件时,每个<service>节点下面会有这样一个子节点。

     <parameter name="scope" value="value"/>

    这个节点配置着你的service object也就是你webservice服务的那个object的圣明周期,在后面的value里可以有三个选项request, session, or application。熟悉Jsp、Servlet、或者EJB里的SessionBean的朋友应该能很快能明白这个三个配置选项的含义。

    requst:这个选项会让AXIS为每一个SOAP的请求产生一个服务对象,可以想像如果这个webservice的对象足够复杂,而且SOAP的请求过多,这个选项是非常耗费服务器性能的。
    session:如果选择了session,程序就会给每个调用这个webservice的客户端创造一个服务对象。
    application:这个选项最彪悍,程序只会在内存里new出来一个服务对象,然后为所有webservice客户端服务。很显然这个选项不能储存客户端的一些个性化数据。所以在功能性上很多时候不能满足要求。

    接 下来说一下Axis的Handler和Chain机制,Handler和Chain是Axis引擎提供的一个很强大的工具。假如现在客户有这样一个需求, 需要记录某一个webservice被调用的次数,这个时候如果在service object里去实现这个功能不仅麻烦,而且侵入了原有的程序也会对增加原有程序的不稳定性。有了Handler我们就能见easy的解决这个问题。我们 先来编写handler的代码。

    package com.chnic.handler;

    import org.apache.axis.AxisFault;
    import org.apache.axis.MessageContext;
    import org.apache.axis.handlers.BasicHandler;

    public class HelloWorldHandler extends BasicHandler{

        
    private static final long serialVersionUID = 1L;
        
    public void invoke(MessageContext context) throws AxisFault {
            String status 
    = (String) this.getOption("status");
            System.out.println(
    "HelloWorldHandler's status is: " + status);
        }

    }
     

    BasicHandler是一个抽象类,Axis提供了很多Handler的具体实现,BasicHandler只是其中最简单的一个。要实现一个自己的 handler首先要从继承BasicHandler这个类开始并实现其中的invoke(MessageContext arg)这个方法。MessageContext可以看成是一个Axis的上下文,里面存储的是一些Axis和webservice的基本信息。想了解的 朋友可以看一下Axis的API。编写完Handler代码之后我们连编写发布文件。
    <deployment xmlns="http://xml.apache.org/axis/wsdd/" 
        xmlns:java
    ="http://xml.apache.org/axis/wsdd/providers/java">
        
    <handler name="Hello" type="java:com.chnic.handler.HelloWorldHandler">
             
    <parameter name="status" value="success"/>
        
    </handler>

         
    <service name="HelloWorld" provider="java:RPC">
         
    <requestFlow>
           
    <handler type="Hello"/>
         
    </requestFlow>
             
    <parameter name="className" value="com.chnic.webservice.HelloWorld"/>
             
    <parameter name="allowedMethods" value="*"/>
             
    <parameter name="scope" value="session"/>
         
    </service>
    </deployment>

    发布代码中有这样的一句,细心的朋友一定会发现。

    <parameter name="status" value="success"/>

    看完这句代码再对比一下Handler的实现代码中的一句,相信大多数人都能明白了。
    String status = (String) this.getOption("status");

    Handler通过getOption(String)这个方法拿到了配置文件中我配置的属性值。而我们上述所做的所有工作对于原来的 Webserivce来说都是透明的,不会对侵入原有的程序当中。 一个Handler可以被多个service所使用通过<requestFlow>这个标签来引用到某一个service中,这里还要多提一 句既然是一个requestFlow,这个当然可以加不只一个的Handler。接下来编写测试代码运行。在本地应用服务器上会打出如下语句: HelloWorldHandler's status is: success

    说明测试成功,而且handler是配置在requestflow标签中所以这段代码会在service代码之前先执行。

    介 绍完了Handler再来介绍Chain。从Chain的字面意思就能猜到他实现的一连串Handler的功能。假如某个service需要不止一个 Handler,或者要根据Client的情况来选择需要那些Handler。特别是后一个需求,我们无法用一个或者几个Handler来解决,这个时候 我们就需要<Chain>来实现了。我们先再编写一个Handler,加上之前的那个Handler我们来组成一条锁链。

    package com.chnic.handler;

    import org.apache.axis.AxisFault;
    import org.apache.axis.MessageContext;
    import org.apache.axis.handlers.BasicHandler;

    public class MyHandler extends BasicHandler {

        
    private static final long serialVersionUID = 1L;
        
    public void invoke(MessageContext context) throws AxisFault {
            System.out.println(
    "This is MyHandler..");
        }

    }

    之后我们编写Chain的代码
    package com.chnic.chain;

    import org.apache.axis.SimpleChain;
    import com.chnic.handler.HelloWorldHandler;
    import com.chnic.handler.MyHandler;

    public class HelloWorldChain extends SimpleChain {

        
    private static final long serialVersionUID = 1L;
        
    public HelloWorldChain(){
            HelloWorldHandler hwh 
    = new HelloWorldHandler();
            MyHandler mh 
    = new MyHandler();
            
    this.addHandler(hwh);
            
    this.addHandler(mh);
        }

    }

    在Chain的构造函数中,把我要的两个Handler用addHandler()方法加载进去。之后我们来编写发布文件。<chain>和<handler>元素有些许不同在这里有必要多句嘴。

    < chain>元素中的子元素只允许是<handler>或者<chain>。后者也就是允许在“锁链”里再嵌套“锁链”, 在这里就拿嵌套<handler>来举例,他同样有两种方式来实现。第一种是直接包含<handler>:

    <chain name="myChain">
          
    <handler type="java:com.chnic.handler.MyHandler"/>
    </chain>

    第二种是引用别的<handler>
    <handler name="myHandler" type="java:com.chnic.handler.MyHandler"/>
    <chain name="myChain"/>
       
    <handler type="myHandler"/>
    </chain>
    因为我们这里的Handler并没有由BasicHandler来实现,而是由继承SimpleChain这个类来实现,严格意义上讲, SimpleChain也可以算是一个Handler,因为SimpleChain也是从BasicHandler继承而来,他同样实现了invoke ()这个方法。下面回归正题,来看我们的发布代码。
    <deployment xmlns="http://xml.apache.org/axis/wsdd/" 
        xmlns:java
    ="http://xml.apache.org/axis/wsdd/providers/java">
         
        
    <chain name="myChain">
              
    <handler type="java:com.chnic.chain.HelloWorldChain"/>
        
    </chain>
        
         
    <service name="HelloWorld" provider="java:RPC">
         
    <requestFlow>
           
    <chain type="myChain"/>
         
    </requestFlow>

             
    <parameter name="className" value="com.chnic.webservice.HelloWorld"/>
             
    <parameter name="allowedMethods" value="*"/>
             
    <parameter name="scope" value="session"/>
         
    </service>    
    </deployment>

    从新发布webservice之后,运行我们的测试代码。会发现在应用服务器的本地控制台上打出两句Handler要输出的语句,说明测试成功。而且控制台打出语句的顺序是和我们加载handler的顺序一样的。

    除 了<requestFlow>之外,Axis还提供了与之相应的</responseFlow>,用法和是 requestflow一样的,所不同的是一个在service执行之前一个是之后。可以加下面代码到发布文件中的<service>元素下 就可以实现responseflow的功能

    <responseFlow>
         
    <handler type="HelloWorldHandler"/>
     
    </responseFlow>

    最后简单提一下远程管理,也就是Remote Administration。要实现远程管理在发布文件的<service>标签下加入下面一段语句就可以了。

    <parameter name="enableRemoteAdmin" value="true"/>

    不过远程管理会有安全方面的问题,所以不建议使用。

    一些高级部分就先说到这里,还有一些比如RPC docuement Wrapped Message的区别和使,如何传递一个Javabean,还有一些配置方面的的问题就留到下节说吧。

    发表于 @ 2008年03月14日 00:07:00|评论(loading...)|编辑

    新一篇: 利用AXIS开发Webservice(三) —— 如何传递JavaBean和你的对象 | 旧一篇: 利用AXIS开发Webservice(一) —— 如何发布自己的webservice

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 挠痒痒