论坛首页 Java版 Struts

使用JIVE的代理模式来扩展struts+Spring+Hibernate的web框架

浏览 6688 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2004-10-29
管理员对系统模块的操作权限认证,有主要有三种方法:
1.在每个需要认证的模块前面插入一段验证码.
2.使用AOP或拦截器.
3.使用代理设计模式.

第一种方法,太笨.
第二种方法,在struts中不易实现,因为Strust的Action被Struts容器接管理,Action初始化,实例化都是由系统自动进行的.如果真的是由AOP实现,也许是一大推代码,很麻烦.

下面就讲讲第三种方法: [ 注意: 以下代码随手写的,目前还没有来得极测试 ]

1.定义一个常量类
[code:1]
package oa.web;

/**
* <p>Title: OA1.0</p>
*
* <p>Description: 常量 (权限) </p>
*
* <p>Copyright: Copyright (c) 2004</p>
*
* <p>Company: </p>
*
* @author 段洪杰
* @version 1.0
*/
public class Constant {
    /* 组合标识为: 权限+程序模块
     * 权限数据库字段为: 用户注册名  权限
     * 数据库中权限的记录为: 权限+程序模块(组合标识),为从Constant 类中读出再写到库中
     */

    //权限
    public static String AUTH_WRITE = "读写";
    public static String AUTH_READ = "只读";
    //程序模块数组
    public static String module[] = new String[] {"电子名片", "记事本", "文件快递"};

}

[/code:1]

2.Action的代理类
[code:1]
package oa.web;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForward;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import java.util.List;

/**
* <p>Title: OA1.0</p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2004</p>
*
* <p>Company: </p>
*
* @author 段洪杰
* @version 1.0
*/
public class CardProxyAction extends CardAction {

    private static Logger log = Logger.getLogger(CardProxyAction.class);


    /**
     * 执行用户程序权限检查, 从SessionBean中取得权限List来确定
     * 返回状态:
     *  0  系统超时
     *  1  没有登录
     *  2  没有操作权限
     *  3  读写权限
     *  4  只读
     */
    private int check(ActionMapping mapping,
                      ActionForm form,
                      HttpServletRequest request,
                      HttpServletResponse response) throws
            Exception {

        String moduleName = "电子名片"; //本模块名称,必须和Constant类中定义变量一致

        /* 登录状态检查 */
        SessionBean sessionBean = (SessionBean) request.getSession().
                                  getAttribute("SessionBean");
        if (sessionBean == null) {
            return 0; //系统超时,请返回!
        }
        if (!sessionBean.getIsLogon()) {
            return 1; //你没有登录,请返回!
        }

        /* 本模块权限检查 */
        List userAuths = sessionBean.getUserAuths();
        if (userAuths == null || userAuths.isEmpty()) {
            return 2; //你没有操作权限,请返回!
        }
        for (int i = 0; i < userAuths.size(); i++) {
            String auth = (String) userAuths.get(i);
            //数据库中权限的记录为: 权限+程序模块
            String write = Constant.AUTH_WRITE + moduleName; // 读写权限
            if (write.equals(auth)) {
                return 3; //读写
            }
        }
        for (int i = 0; i < userAuths.size(); i++) {
            String auth = (String) userAuths.get(i);
            //数据库中权限的记录为: 权限+程序模块
            String read = Constant.AUTH_READ + moduleName; // 读写权限
            if (read.equals(auth)) {
                return 4; //只读
            }
        }
        return 2; //你没有操作权限,请返回!
    }

    /**
     * 返回无权限时状态信息
     * @param mapping ActionMapping
     * @param form ActionForm
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @param result int
     * @return ActionForward
     * @throws Exception
     */
    private ActionForward checkForward(ActionMapping mapping,
                                       ActionForm form,
                                       HttpServletRequest request,
                                       HttpServletResponse response, int result) throws
            Exception {

        switch (result) {
        case 0: {
            request.setAttribute("message", "系统超时,请返回!");
            request.setAttribute("locationFile",
                                 "<A HREF=\"javascript:history.back()\">返回</A>");
            return (mapping.findForward("message"));
        }
        case 1: {
            request.setAttribute("message", "你没有登录,请返回!");
            request.setAttribute("locationFile",
                                 "<A HREF=\"javascript:history.back()\">返回</A>");
            return (mapping.findForward("message"));

        }
        case 2: {
            request.setAttribute("message", "你没有操作权限,请返回!");
            request.setAttribute("locationFile",
                                 "<A HREF=\"javascript:history.back()\">返回</A>");
            return (mapping.findForward("message"));
        }
        case 3: {
            //有读写权限,这句一般不会直接调用,因为有权限时不会限制操作
            request.setAttribute("message", "有编辑权限!");
            request.setAttribute("locationFile",
                                 "<A HREF=\"javascript:history.back()\">返回</A>");
            return (mapping.findForward("message"));
        }
        case 4: {
            // 只读权限,没有写权限
            request.setAttribute("message", "你没有编辑权限,请返回!");
            request.setAttribute("locationFile",
                                 "<A HREF=\"javascript:history.back()\">返回</A>");
            return (mapping.findForward("message"));

        }

        }
        request.setAttribute("message", "不知名的错误信息!");
        request.setAttribute("locationFile",
                             "<A HREF=\"javascript:history.back()\">返回</A>");
        return (mapping.findForward("message"));

    }

