`
zhuhaiyongleo
  • 浏览: 9821 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

如何防止页面刷新(Struts1.x)

    博客分类:
  • j2ee
阅读更多
Struts2中多次提交问题
使用Struts2.0+Spring2.0+Hibernate3整合开发实现基本的数据CRUD
字号: 大大  中中  小小 如何防止页面刷新(Struts1.x)
1.<forward name="action别名" path="/跳转页面" redirect="true" />

2.struts的token(令牌)机制



Struts令牌防止重复提交(转贴)!

转自http://blog.csdn.net/qhmao/archive/2008/04/10/2280172.aspx

在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);

  

  }

  

  }
分享到:
评论

相关推荐

    用户信息管理系统(仅登录注册搜索列表)【ssh+jsp+mysql5.x】

    用户信息管理系统(仅登录注册搜索列表)【ssh+jsp+mysql5.x】先注册再...前端页面利用JSP来实现动态内容的展示,并配合AJAX技术实现无刷新的用户体验,同时,使用Bootstrap框架来确保页面在不同设备上都有良好的响应性。

    图书管理系统(ssh+jsp+mysql5.x)含文档

    图书馆管理系统(SSH+JSP+MySQL5.x) 是一套融合了先进的信息技术解决...前端页面利用JSP来实现动态内容的展示,并配合AJAX技术实现无刷新的用户体验,同时,使用Bootstrap框架来确保页面在不同设备上都有良好的响应性。

    java之路-caibanStruts的使用

    这是一个经过改写的struts1.2 ...当要防止页面刷新时,可以使用basebean里的方法goRedirect(mappingName, params) 这是一些关于action使用时的建议,参考下 有问题可以联系我: QQ/EMAIL/MSN:x03570227@163.com

    Spring in Action(第二版 中文高清版).part1

    A.1 下载Spring A.1.1 研究Spring发布 A.1.2 构建自己的类路径 A.2 把Spring添加为一个Maven 2依赖项 A.3 Spring与Ant A.4 Spring与Log4j 附录B 用(和不用)Spring进行测试 B.1 测试简介 B.1.1 理解不同类型...

    Spring in Action(第二版 中文高清版).part2

    A.1 下载Spring A.1.1 研究Spring发布 A.1.2 构建自己的类路径 A.2 把Spring添加为一个Maven 2依赖项 A.3 Spring与Ant A.4 Spring与Log4j 附录B 用(和不用)Spring进行测试 B.1 测试简介 B.1.1 理解不同类型...

    整理后java开发全套达内学习笔记(含练习)

    十六进制数,零x开头 0x55(十六进制)=5*16+5(十进制) 类型:数据都必须有类型 boolean (8bit,不定的)只有true和false两个值 char 16bit, 0~2^16-1 (2^16=6万6) byte 8bit, -2^7~2^7-1 (2^7=128; 注意:两个 ...

    Spring in Action(第2版)中文版

    a.1下载spring a.1.1研究spring发布 a.1.2构建自己的类路径 a.2把spring添加为一个maven2依赖项 a.3spring与ant a.4spring与log4j 附录b用(和不用)spring进行测试 b.1测试简介 b.1.1理解不同类型的测试 b....

    千方百计笔试题大全

    18、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对? 9 19、是否可以继承String 类? 9 20、以下二条语句返回值为true 的有: 10 21、当一个对象被当作参数传递到一个方法后,此方法可...

    java面试宝典

    18、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对? 9 19、是否可以继承String 类? 9 20、以下二条语句返回值为true 的有: 10 21、当一个对象被当作参数传递到一个方法后,此方法可...

    JAVA上百实例源码以及开源项目

     数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录  一个Java+ajax写...

    JAVA上百实例源码以及开源项目源代码

     数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录  一个Java+ajax写...

Global site tag (gtag.js) - Google Analytics