struts2的CRUD中的权限控制初探
来源:互联网 发布:共产 革命 知乎 编辑:程序博客网 时间:2024/05/29 18:52
« 博客园首页
struts2的CRUD中的权限控制初探(转)
作者:殇 来源:博客园 发布时间:2008-01-28 09:14 阅读:1247 次 原文链接 [收藏]
在信息管理系统中,涉及到最多的就是对信息(数据)的增删改查,当然在真是的系统中,对于这些操作要控制在严格的权限中,在前面的文章中,我们已经使用 struts2+hibernate+spring实现了简单的crud操作,现在我们就来研究下如何给这些相关操作增加权限控制。
当然最简单的实现就是在每个Action的CRUD方法中首先判断登陆用户的权限,如果没有此方法操作的权限就可以抛出一个说明原因的异常,这样在一个庞大的系统中,这样类似权限检查的代码就会在众多Action中蔓延,这将会使得业务逻辑代码变得晦涩,对系统以后的维护变得困难,严重违反了单一职责原则。
相反,我们可以将一个权限控制剥离到一个代理中,这样Action几乎不需要改动就可以达到权限控制的目的。以下是详细实现。
1.基本的实现步骤:使用一个动态代理类(Proxy),通过拦截一个对象(我们实现crud操作的一个抽象类AbstractCRUDAction)的行为("load", "store","remove")并添加我 们需要的功能(权限控制)来完成。Java中的java.lang.reflect.Proxy类和 java.lang.reflect.InvocationHandler接口为我们实现动态代理类提供了一个方案.
2.实现InvocationHandler接口的invoke()方法,所有代理对象的调用都会发送到invoke方法,所以只要在调用前后实现自己的控制即可,这里我们在调用代理方法之前进行权限控制,伪代码如下:本例的代码如下:
3.调用代理类实现系统功能,代码大致如此:
这样我们的权限控制目的就在引入动态代理后优雅的实现了,在上面的代码大家可能已经留意到,权限控制是在实际操作之前完成的,也有很多操作需要在 invoke之后完成,比如用户在完成一笔交易以后,积分要相应增加....那么我们就要在动态代理类的invoke后加入doAfter()之类的代码。是不是感觉到些什么,对,AOP,就是AOP思想的起源。
最后回到我们需要解决的问题上,由于我们是对struts2的Action进行动态代理,在整个struts的整个框架中,我们并不显式调用 action,这可怎么办呢?呵呵,不用着急,在aop风靡的今天,struts不会落后的,struts2整合了webwork,最重要的一个特性就是拦截器(拦截器)。在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个 action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。既然如此,我们看看struts2中拦截器调用的时序图:
yeah,和我们之前的动态代理的原理一样,那么我们就使用拦截器来完成我们这样的需求,下篇文章我们将解决这些问题。
当然最简单的实现就是在每个Action的CRUD方法中首先判断登陆用户的权限,如果没有此方法操作的权限就可以抛出一个说明原因的异常,这样在一个庞大的系统中,这样类似权限检查的代码就会在众多Action中蔓延,这将会使得业务逻辑代码变得晦涩,对系统以后的维护变得困难,严重违反了单一职责原则。
相反,我们可以将一个权限控制剥离到一个代理中,这样Action几乎不需要改动就可以达到权限控制的目的。以下是详细实现。
1.基本的实现步骤:使用一个动态代理类(Proxy),通过拦截一个对象(我们实现crud操作的一个抽象类AbstractCRUDAction)的行为("load", "store","remove")并添加我 们需要的功能(权限控制)来完成。Java中的java.lang.reflect.Proxy类和 java.lang.reflect.InvocationHandler接口为我们实现动态代理类提供了一个方案.
2.实现InvocationHandler接口的invoke()方法,所有代理对象的调用都会发送到invoke方法,所以只要在调用前后实现自己的控制即可,这里我们在调用代理方法之前进行权限控制,伪代码如下:
//在调用核心功能之前作一些动作
……
//调用核心功能
m.invoke(obj, args);
//在调用核心功能以后做一些动作
……
……
//调用核心功能
m.invoke(obj, args);
//在调用核心功能以后做一些动作
……
package com.waimai.experiment;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import com.waimai.web.AbstractCRUDAction;
/** *//**
* 描述:
*
*@author Stone yang 创建日期:2007-5-20
*@version pattern Study 技术支持: <a
* href="http://blog.csdn.net/yq76034150">http://blog.csdn.net/yq76034150</a>
*/
publicclass ActionProxyimplements InvocationHandler...{
//需要权限控制的方法列表
private List<String> methods;
private Object target;
/** *//**
* 描述:构造函数
*
*@param methods
*@param target
*@author Stone yang 创建时间:2007-5-20
*/
public ActionProxy(Object target, String... methodNames)...{
this.methods = Arrays.asList(methodNames);
this.target = target;
}
public static Object getInstance()...{
ActionProxy actionProxy= new ActionProxy(new AbstractCRUDAction(),"load","store","remove");
return Proxy.newProxyInstance(AbstractCRUDAction.class.getClassLoader(),
new Class[] ...{AbstractCRUDAction.class}, actionProxy);
}
/** *//**
* 描述:
*
*@author Stone yang
*@see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable...{
// TODO 自动生成方法存根
this.doBegin();
return method.invoke(target, args);
}
/** *//**
*
* 描述:
*
*@author Stone yang 创建时间:2007-5-20
*/
private void doBegin() ...{
// TODO 自动生成方法存根
//权限检查代码
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import com.waimai.web.AbstractCRUDAction;
/** *//**
* 描述:
*
*@author Stone yang 创建日期:2007-5-20
*@version pattern Study 技术支持: <a
* href="http://blog.csdn.net/yq76034150">http://blog.csdn.net/yq76034150</a>
*/
publicclass ActionProxyimplements InvocationHandler...{
//需要权限控制的方法列表
private List<String> methods;
private Object target;
/** *//**
* 描述:构造函数
*
*@param methods
*@param target
*@author Stone yang 创建时间:2007-5-20
*/
public ActionProxy(Object target, String... methodNames)...{
this.methods = Arrays.asList(methodNames);
this.target = target;
}
public static Object getInstance()...{
ActionProxy actionProxy= new ActionProxy(new AbstractCRUDAction(),"load","store","remove");
return Proxy.newProxyInstance(AbstractCRUDAction.class.getClassLoader(),
new Class[] ...{AbstractCRUDAction.class}, actionProxy);
}
/** *//**
* 描述:
*
*@author Stone yang
*@see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable...{
// TODO 自动生成方法存根
this.doBegin();
return method.invoke(target, args);
}
/** *//**
*
* 描述:
*
*@author Stone yang 创建时间:2007-5-20
*/
private void doBegin() ...{
// TODO 自动生成方法存根
//权限检查代码
}
}
3.调用代理类实现系统功能,代码大致如此:
package com.waimai.experiment;
import com.waimai.web.CaiTypeAction;
/** *//**
* 描述:
*@author Stone yang 创建日期:2007-5-20
*@version pattern Study
* 技术支持: <a href="http://blog.csdn.net/yq76034150">http://blog.csdn.net/yq76034150</a>
*/
publicclass ProxyInvokeMock...{
/** *//**
* 描述:
*@param args
*@author Stone yang
* 创建时间:2007-5-20
*/
public static void main(String[] args)...{
// TODO 自动生成方法存根
CaiTypeAction actionProxy= (CaiTypeAction)ActionProxy.getInstance();
//调用需要进行权限控制的方法
actionProxy.load();
// actionProxy.store();
// actionProxy.remove();
}
}
import com.waimai.web.CaiTypeAction;
/** *//**
* 描述:
*@author Stone yang 创建日期:2007-5-20
*@version pattern Study
* 技术支持: <a href="http://blog.csdn.net/yq76034150">http://blog.csdn.net/yq76034150</a>
*/
publicclass ProxyInvokeMock...{
/** *//**
* 描述:
*@param args
*@author Stone yang
* 创建时间:2007-5-20
*/
public static void main(String[] args)...{
// TODO 自动生成方法存根
CaiTypeAction actionProxy= (CaiTypeAction)ActionProxy.getInstance();
//调用需要进行权限控制的方法
actionProxy.load();
// actionProxy.store();
// actionProxy.remove();
}
}
最后回到我们需要解决的问题上,由于我们是对struts2的Action进行动态代理,在整个struts的整个框架中,我们并不显式调用 action,这可怎么办呢?呵呵,不用着急,在aop风靡的今天,struts不会落后的,struts2整合了webwork,最重要的一个特性就是拦截器(拦截器)。在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个 action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。既然如此,我们看看struts2中拦截器调用的时序图:
yeah,和我们之前的动态代理的原理一样,那么我们就使用拦截器来完成我们这样的需求,下篇文章我们将解决这些问题。
》点击查看原文...
- struts2的CRUD中的权限控制初探
- struts2的CRUD中的权限控制初探
- 实现struts2的CRUD中的权限控制(一)
- 实现struts2的CRUD中的权限控制(二)
- 实现struts2的CRUD中的权限控制(一)
- Struts2 之四:初探CRUD
- 基于Struts2拦截器的权限控制
- Struts2实现权限控制
- Struts2权限控制
- Struts2权限控制
- Struts2权限控制
- Struts2权限控制
- struts2 一个CRUD的BaseAction
- Linux 系统中的超级权限的控制
- Linux 系统中的超级权限的控制
- Linux 系统中的超级权限的控制
- Linux 系统中的超级权限的控制
- Linux 系统中的超级权限的控制
- shell中的一些特殊变量
- 【整理】BIOS、BootLoader、uboot对比
- 黑马程序员——多线程
- 完美解决desktop图标换行问题
- linux下C语言多线程编程实例
- struts2的CRUD中的权限控制初探
- 跟着二厶学编程---JAVA第五章---【运算符】
- 实现struts2的CRUD中的权限控制(一)
- 好网站
- SSIS的OLEDB COMMAND中使用存储过程输出参数
- Sleep
- 关于昨天在鸿鹄上面看到一个问题-(网络)检查你是不是高手??
- 黑马程序员——基本数据类型和字符串类型
- 牢记职场生存中的10大职业铁律 让你受用一生