    /**
     * 录入一条信息
     * @param mapping ActionMapping
     * @param form ActionForm
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @return ActionForward
     * @throws Exception
     */
    public ActionForward set(ActionMapping mapping,
                             ActionForm form,
                             HttpServletRequest request,
                             HttpServletResponse response) throws
            Exception {
        int result = this.check(mapping, form, request, response); //取出权限状态码
        if (result == 3) { //有读写权
            return super.set(mapping, form, request, response);
        } else { //无权,返回状态信息
            return this.checkForward(mapping, form, request, response, result);
        }
    }

}
[/code:1]
   
最后更新时间:2004-10-29
刚贴了上面的贴2分钟,又改了一下,把类中的两个方法放到基类中去了. 代码简洁了不少,已通过测试:

[code:1]
package oa.web;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForward;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import java.util.List;
import org.apache.struts.action.ActionServlet;
import oa.pojo.Card;

/**
* <p>Title: OA1.0</p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2004</p>
*
* <p>Company: </p>
*
* @author 段洪杰
* @version 1.0
*/
public class CardProxyAction extends CardAction {

    private static Logger log = Logger.getLogger(CardProxyAction.class);

    String moduleName = "电子名片"; //本模块名称,必须和Constant类中定义变量一致
   
    /**
     * 录入一条信息
     * @param mapping ActionMapping
     * @param form ActionForm
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @return ActionForward
     * @throws Exception
     */
    public ActionForward set(ActionMapping mapping,
                             ActionForm form,
                             HttpServletRequest request,
                             HttpServletResponse response) throws
            Exception {
        //checkForward, check方法在 BaseDispatchAction 类中
        int result = check(mapping, form, request, response,moduleName); //取出权限状态码
        if (result == 3) { //有读写权
            return super.set(mapping, form, request, response);
        } else { //无权,返回状态信息
            return checkForward(mapping, form, request, response, result);
        }
    }

}
[/code:1]
   
0 请登录后投票
最后更新时间:2004-10-29
看着怎么像是在写C语言呢?
一大堆的switch case,if 。。。。 else。。。。
   
0 请登录后投票
最后更新时间:2004-10-30
还不如给Struts actions做一个base action,在这里加上IoC和interceptor,比这个方案简单而且用途广泛。记得以前TSS介绍过一个给Struts加上IoC的改装,想来大概也就是如此。
   
0 请登录后投票
最后更新时间:2004-10-30
Struts 没有相关的AOP实现,好像WebWork2中有,如果真是这样就比WebWork2低了一筹,但不是有个一专门对Struts做的AOP吗? 它能够对
Action 进行拦截,
http://struts.sourceforge.net/saif/
会很好的!
   
0 请登录后投票
最后更新时间:2004-10-30
在STRUTS+SPRING+HIBERNATE中,完成可以用SPRING的 AOP !

但是感觉做起来比较烦. 不如代理模式直观.

还有一种实现方法是 filter .  在 chinaxp 网站上有下载这种方法的程序,但是功能太弱,控制不灵活!
   
0 请登录后投票
最后更新时间:2004-11-04
写得很好,不过我更喜欢用 SAIF. 

BTW: filter 里面如果做太多的事情,使得程序过程化了,有点面向过程的意思.
   
0 请登录后投票
最后更新时间:2004-11-05
泰国笨拙,加上IOC就可以了
   
0 请登录后投票
最后更新时间:2004-11-05
很多人主张用AOP, 我认为代理模式更加稳定.作为项目开发,而不是个人学习来说,代理模式更加可靠.

用aop依赖于第三方的jar包. 这种包的稳定性如果没有在实际项目中应用过.那风险就太大了.

看来很多程序员是学习了玩的,或者是做试验的.不太注重实际应用!
   
0 请登录后投票
最后更新时间:2004-11-05
dhj1 写道
很多人主张用AOP, 我认为代理模式更加稳定.作为项目开发,而不是个人学习来说,代理模式更加可靠.

用aop依赖于第三方的jar包. 这种包的稳定性如果没有在实际项目中应用过.那风险就太大了.

看来很多程序员是学习了玩的,或者是做试验的.不太注重实际应用!


你用得不熟的,就是“学习了玩的”?

现在流行的runtime AOP全部都是用dynamic proxy实现的,说穿了就是一个灵活的代理模式,跟你欣赏的代理模式有啥不同呢?唯一的不同就是可以(1)可以少写些代码;(2)更好的模块化。如果从实用的角度出发,用AOP更好地把aspect和business解耦,难道不是更易于维护的做法吗?至于“依赖第三方jar”的风险,我感觉说好听点是杞人忧天,说得难听点叫夜郎自大。如果Spring和Nanning都不可靠,难道我还能相信你自己做的一个小框架可靠?再说了,AOP也有公认的API,只要你照着AOP-Alliance API来实现你的aspect,这个AOP framework不行就换另一个,你要真喜欢自己做就自己做一个,工作量也并不比你实现一堆代理模式来得更大。
   
0 请登录后投票
论坛首页 Java版 Struts

跳转论坛:
JavaEye推荐