struts token令牌机制
利用Struts同步令牌(Token)机制来解决Web应用中的重复提交问题。该方法的基本原理是:服务器端在处理到达的request之前,会将request中的Token值与保存在当前用户session中的令牌值进行比较,看是否匹配。在处理完该request后,且在response发送给客户端之前,将会产生一个新的 Token,该Token除传给客户端以外,也会将用户session中保存的旧的Token进行替换。这样,如果用户会退到刚才的提交页面并再次提交的话,客户端传过来的Token值和服务器端的不一致,从而有效地防止了重复提交地发生。
struts的Token机制实际上就是通过用户提交表单时,比较request中的请求参数“org.apache.struts.taglib.html.TOKEN”的值与当前会话中的属"org.apache.struts.action.TOKEN"的值是否相等,相等则是正常提交,不等则为重复提交。
下面我们看下一个完整的操作流程,这样便于理解:
首先我们要明白,重复提交是发生在什么情况下的,什么情况下需要处理重复提交。我们所要解决的重复提交一般是考虑用户新插入一条记录的情形,对于修改记录的重复提交一般不考虑,因为修改记录本身记录就存在ID,重复提交也只不过是重复更新数据库同一记录而已,对数据的正确性不会有影响。如果新插入一条记录不对重复提交进行处理的话,那么就会在数据库中重复插入同一记录,这样会在数据库产生冗余的重复记录。当我们要插入一条记录时,会分二步走。第一步我们要打开新增记录的页面。第二步,我们会在打开的页面中填写相关信息,然后提交,这个时候提交才算完成。
第一步:假如我们打开新增记录这个操作由add方法完成,代码如下:
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
this.saveToken(request);//这个方法就是产生令牌值,struts已有的方法
return mapping.findForward("add");//返回新增页面
}
通过调用saveToken(request),产生一个token值。(注:每次调用saveToken方法产生的token值都不同)然后在记录新增页面中的<html:form>内部增加一个隐含表单字段,形式如下:
<div>
<input type="hidden" name="org.apache.struts.taglib.html.TOKEN"
value="8b2d950f23b02c527988a14171254025">
</div>
然后再把token值"8b2d950f23b02c527988a14171254025"保存到当前会话中,也就是 session.setAttribute( "org.apache.struts.action.TOKEN","8b2d950f23b02c527988a14171254025");
第二步:假如我们提交这个页面数据由save方法完成,代码如下:
public ActionForward save(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
if (this.isTokenValid(request)) {//正常提交
this.resetToken(request);//清空当前会话中的token值
return mapping.findForward("success");//返回保存成功页面
} else {//重复提交
this.saveToken(request);//注:此方法在这里可要也可不要。
return mapping.findForward("fail");//返回重复提交提示信息页面
}
}
判断是不是重复提交关键是isTokenValid(request)这个方法,这个方法由struts提供,如果返回结果为true则表示正常提交,false则为重复提交。isTokenValid(request)这个方法实际上主要做了三件事,
1.判断当前会话是否过期,如果过期,直接返回false
HttpSession session = request.getSession(false);
if (session == null) {
return false;
}
2.然后再判断当前会话中是否存在令牌属性"org.apache.struts.action.TOKEN",如果不存在,返回false
String saved =(String) session.getAttribute("org.apache.struts.action.TOKEN");
if (saved == null) {
return false;
}
为什么令牌属性"org.apache.struts.action.TOKEN"会不存在呢,那是因为当用户正常提交后,会调用this.resetToken(request);//清空当前会话中的token值。也就是说resetToken(request)方法中调用了 session.removeAttribute("org.apache.struts.action.TOKEN");
当用户重复提交时,我说了"this.saveToken(request);//此方法在这里可要也可不要。",下面我们分
析下,如果不调用这个方法,会话中就不会再重新保存token值,那么再刷新的时候,session中的token
值总是为null,isTokenValid(request)直接返回false,如果调用this.saveToken(request)的话,
session中会重新添加token属性值。这个时候isTokenValid(request)会进行下面第三步的判断。
3.从当前会话中取得token的值与当前request中得到的token值比较,相同返回true,不同返回false
String token = request.getParameter("org.apache.struts.taglib.html.TOKEN");
if (token == null) {
return false;
如果是重复刷新,那么每次request中的令牌值都是一样的,但每次刷新当前会话中的令牌值都被重新替换了,所以会返回false
注:使用struts的表单提交Token机制时,提交的表单一定要写成<html:form></html:form>这种形式,如果写成<form></form>这种形式的话,尽管调用saveToken(request)方法也不会在当前的<form></form>里面生成隐含表单,最终的结果都是"重复提交".
struts token令牌机制的更多相关文章
- java:struts框架3(自定义拦截器,token令牌,文件上传和下载(单/多))
1.自定义拦截器: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ...
- 【Java EE 学习 36】【struts2】【struts2系统验证】【struts2 ognl值栈】【struts2 ongl标签】【struts2 UI标签】【struts2模型驱动和令牌机制】
一.struts2系统验证 1.基于struts2系统验证的方式实际上就是通过配置xml文件的方式达到验证的目的. 2.实际上系统校验的方法和手工校验的方法在底层的基本实现是相同的.但是使用系统校验的 ...
- .NET WebAPI 用ActionFilterAttribute实现token令牌验证与对Action的权限控制
项目背景是一个社区类的APP(求轻吐...),博主主要负责后台业务及接口.以前没玩过webAPI,但是领导要求必须用这个(具体原因鬼知道),只好硬着头皮上了. 最近刚做完权限这一块,分享出来给大家.欢 ...
- WebAPI 用ActionFilterAttribute实现token令牌验证与对Action的权限控制
.NET WebAPI 用ActionFilterAttribute实现token令牌验证与对Action的权限控制 项目背景是一个社区类的APP(求轻吐...),博主主要负责后台业务及接口.以前没玩 ...
- day25(令牌机制)
令牌机制 作用:处理页面重复提交,造成数据多次写入数据库. 使用方法: 类似于验证码机制,使用session记录一个不可能重复的值(Uuid)在访问controller时对session进行校验. / ...
- java- 综合实例-增删查改查,删除多项,分页,令牌机制
重点内容:分页.令牌机制(重定向下防止重复提交).使用c3p0连接数据库(以及数据库连接类) 项目结构: 类: 项目展示: 数据库: /* SQLyog Ultimate v12.09 (64 bit ...
- 在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证
基于令牌的身份验证 基于令牌的身份验证主要区别于以前常用的常用的基于cookie的身份验证,基于cookie的身份验证在B/S架构中使用比较多,但是在Web Api中因其特殊性,基于cookie的身份 ...
- [Struts]Token 使用及原理
Struts Token 使用 1,先在一个Action中,调用saveToken(HttpServletRequest request)方法.然后转向带有表单的JSP页面. 2,在JSP页面提交 ...
- Token令牌管理权限
什么是token HTTP是一种无状态的协议,也就是HTTP没法保存客户端的信息,没办法区分每次请求的不同. Token是服务器生成的一串字符,作为客户端请求的令牌.当第一次登陆后,服务器会分发Ton ...
随机推荐
- php 23种设计模型 - 装饰模式
装饰器模式(Decorator) 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. ...
- java方法学习
java方法学习 方法概念 什么是方法 方法就是完成某些事情的过程,如:实现两个数相加,用方法add(数值1,数值2). 1.System.out.print(),System是系统的一个类,out是 ...
- mysql 完整备份和恢复
mysql 完整备份和恢复 一.MySQL完整备份操作 1.直接打包数据库文件夹 创建数据库auth: MariaDB [(none)]> create database auth;Quer ...
- 1251-Client does not support authentication protocol requested by server; consider upgrading MySQL client。
三:出现的一个错误在安装完MySQL的时候,我们现在一般都使用Navicat来连接数据库,可惜出现下面的错误:1251-Client does not support authentication p ...
- e值计算来了
e值该如何计算呢? 若关于ex幂级数展开 ex=1+x+x2/2!+x3/3!+•••+xn/n! 取x=1,有e=1+1/2+1/6+••• 接下来就是十分简单的编程 这里选用了python语言(当 ...
- 机器学习实战 | SKLearn最全应用指南
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/41 本文地址:http://www.showmeai.tech/article-det ...
- async-validator 源码学习笔记(二):目录结构
上一篇文章<async-validator 源码学习(一):文档翻译>已经将 async-validator 校验库的文档翻译为中文,看着文档可以使用 async-validator 异步 ...
- sqlserver 中,如何将getdate()时间的时分秒固定为00:00:00或者忽略不要
在使用getdate()时,时间会实时刷新,那么我们就要再查询的时候就需要精确到毫秒后三位,非常难受,那么为了解决这个问题我们可以通过以下几种方法进行固定或者去掉毫秒 1.将毫秒固定为00:00:00 ...
- 《手把手教你》系列基础篇(八十)-java+ selenium自动化测试-框架设计基础-TestNG依赖测试-番外篇(详解教程)
1.简介 经过前边几篇知识点的介绍,今天宏哥就在实际测试中应用一下前边所学的依赖测试.这一篇主要介绍在TestNG中一个类中有多个测试方法的时候,多个测试方法的执行顺序或者依赖关系的问题.如果不用de ...
- Java的http post请求01之HttpURLConnection
package com.ricoh.rapp.ezcx.iwbservice.webservice; import java.io.BufferedOutputStream; import java. ...