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. YII用户注冊和用户登录(五)之进行session和cookie分析 ,并在前后区分session和cookie

    5 进行session和cookie分析 ,并在前后区分session和cookie: 记住登录状态 这样下次再登录站点的时候.就不用反复输入username和password. 是浏览器的cooki ...

  2. 改动图片exif信息

    我们先了解一下EXIF: EXIF能够附加于JPEG.TIFF.RIFF等文件之中.为其添加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本号信息. 全部的JPEG文件以字符串"0xF ...

  3. nginx只允许域名访问,禁止ip访问

    背景:为什么要禁止ip访问页面呢?这样做是为了避免其他人把未备案的域名解析到自己的服务器IP,而导致服务器被断网,我们可以通过禁止使用ip访问的方法,防止此类事情的发生. 解决方法:这里介绍修改配置文 ...

  4. Jmeter-性能测试(三)

    一.调通脚本(以json串Post接口为例)添加聚合报告(线程组->添加->监听器->聚合报告)并调试好需要压测的脚本,如下已经调通的P_C_B151就是我需要压测的脚本 二.设置场 ...

  5. 关于struts、spring 和 hibernate的说明

    struts 是 web 框架 (jsp/action/actionfrom) hibernate 是 orm框架,处于持久层. spring 是容器框架,用于配置bean,并维护bean之间关系的框 ...

  6. MySQL学习总结(一)下载与安装

    关于数据库这块平时用的也就是Oracle和SQL Server,关于别的数据库也就是耳闻,但从没有用过.所以,最近一直都在学习使用MySQL数据库,这个教程也是通过记录博客,增加学习的印象. 关于My ...

  7. 20180113Go匿名函数和闭包

    最近codereview看到闭包,得学习下 https://studygolang.com/articles/5057 匿名函数:没有函数名的函数 闭包:外部函数定义的内部函数. 闭包给访问外部函数定 ...

  8. Atitit,通过pid获取进程文件路径 java php  c#.net版本大总结

    Atitit,通过pid获取进程文件路径 java php  c#.net版本大总结 1. 通过PID获取进程路径的几种方法2 1.1. GetModuleFileNameEx 想获得进程可执行文件的 ...

  9. 批量分发SSH秘钥

    #!/usr/bin/expect # filename: distribute_key.expif [ $argc != 2 ]{ send_user "usage: expect exp ...

  10. ConcurrentHashMap的JDK1.8实现

    今天我们介绍一下ConcurrentHashMap在JDK1.8中的实现.基本结构 ConcurrentHashMap在1.8中的实现,相比于1.7的版本基本上全部都变掉了.首先,取消了Segment ...