山寨版struts的TokenProcessor类

来源:互联网 发布:免费教育网 建站 编辑:程序博客网 时间:2024/05/21 14:40

 

【文章标题】山寨版strutsTokenProcessor

【文章作者】曾健生

【作者邮箱】zengjiansheng1@126.com

【作者QQ190678908

【作者声明】本人水平有限,失误之处,敬请各位指出。

*******************************************************************************

Struts 1.x中有个很有用的工具类TokenProcessor,在阅读了源代码后根据原理进行了一定程度上的改写,同时也对这个类的编写思路进行阐述。

 

由于在原代码中要用到另外一个类Globals的常量值,方便起见把需要用到常量值写到山寨版的TokenProcessorMyTokenProcessor中,内容如下:

 

//标识session中的属性

    public static final String TOKEN_KEY = "newjueqi.net.csdn.session.token.key";

   

    //标识通过表单传递的属性

    public static final String PARAM_TOKEN_KEY = "newjueqi.net.csdn.session.param.token.key";

 

编写MyTokenProcessor类分以下几步:

 

一.把类变为“单实例模式”

 

//单例模式

    private MyTokenProcessor(){}

    private static final MyTokenProcessor myTokenProcessor=new MyTokenProcessor();

    public static MyTokenProcessor getInstance()

    {

       return myTokenProcessor;

    }  

 

二.产生一个随机的字符串, 把该字符串放在 Session , 并返回

 

//产生一个随机的字符串, 把该字符串放在 Session , 并返回

    public String saveToken(HttpServletRequest request){

      

       String tokenStr=null;

      

       //产生一个随机的字符串

       tokenStr=this.generateToken(request);

      

       //获取session

       HttpSession session=request.getSession();

      

       //把产生的字符串放入到session

       session.setAttribute(TOKEN_KEY, tokenStr);      

      

       return tokenStr; 

    }

 

其中的generateToken方法用MD5 算法和 sessionId, 系统时间产生一个随机的字符串

 

    private String generateToken(HttpServletRequest request){

      

       String tokenStr=null;

       String currentTime=null;

       String sessionId=null;

      

       //获取现在系统时间的字符串

       currentTime=System.currentTimeMillis()+"";

      

       //获取sessionID

       sessionId=request.getSession().getId();      

      

       try {

          

           MessageDigest md=null;

          

           //使用MD5算法

           md = MessageDigest.getInstance("MD5");

          

           //把系统时间和sessionId都参与MD5运算

           md.update( currentTime.getBytes());

          

           md.update( sessionId.getBytes());

          

      

           //获取MD5

           byte tokenByte[]=md.digest();

          

          

           //MD5值转换为16进制字符串

           tokenStr=this.toHex(tokenByte);

          

       } catch (NoSuchAlgorithmException e) {

          

           e.printStackTrace();

       }

      

       return tokenStr;

    }

 

generateToken中使用了一个函数把字节数组变成一个字符串,其中的原理已在本人的博文《从计算机的核心思想探讨一种进制转换的方法》(http://blog.csdn.net/newjueqi)进行了相关的阐述,这个函数的算法generateToken过程如图1 所示:

                                                               1

 

三.检验在 session 域中的 TOKEN_KEY 属性值和表单传递的请求参数的值是否一致。

    public boolean isTokenValid(HttpServletRequest request){

      

       //1.先检查session是否存在,如果不存在就返回

       HttpSession session=null;

       //getSession()获取session,传入的参数为false

       //则表示如果session不存在就不创建新的session

       session=request.getSession(false);

       if( session==null )

       {

           return false;

       }

      

       //2.检查 Session 中是否有 TOKEN_KEY 属性, 若没有, 返回 false

       Object tokenValue=session.getAttribute(TOKEN_KEY);

       if( tokenValue==null )

       {

           return false;

       }

      

       //3. 检查表单的隐藏域中是否存在指定的参数值: PARAM_TOKEN_KEY, 若不存在, 返回 false

       String paramValue=request.getParameter( PARAM_TOKEN_KEY );    

       if( paramValue==null )

       {

           return false;

       }

      

       //返回表单的隐藏域指定的参数值和Session域中属性值的比较结果

       return tokenValue.toString().equals(paramValue);

    }

 

四.清空 session 中的 TOKEN_KEY 属性

    public void resetToken(HttpServletRequest request){

      

       HttpSession session=null;

      

       //获取session的引用

       session=request.getSession();

      

       //如果session不为空,则从session中清除TOKEN_KEY 属性

       if( session!=null )

       {

           session.removeAttribute(TOKEN_KEY);

       }

             

    }

   

在附件中的工程是用这个自定义的类实现防止表单的重复提交。

附件下载地址:http://newjueqi.ys168.com/

 

原创粉丝点击