• Struts之Token机制


    Struts的Token(令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。

    具体使用方法如下:

    1.先在一个Action中,调用saveToken(HttpServletRequest request)方法。然后转向带有表单的JSP页面。

    2.在JSP页面提交表单给一个Action,再这个Action中进行是否为重复提交的判断。


     1     if (isTokenValid(request, true)) {
     2 
     3             // 未重复提交时,正确的时候应该做的事情
     4 
     5                   return mapping.findForward("success");
     6 
     7      } else {
     8 
     9             // 重复提交时,需要做的事情
    10 
    11                   saveToken(request);
    12 
    13                   return mapping.findForward("error");
    14 
    15      }

    Struts Token 机制原理:

    1,  由第一个Action调用saveToken(HttpServletRequest request),这个方法内部实现如下:

    protected void saveToken(HttpServletRequest request) {
    
            token.saveToken(request);
    
    }
    
    public synchronized void saveToken(HttpServletRequest request) {
    
     
    
            HttpSession session = request.getSession();
    
            String token = generateToken(request);
    
            if (token != null) {
    
                session.setAttribute(Globals.TRANSACTION_TOKEN_KEY, token);
    
            }
    
    }

    这个方法调用generateToken方法实现如下:

     public synchronized void saveToken(HttpServletRequest request) {
    
     
    
            HttpSession session = request.getSession();
    
            String token = generateToken(request);
    
            if (token != null) {
    
                session.setAttribute(Globals.TRANSACTION_TOKEN_KEY, token);
    
            }
    
    }

    generateToken完毕后,将得到的唯一值setAttribute到session中。

     session.setAttribute(Globals.TRANSACTION_TOKEN_KEY, token);

    Globals.TRANSACTION_TOKEN_KEY的值是:” org.apache.struts.action.TOKEN”

    然后跳转到JSP页面。

    2,  JSP页面的Struts自定义标签 <html:form>的标签类:org.apache.struts.taglib.html. FormTag

    这个类的doStartTag()方法会调用本类的renderToken()方法。

    protected String renderToken() {
    
            StringBuffer results = new StringBuffer();
    
            HttpSession session = pageContext.getSession();
    
     
    
            if (session != null) {
    
                String token =
    
                    (String) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
    
                    
    
                if (token != null) {
    
                    results.append("<input type="hidden" name="");
    
                    results.append(Constants.TOKEN_KEY);
    
                    results.append("" value="");
    
                    results.append(token);
    
                    if (this.isXhtml()) {
    
                        results.append("" />");
    
                    } else {
    
                        results.append("">");
    
                    }
    
                }
    
            }
    
     
    
            return results.toString();
    
    }

    这样子会生成类似于

     
     <input type="hidden" name="org.apache.struts.taglib.html.TOKEN" 
             value="6aa35341f25184fd996c4c918255c3ae">

    的隐藏标签。

    然后提交到一个Action中,在Action中用isTokenValid()方法进行比较session中” org.apache.struts.action.TOKEN”的这个key所对应的值和提交来的request中的” org.apache.struts.action.TOKEN”的这个value是否一致。

    如果为true,那么证明可以提交。如果为false,证明已经重复,不允许提交。

  • 相关阅读:
    MySQL中的char与varchar详解
    有关PHPstorm的git环境的配置和git密钥的生成总结
    PHP开发中常用的字符串操作函数
    PHP 二维数组排序函数的应用 array_multisort()
    大龄程序员的出路在哪里
    近期面试总结(PHP后端开发工程师)(部分笔试题)
    B-Tree目录和Hash索引的区别
    curl、fopen和file_get_contents区别
    什么是OAuth授权
    SEO 统计算法
  • 原文地址:https://www.cnblogs.com/uu5666/p/6635902.html
Copyright © 2020-2023  润新知