前一篇博文中简单介绍了Axis的使用方法,这篇将介绍一些Axis的一些高级特性
Axis中Handler的使用
Handler的作用和Struts中Filter类似,主要用于访问之前或之后做一些特别的处理。主要包括权限验证,授权,访问量统计等等。
下面一个简单的例子介绍一下具体的使用方法
访问量统计
关于访问量统计,最简单的方法是在类内部添加一个静态同步的字段,每次访问对其进行加1.但是在WebService的中可能你只有一个class文件,此时不能也不允许在类中进行修改;而且在类中添加方法的话侵入性比较高。
Handler处理类:CountHandler.java
package com.handler; import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.handlers.BasicHandler; public class CountHandler extends BasicHandler { private static final long serialVersionUID = 6788857289474496020L; private long visitCount = 0L; @Override public void invoke(MessageContext msgCtx) throws AxisFault { visitCount++; String className = (String)msgCtx.getProperty("className"); System.out.println("class:"+className+" current visit count :"+visitCount); } }
将CountHandler.java编译后放到服务器webapps/axis/WEB_INF/classes/com/handler/下。
在上一篇笔记中的<service>中添加Handler处理
<service name="Answer" provider="java:RPC"> <span style="color:#ff0000;"><requestFlow> <handler type="java:com.handler.CountHandler"/> </requestFlow></span> <parameter name="className" value="com.webservice.wsdd.Answer"/> <parameter name="allowedMethods" value="*"/> <beanMapping qname="bean:Question" xmlns:bean="BeanManger" languageSpecificType="java:com.webservice.wsdd.Question" /> <span style="color:#ff0000;"><responseFlow> <handler type="java:com.handler.CountHandler"/> </responseFlow></span> </service>
在访问之前或之后都是可以的,两次都会创建不同的对象进行处理,处理结果如下
class:com.webservice.wsdd.Answer current visit count :1 read question:先有鸡还是先有蛋! class:com.webservice.wsdd.Answer current visit count :1 class:com.webservice.wsdd.Answer current visit count :2 read question:先有鸡还是先有蛋! class:com.webservice.wsdd.Answer current visit count :2
验证
首先要弄清楚验证和授权的概念,以普通的web应用为例,当你点击一个菜单时
验证:验证用户名密码是否正确
授权:前提是验证通过.根据用户名查询出访问权限,跟菜单的访问权限进行逻辑处理,如果有权限访问,则授权访问,否则,拒绝访问
下面给出一个简单的验证的例子
VerifyHandler.java
package com.handler; import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.handlers.BasicHandler; import org.apache.axis.security.AuthenticatedUser; import org.apache.axis.security.SecurityProvider; import org.apache.axis.security.simple.SimpleSecurityProvider; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class VerifiyHandler extends BasicHandler { private static final long serialVersionUID = 129414778283139001L; Log log = LogFactory.getLog(VerifiyHandler.class); @Override public void invoke(MessageContext msgCtx) throws AxisFault { //1.获取安全机制 SecurityProvider provider = (SecurityProvider) msgCtx.getProperty("securityProvider"); if(provider == null) { provider = new SimpleSecurityProvider(); msgCtx.setProperty("securityProvider", provider); } //2.验证访问,如果验证通过返回AuthenticatedUser对象,否则返回null AuthenticatedUser user = provider.authenticate(msgCtx); if(user == null) { log.info("verify failed"); throw new AxisFault("username or password not correct,visit refused"); } //为后面授权进行准备... msgCtx.setProperty("authenticatedUser", user); msgCtx.setProperty("yourRole", "007"); log.info("verify success,username:"+user.getName()); } }
和访问量统计处理步骤类似,配置文件如下
<service name="Answer" provider="java:RPC"> <span style="color:#ff0000;"><requestFlow> <handler type="java:com.handler.VerifiyHandler"/> <handler type="java:com.handler.CountHandler"/> </requestFlow> </span> <parameter name="className" value="com.webservice.wsdd.Answer"/> <parameter name="allowedMethods" value="*"/> <beanMapping qname="bean:Question" xmlns:bean="BeanManger" languageSpecificType="java:com.webservice.wsdd.Question" /> </service>
客户端访问时需要在原有的Call对象中设置username和password属性,属性值的映射内容可以在webappsaxisWEB-INFusers.lst中找到
call.setUsername("user3"); call.setPassword("pass3");
运行结果如下
- verify failed - verify success,username:user3 class:com.webservice.wsdd.Answer current visit count :1 read question:先有鸡还是先有蛋!
授权
AuthorizeHandler.java
package com.handler; import java.util.StringTokenizer; import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.handlers.BasicHandler; import org.apache.axis.security.AuthenticatedUser; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class AuthorizeHandler extends BasicHandler { private static final long serialVersionUID = -8124974403139594724L; Log log = LogFactory.getLog(this.getClass()); /** * */ @Override public void invoke(MessageContext msgContext) throws AxisFault { AuthenticatedUser user = (AuthenticatedUser) msgContext.getProperty("authenticatedUser"); if(user!=null) { String role = (String)msgContext.getProperty("yourRole"); String roles = (String)msgContext.getProperty("allowedRoles"); for (StringTokenizer t = new StringTokenizer(roles, ",");t.hasMoreTokens();) { String allowedrole = t.nextToken(); if(allowedrole.contains(role)) { log.info("authorize pass! welcome "+role); return; } } log.info("sorry,you did not have the permitions!"); throw new AxisFault("sorry,you did not have the permitions!"); } else { log.info("verify not pass,will not authorize!"); throw new AxisFault("verify not pass,will not authorize!"); } } }
配置如下
<service name="Answer" provider="java:RPC"> <requestFlow> <handler type="java:com.handler.VerifiyHandler"/> <span style="color:#ff0000;"><handler type="java:com.handler.AuthorizeHandler"/></span> <handler type="java:com.handler.CountHandler"/> </requestFlow> <parameter name="className" value="com.webservice.wsdd.Answer"/> <parameter name="allowedMethods" value="*"/> <span style="color:#ff0000;"><parameter name="allowedRoles" value="007,M"/></span> <beanMapping qname="bean:Question" xmlns:bean="BeanManger" languageSpecificType="java:com.webservice.wsdd.Question" /> </service>
运行结果如下
- verify success,username:user3 - authorize pass! welcome 007 class:com.webservice.wsdd.Answer current visit count :1 read question:先有鸡还是先有蛋!