`
leo1211
  • 浏览: 140428 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Struts1.x令牌防止重复提交

阅读更多
Struts1.x令牌防止重复提交
在Action中的add方法中,我们需要将Token值明确的要求保存在页面中,只需增加一条语句:saveToken(request);,如下所示:
  
  public ActionForward add(ActionMapping mapping, ActionForm form,
  
  HttpServletRequest request, HttpServletResponse response)
  
  //前面的处理省略
  
  saveToken(request);
  
  return mapping.findForward("add");
  
  }在Action的insert方法中,我们根据表单中的Token值与服务器端的Token值比较,如下所示:
  
  public ActionForward insert(ActionMapping mapping, ActionForm form,
  
  HttpServletRequest request, HttpServletResponse response)
  
  if (isTokenValid(request, true)) {
  
  // 表单不是重复提交
  
  //这里是保存数据的代码
  
  } else {
  
  //表单重复提交
  
  saveToken(request);
  
  //其它的处理代码
  
  }
  
  }
  
  其实使用起来很简单,举个最简单、最需要使用这个的例子:
  
   一般控制重复提交主要是用在对数据库操作的控制上,比如插入、更新、删除等,由于更新、删除一般都是通过id来操作(例 如:updateXXXById, removeXXXById),所以这类操作控制的意义不是很大(不排除个别现象),重复提交的控制也就主要是在插入时的控制了。
  
  先说一下,我们目前所做项目的情况:
  
   目前的项目是用Struts+Spring+Ibatis,页面用jstl,Struts复杂View层,Spring在Service层提供事务控 制,Ibatis是用来代替JDBC,所有页面的访问都不是直接访问jsp,而是访问Structs的Action,再由Action来Forward到 一个Jsp,所有针对数据库的操作,比如取数据或修改数据,都是在Action里面完成,所有的Action一般都继承 BaseDispatchAction,这个是自己建立的类,目的是为所有的Action做一些统一的控制,在Struts层,对于一个功能,我们一般分 为两个Action,一个Action里的功能是不需要调用Struts的验证功能的(常见的方法名称有 add,edit,remove,view,list),另一个是需要调用Struts的验证功能的(常见的方法名称有insert,update)。
  
  就拿论坛发贴来说吧,论坛发贴首先需要跳转到一个页面,你可以填写帖子的主题和内容,填写完后,单击“提交”,贴子就发表了,所以这里经过两个步骤:
  
  1、转到一个新增的页面,在Action里我们一般称为add,例如:
  
  public ActionForward add(ActionMapping mapping, ActionForm form,
  
  HttpServletRequest request, HttpServletResponse response)
  
  throws Exception {
  
  //这一句是输出调试信息,表示代码执行到这一段了
  
  log.debug(":: action - subject add");
  
  //your code here
  
  //这里保存Token值
  
  saveToken(request);
  
  //跳转到add页面,在Structs-config.xml里面定义,例如,跳转到subjectAdd.jsp
  
  return mapping.findForward("add");
  
  }
  
  2、在填写标题和内容后,选择 提交 ,会提交到insert方法,在insert方法里判断,是否重复提交了。
  
  public ActionForward insert(ActionMapping mapping, ActionForm form,
  
  HttpServletRequest request, HttpServletResponse response){
  
  if (isTokenValid(request, true)) {
  
  // 表单不是重复提交
  
  //这里是保存数据的代码
  
  } else {
  
  //表单重复提交
  
  saveToken(request);
  
  //其它的处理代码
  
  }
  
  }
  
  下面更详细一点(注意,下面所有的代码使用全角括号):
  
  1、你想发贴时,点击“我要发贴”链接的代码可以里这样的:
  
  〈html:link action="subject.do?method=add"〉我要发贴〈/html:link〉
  
  subject.do 和 method 这些在struct-config.xml如何定义我就不说了,点击链接后,会执行subject.do的add方法,代码如上面说的,跳转到subjectAdd.jsp页面。页面的代码大概如下:
  
  〈html:form action="subjectForm.do?method=insert"〉
  
  〈html:text property="title" /〉
  
  〈html:textarea property="content" /〉
  
  〈html:submit property="发表" /〉
  
  〈html:reset property="重填" /〉
  
  〈html:form〉
  
   如果你在add方法里加了“saveToken(request);”这一句,那在subjectAdd.jsp生成的页面上,会多一个隐藏字段,类似 于这样〈input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae"〉,
  
  2、点击发表后,表单提交到 subjectForm.do里的insert方法后,你在insert方法里要将表单的数据插入到数据库中,如果没有进行重复提交的控制,那么每点击一 次浏览器的刷新按钮,都会在数据库中插入一条相同的记录,增加下面的代码,你就可以控制用户的重复提交了。
  
  if (isTokenValid(request, true)) {
  
  // 表单不是重复提交
  
  //这里是保存数据的代码
  
  } else {
  
  //表单重复提交
  
  saveToken(request);
  
  //其它的处理代码
  
  }
  
  注意,你必须在add方法里使用了saveToken(request),你才能在insert里判断,否则,你每次保存操作都是重复提交。
  
   记住一点,Struts在你每次访问Action的时候,都会产生一个令牌,保存在你的Session里面,如果你在Action里的函数里面,使用了 saveToken(request);,那么这个令牌也会保存在这个Action所Forward到的jsp所生成的静态页面里。
  
  如果你在你Action的方法里使用了isTokenValid,那么Struts会将你从你的request里面去获取这个令牌值,然后和Session里的令牌值做比较,如果两者相等,就不是重复提交,如果不相等,就是重复提交了。
  
   由于我们项目的所有Action都是继承自BaseDispatchAction这个类,所以我们基本上都是在这个类里面做了表单重复提交的控制,默认 是控制add方法和insert方法,如果需要控制其它的方法,就自己手动写上面这些代码,否则是不需要手写的,控制的代码如下:
  
  public abstract class BaseDispatchAction extends BaseAction {
  
  protected ActionForward perform(ActionMapping mapping, ActionForm form,
  
  HttpServletRequest request, HttpServletResponse response)
  
  throws Exception {
  
  String parameter = mapping.getParameter();
  
  String name = request.getParameter(parameter);
  
  if (null == name) { //如果没有指定 method ,则默认为 list
  
  name = "list";
  
  }
  
  if ("add".equals(name)) {
  
  if ("add".equals(name)) {
  
  saveToken(request);
  
  }
  
  } else if ("insert".equals(name)) {
  
  if (!isTokenValid(request, true)) {
  
  resetToken(request);
  
  saveError(request, new ActionMessage("error.repeatSubmit"));
  
  log.error("重复提交!");
  
  return mapping.findForward("error");
  
  }
  
  }
  
  return dispatchMethod2(mapping, form, request, response, name);
  
  }
  
  }

 

 原文地址 http://blog.csdn.net/qhmao/archive/2008/04/10/2280172.aspx
分享到:
评论

相关推荐

    Struts1.x令牌(Token)的使用.rar

    而Struts1.x的令牌机制(Token)则是防止重复提交、跨页请求攻击的重要手段。在此,我们将深入探讨Struts1.x令牌的使用方法及其背后的原理。 首先,理解为何需要令牌。在Web应用中,用户可能会意外或恶意地多次点击...

    Struts1.x实现防止提交的Token使用示例

    通过以上步骤,Struts1.x的Token机制就能有效地防止重复提交和CSRF攻击。在实际项目中,可以根据具体需求进行适当的调整,例如增加对Ajax请求的支持,或者自定义错误处理逻辑。记住,安全是Web开发中不可忽视的一...

    struts 1的标签的用法详细

    用于防止重复提交。`saveToken(request)`在请求处理前保存令牌,`isTokenValid(request)`检查令牌是否有效。若有效则继续处理,否则提示用户重复提交。 #### 7. RequestUtil 和 TagUtils - `RequestUtil`提供对请求...

    struts框架、及其标签使用的一些相关文档

    在实际应用中,Struts还提供了一种防止重复提交的机制,这在`Struts令牌防止重复提交.docx`中有所阐述。通过在请求中添加令牌,服务器可以在接收到请求时检查该令牌,如果发现重复的令牌,则拒绝处理,从而避免了因...

    张孝祥09年struts高级实战进阶PPT

    - **防止表单重复提交**:为了避免用户误操作导致的多次请求,可以通过令牌机制或JavaScript禁用提交按钮来防止重复提交。 **5. 用户界面组件** - **复选框的使用技巧**:在Struts中处理复选框的数据通常需要使用...

    java web demo

    `Struts1.x令牌(Token)的使用.rar`则涉及Struts 1.x框架中的令牌机制,这是一种防止重复提交和跨站请求伪造(CSRF)的安全措施。在表单提交过程中,Struts会生成一个唯一的令牌并存储在session中,同时将其作为隐藏...

    java_学习资料

    - **目的**:防止表单重复提交。 - **实现**:通过在表单中添加一个隐藏字段,并在提交表单前验证该字段的值是否有效。 **文件上传** - **原理**:使用MultipartRequest来处理含有文件的HTTP请求。 - **实现**:...

    struts_tag

    `<s:token>` 生成和检查令牌,防止重复提交。 Y. `<s:url>` 创建URL,可以附加参数,例如:`<s:url action="myAction"><s:param name="param1" value="value1" /></s:url>`。 Z. `<s:validate>` 验证表单字段。 ...

    struts 2标签库介绍

    虽然 Struts 2 不再推荐使用 Struts 1.x 的标签,但在某些情况下仍然可能见到 `<s:bean>` 标签。此标签用于访问 JavaBean 的属性值。例如:`<s:bean name="user" property="firstName"/>`,这里的 `name` 指定了 ...

    下面就介绍下Struts2每个标签的用法(有错请指正):

    - **用途**:相当于 Struts1.x 中的 `<bean>` 标签,用于创建 JavaBean 实例。 - **示例**: ```xml <s:bean name="myBean" id="beanInstance" class="com.example.MyBean"/> ``` ##### 8. `<s:checkbox>` 标签 ...

    小码哥Java学科的课程大纲.docx

    12. **MVC思想和令牌机制**:进一步探讨MVC设计模式,并介绍防止重复提交的令牌机制。 13. **模拟Struts1/2和Spring MVC**:模拟Struts框架或Spring MVC框架进行开发实践。 #### 六、JavaEE核心技能 1. **Struts2*...

    java必备知识点大全.pdf

    防止表单重复提交:为了防止表单被重复提交,可以使用token令牌或者点击后禁用提交按钮。 JSP标签:JSP标签用于在JSP文件中嵌入Java代码。 过滤器器:过滤器是用于对Web应用中的请求和响应进行预处理和后处理的...

    java常用框架学习笔记

    Struts2提供了防止表单重复提交的机制,可以通过令牌机制来实现。 ##### 9.11 Struts中Result标签 Struts2的`<result>`标签用于定义请求处理后的结果页面。 以上内容概述了Java开发中常用的几个框架的基本概念和...

Global site tag (gtag.js) - Google Analytics