Java WebService学习笔记 - Axis进阶(二)

上一篇  Java WebService学习笔记 - Axis(一)

前一篇博文中简单介绍了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属性,属性值的映射内容可以在\webapps\axis\WEB-INF\users.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:先有鸡还是先有蛋!



posted @ 2014-05-22 16:49  汤姆的猫  阅读(170)  评论(0编辑  收藏  举报