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,证明已经重复,不允许提交。

Struts之Token机制的更多相关文章

  1. Strut2 采用token机制防御CSRF同时也可以防止表单重复提交

    一 未配置Struts2 token的情况下测试 1.从表单提交数据,可以从下图看出,快速点击保存按钮,请求提交了两次 2.检查post提交的数据中未含有token参数 3.查看数据列表,有重复数据 ...

  2. 使用token机制来验证用户的安全性-b

    登录的业务逻辑{    http:是短连接.         服务器如何判断当前用户是否登录?        // 1. 如果是即时通信类:长连接.    // 如何保证服务器跟客户端保持长连接状态? ...

  3. javaEE开发中使用session同步和token机制来防止并发重复提交

    javaEE开发中使用session同步和token机制来防止并发重复提交 通常在普通的操作当中,我们不需要处理重复提交的,而且有很多方法来防止重复提交.比如在登陆过程中,通过使用redirect,可 ...

  4. 【原创】分布式之数据库和缓存双写一致性方案解析(三) 前端面试送命题(二)-callback,promise,generator,async-await JS的进阶技巧 前端面试送命题(一)-JS三座大山 Nodejs的运行原理-科普篇 优化设计提高sql类数据库的性能 简单理解token机制

    [原创]分布式之数据库和缓存双写一致性方案解析(三)   正文 博主本来觉得,<分布式之数据库和缓存双写一致性方案解析>,一文已经十分清晰.然而这一两天,有人在微信上私聊我,觉得应该要采用 ...

  5. IOS 中使用token机制来验证用户的安全性

    登录的业务逻辑{    http:是短连接.         服务器如何判断当前用户是否登录?    // 1. 如果是即时通信类:长连接.    // 如何保证服务器跟客户端保持长连接状态? // ...

  6. token机制完成登录状态保持/身份认证

    一般APP都是刚安装后,第一次启动时需要登录(提示你需要登录或者直接启动在登录界面).而只要登录成功后,以后每次启动时都是登录状态,不需要每次启动时再次登录.不过,也有些APP若你长期未启动,再次启动 ...

  7. 深入理解struts的运行机制

    扫码关注公众号,不定期更新干活 在此申明本博文并非原创,原文:http://blog.csdn.net/lenotang/article/details/3336623,本文章是在此文章基础上进行优化 ...

  8. Token机制,session机制

    对于初学者来说,对Token和Session的使用难免会限于困境,开发过程中知道有这个东西,但却不知道为什么要用他? session机制:就是一个id号(cookie里面携带一个sessionid), ...

  9. 前后端分离中的无痛刷新token机制

    今天我们来说一说前后端分离中的无痛刷新token机制 博主先来分享一波福利,最近挖到的宝藏,刚开始学Java的同学看 https://www.bilibili.com/video/BV1Rx41187 ...

随机推荐

  1. unsupported major.minor version 解决方法

        转载自http://hi.baidu.com/fatchong/blog/item/191da23b478bbfef15cecbae.html         一直以来都是用jdk1.5,这次 ...

  2. css3组件实战--绚丽效果篇

    代码地址如下:http://www.demodashi.com/demo/11656.html 一.3D风景动态骰子 在线演示 1.css3D.动画基础知识预备 2.创建一个3D场景 先放置一个.bo ...

  3. Silverlight实例教程 - Validation数据验证基础属性和事件(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  4. 转:SQL2008 UNPIVOT 列转行示例

    CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int, Emp3 int, Emp4 int, Emp5 int); GO INSERT INTO pv ...

  5. 将bloomfilter(布隆过滤器)集成到scrapy-redis中

    Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中,判断URL是否重复 布隆过滤器(Bloom Filter)详解 基本概念 如 ...

  6. Manjaro折腾笔记:我的数据科学环境搭建之路

    ss并且开机启动 0. 安装shadowsocks sudo pip install shadowsocks 1. 建立配置文件ss.json 我的位置是:/home/ray/Documents/sh ...

  7. Linux Linux程序练习二

    /* 编写一个程序读取a.txt文件,将文件内容数字从小到大排序,并将排序结果写入b.txt. */ #include <stdio.h> #include <stdlib.h> ...

  8. 第一百六十九节,jQuery,基础事件

    jQuery,基础事件 学习要点: 1.绑定事件 2.简写事件 3.复合事件 JavaScript 有一个非常重要的功能,就是事件驱动.当页面完全加载后,用户通过鼠标 或键盘触发页面中绑定事件的元素即 ...

  9. Servlet 环境设置

    开发环境是您可以开发.测试.运行 Servlet 的地方. 就像任何其他的 Java 程序,您需要通过使用 Java 编译器 javac 编译 Servlet,在编译 Servlet 应用程序后,将它 ...

  10. java String去除两端的空格和空字符

    java中String有个trim()能够去掉一个字符串的前后空格.但是trim()只能去掉字符串中前后的半角空格,而无法去掉全角空格.去掉全角空格需要在trim()方法的基础上加上一些判断.Stri ...