1、前言
axis1提供了这样的基本类,继承这个类后可以对服务的请求和回应过程进行监听和其他处理;
在使用上和servlet的过滤器非常相似,都是继承基本类,然后是提供服务,设置被拦截的方法,只不过在axis1中Filter被叫做Handler;
多个Handler可以单个存在,也可以被一个特别的Handler集中调用,这就是HandlerChain,这个意思也容易理解,chain的意思就是链嘛。
简单来说,Handler和HandlerChain的区别在于,二者继承的类是不同的
Handler继承BasicHandler
HandlerChain继承SimpleChain
再一个是,HandlerChain调用Handler,即Handler是HandlerChain存在的基础
最后是,Handler可以获取WSDD方式发布服务时设置的默认值,但是HandlerChain则不可以。
2、前期准备
我们运行Handler一般是用于基本服务的监控的,所以需要先有一个基本类,由于之前已经有介绍如何编写和发布此类服务,这里不再赘述
请参考
axis1-myeclipse/eclipse-入门级别-资源、流程、常见问题
axis1.4 wsdd 方式发布webservice 服务配置文件以及常用的DOS执行语句
总之,提供一个可对外发布的服务即可。
3、Handler的编写、发布、调用配置和运行效果
TheHandler.java
其继承了 BasicHandler,用于统计服务被访问的次数,当然后面会说到如何设置,这个invoke方法是继承自父类。
package com.demo.action; import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.handlers.BasicHandler; public class TheHandler extends BasicHandler { /** * 继承axis1的BasicHandler,设置全局变量,该类类似于web中的lister类,自动运行 */ private static final long serialVersionUID = 3423234116214630747L; private static int SUM_COUNT = 0; public void invoke(MessageContext arg0) throws AxisFault { // TODO Auto-generated method stub SUM_COUNT++;//更新服务的总访问次数 System.out.print("TheHandler-服务被访问的次数为:"+SUM_COUNT+" "); //还可以在wsdd配置文件中设置全局变量 String param0 = (String) this.getOption("param0"); System.out.println("配置文件的参数为:"+param0); } }
由于我们下面还有一个HandlerChain的实验,所以这里再写一个类,TheHandler2.java,功能实现是一样一样的~
package com.demo.action; import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.handlers.BasicHandler; public class TheHandler2 extends BasicHandler { /** * 继承axis1的BasicHandler,设置全局变量,该类类似于web中的lister类,自动运行 */ private static final long serialVersionUID = 3423234116214630747L; private static int SUM_COUNT = 0; public void invoke(MessageContext arg0) throws AxisFault { // TODO Auto-generated method stub SUM_COUNT++;//更新服务的总访问次数 System.out.print("TheHandler2-服务被访问的次数为:"+SUM_COUNT+" "); //还可以在wsdd配置文件中设置全局变量 String param0 = (String) this.getOption("param0"); System.out.println("配置文件的参数为:"+param0); } }
编写wsdd发布文件,和一般服务不同的是,Handler的声明比较简单
<handler name="自定义" type="类路径">,可以有常量设置,<paramter name="" value="">
而调用的方法分为<requestFlow>即服务被请求,<responseFlow>即响应外部请求
<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <!-- 定义handler和常量 --> <handler name="TheHandler" type="java:com.demo.action.TheHandler"> <parameter name="param0" value="testParam" /> </handler> <handler name="TheHandler2" type="java:com2.demo.action.TheHandler"> <parameter name="param0" value="testParam" /> </handler> <service name="TheUserWsddAction" provider="java:RPC"> <requestFlow> <!-- 外部请求时调用handler-其他服务会自动触发这个 --> <handler type="TheHandler"/> </requestFlow> <parameter name="className" value="com.demo.action.TheUserWsddAction" /> <!-- * 代表所有的方法都暴露 --> <parameter name="allowedMethods" value="*" /> <parameter name="scope" value="request" /> <!-- 这里的urn:TheUser和new QName("urn:TheUser", "TheUser")这里是对应的 --> <beanMapping qname="myNSD:TheUser" xmlns:myNSD="urn:TheUser" languageSpecificType="java:com.demo.model.TheUser"/> <!-- 响应外部请求时调用handler-其他服务会自动触发这个 --> <responseFlow> <handler type="TheHandler"/> </responseFlow> </service> </deployment>
(
使用wsdd发布命令,在wsdd文件目录下运行下面的命令。
发布的命令:java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -l http://localhost:8080/webserviceAxis1/services/HelloWSDD deployfz.wsdd
去除服务的命令:java org.apache.axis.client.AdminClient undeploy.wsdd -l http://localhost:8080/webserviceAxis1/servlet/AxisServlet undeploy.wsdd
undeploy.wsdd的内容请看文章最后的终极版
)
发布后调用 service名字为TheUserWsddAction的方法
控制台打印
再运行一次
访问次数累加,
过程是,第一次:进1,出2
第二次,进3,出4
累加
然后运行undeploy.wsdd把服务去除,因为要运行handlerChain,避免混乱
4、HandlerChain的编写、发布、调用配置和运行效果
TheHandlerChain.java,继承了 SimpleChain.java
package com.demo.action; import org.apache.axis.SimpleChain; public class TheHandlerChain extends SimpleChain { /** * */ private static final long serialVersionUID = 195605837725263130L; public TheHandlerChain() { TheHandler theHandler =new TheHandler(); TheHandler2 theHandler2 =new TheHandler2(); this.addHandler(theHandler); this.addHandler(theHandler2); } }
发布文件
发布handlerChain有两个思路,1:a是handler,a是chain,2:a是handlerchain
在调用上则没有差异,声明式chain调用即可
<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <!-- 声明handlerChain的两个思路,1:a是handler,a是chain,2:a是handlerchain--> <!-- 1 --> <!--<handler name="HandlerChainF" type="java:com.demo.action.TheHandlerChain"/> <chain name="HandlerChain"> <handler type="HandlerChainF"/> </chain> --><!-- 2 --> <chain name="HandlerChain"> <parameter name="param0" value="testParam" /> <handler type="java:com.demo.action.TheHandlerChain"/> </chain> <service name="TheUserWsddAction" provider="java:RPC"> <requestFlow> <!-- 外部请求时调用handler-其他服务会自动触发这个 --> <chain type="HandlerChain"/> </requestFlow> <parameter name="className" value="com.demo.action.TheUserWsddAction" /> <!-- * 代表所有的方法都暴露 --> <parameter name="allowedMethods" value="*" /> <parameter name="scope" value="request" /> <!-- 这里的urn:TheUser和new QName("urn:TheUser", "TheUser")这里是对应的 --> <beanMapping qname="myNSD:TheUser" xmlns:myNSD="urn:TheUser" languageSpecificType="java:com.demo.model.TheUser"/> <!-- 响应外部请求时调用handler-其他服务会自动触发这个 --> <responseFlow> <chain type="HandlerChain"/> </responseFlow> </service> </deployment>
(
发布:java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -l http://localhost:8080/webserviceAxis1/services/HelloWSDD deployHandlerChain.wsdd
)
运行调用:(服务器重启)
进:1和1,出2和2
5、undeploy.wsdd终极版
<undeployment xmlns="http://xml.apache.org/axis/wsdd/"> <!-- 去除service --> <service name="HelloWorldWSDD"/> <service name="TheUserWsddAction"/> <!-- 去除handler-不要发布不存在的handler一单被使用只能到server-config.wsdd修改文件了 --> <handler name="TheHandler2"></handler> <handler name="TheHandler"></handler> <!--去除handlerChain--> <chain name="HandlerChain"></chain> </undeployment>