在信息管理系统中,涉及到最多的就是对信息(数据)的增删改查,当然在真是的系统中,对于这些操作要控制在严格的权限中,在前面的文章中,我们已经使用 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方法,所以只要在调用前后实现自己的控制即可,这里我们在调用代理方法之前进行权限控制,伪代码如下:
struts2的CRUD中的权限控制初探(转) //在调用核心功能之前作一些动作
struts2的CRUD中的权限控制初探(转)
……
struts2的CRUD中的权限控制初探(转)
//调用核心功能
struts2的CRUD中的权限控制初探(转)
m.invoke(obj, args);
struts2的CRUD中的权限控制初探(转)
//在调用核心功能以后做一些动作
struts2的CRUD中的权限控制初探(转)
……
struts2的CRUD中的权限控制初探(转)
本例的代码如下:
struts2的CRUD中的权限控制初探(转)package com.waimai.experiment;
struts2的CRUD中的权限控制初探(转)
struts2的CRUD中的权限控制初探(转)
import java.lang.reflect.InvocationHandler;
struts2的CRUD中的权限控制初探(转)
import java.lang.reflect.Method;
struts2的CRUD中的权限控制初探(转)
import java.lang.reflect.Proxy;
struts2的CRUD中的权限控制初探(转)
import java.util.Arrays;
struts2的CRUD中的权限控制初探(转)
import java.util.List;
struts2的CRUD中的权限控制初探(转)
struts2的CRUD中的权限控制初探(转)
import com.opensymphony.xwork2.ActionSupport;
struts2的CRUD中的权限控制初探(转)
import com.waimai.web.AbstractCRUDAction;
struts2的CRUD中的权限控制初探(转)
{
       //需要权限控制的方法列表
struts2的CRUD中的权限控制初探(转)    
private List<String> methods;
struts2的CRUD中的权限控制初探(转)
struts2的CRUD中的权限控制初探(转)    
private Object target;
struts2的CRUD中的权限控制初探(转)

3.调用代理类实现系统功能,代码大致如此:
struts2的CRUD中的权限控制初探(转)package com.waimai.experiment;
struts2的CRUD中的权限控制初探(转)
struts2的CRUD中的权限控制初探(转)
import com.waimai.web.CaiTypeAction;
struts2的CRUD中的权限控制初探(转)
     这样我们的权限控制目的就在引入动态代理后优雅的实现了,在上面的代码大家可能已经留意到,权限控制是在实际操作之前完成的,也有很多操作需要在 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中拦截器调用的时序图:
struts2的CRUD中的权限控制初探(转)struts2的CRUD中的权限控制初探(转)
yeah,和我们之前的动态代理的原理一样,那么我们就使用拦截器来完成我们这样的需求,下篇文章我们将解决这些问题。

相关文章:

  • 2021-07-30
  • 2022-01-02
  • 2022-02-08
  • 2022-12-23
  • 2022-12-23
  • 2021-07-13
  • 2021-12-14
猜你喜欢
  • 2021-10-13
  • 2021-10-03
  • 2022-12-23
  • 2021-06-04
  • 2021-11-17
  • 2021-10-09
相关资源
相似解决方案