上一篇  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:先有鸡还是先有蛋!



Java WebService学习笔记 - Axis进阶(二)的更多相关文章

  1. Java WebService学习笔记 - Axis(一)

    WebService 简介 实际开发中,很多系统都是基于历史遗留系统进行开发,有时,这些系统基于不同的语言,如C,C++,C#,java,PHP等等.为了实现历史系统的再利用,或向外部程序暴露调用接口 ...

  2. WebService学习笔记系列(二)

    soap(简单对象访问协议),它是在http基础之上传递xml格式数据的协议.soap协议分为两个版本,soap1.1和soap1.2. 在学习webservice时我们有一个必备工具叫做tcpmon ...

  3. Java菜鸟学习笔记--数组篇(二):数组实例&args实例

    基本类型实例 //1.定义一个一维数组,先声明,在分配空间 int []number;//生命,没有初始化,number=null number=new int[5];//初始化为默认值,int默认值 ...

  4. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  5. Java NIO 学习笔记(二)----聚集和分散,通道到通道

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  6. Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer

    作者:Grey 原文地址:Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer ByteBuffer.allocate()与ByteBuffer.allocateD ...

  7. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

  8. java JDK8 学习笔记——第16章 整合数据库

    第十六章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API中的接口会有数据库厂商操作,称为JDBC驱动程 ...

  9. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

随机推荐

  1. C++ 海量代码 排查内存/GDI泄漏历程

    排查分两大部分: 1.代码静态分析,通过Code Review查找不合规范的代码点: 2.运行目标软件,结合内存监控工具,分析目标软件的代码,定位内存泄漏点. 目前能找到的代码静态分析软件:Cover ...

  2. 域渗透分析工具BloodHound

    简介:BloodHound是一款将域内信息可视化的单页的web应用程序,是一款在域内进行信息收集的免费工具: Kali中直接命令安装即可 apt-get install bloodhound 打开lo ...

  3. debug PHP程序(xdebug、IntelliJ IDEA)

    之前写PHP程序的都是echo调试,今天感觉太麻烦了就想起研究一下IntelliJ IDEA如何调试PHP程序. 从网上查找了很多资料,大部分都提到在IDE里开启服务,一下就懵了,怎么启这么多服务呢. ...

  4. SDP架构初识

    实现零信任的框架主要有SDP和Google Beyondcorp模型,前者出现在乙方的安全解决方案中,后者多作为甲方落地零信任的参考.本文主要记录对SDP技术的一些初步认识. 一.SDP简介 SDP是 ...

  5. Rocket - tilelink - Filter

    https://mp.weixin.qq.com/s/6XX0CZHoDotIgLbNDSIUog   简单介绍Filter的实现.   ​​   1. 基本介绍   使用过滤器过滤掉client和m ...

  6. Java实现 蓝桥杯 算法训练 乘法次数

    乘法次数 资源限制 时间限制:1.0s 内存限制:999.4MB 问题描述 给你一个非零整数,让你求这个数的n次方,每次相乘的结果可以在后面使用,求至少需要多少次乘.如24:22=22(第一次乘),2 ...

  7. Java实现LeetCode_0007_ReverseInteger

    package javaLeetCode_primary; import java.util.Scanner; /** * Given a 32-bit signed integer, reverse ...

  8. Python:求时间差(天时分秒格式)

    传入一个时间戳,以天时分秒格式打印出时间差 输入一个10位的时间戳,求出时间差 def time_diff(timestamp): onlineTime = datetime.datetime.fro ...

  9. Netty源码学习系列之1-netty的串行无锁化

    前言 最近趁着跟老东家提离职之后.到新公司报道之前的这段空闲时期,着力研究了一番netty框架,对其有了一些浅薄的认识,后续的几篇文章会以netty为主,将近期所学记录一二,也争取能帮未对netty有 ...

  10. 浅谈Python内置对象类型——数字篇(附py2和py3的区别之一)

    Python是一门面向对象的编程设计语言,程序中每一样东西都可以视为一个对象.Python内置对象可以分为简单类型和容器类型,简单类型主要是数值型数据,而容器类型是可以包含其他对象类型的集体,如序列. ...