会计考友 发表于 2012-8-4 12:37:27

JAVA基础:防止重复提交java解决方法

防止一再提交java解决
  B/S结构的软件开发中,出格是在越大型的分布式应用中浮现的越较着,后端的措置往往会因为呈现较多的时刻耗损而引起延迟,这种延迟有可能过长而最终使用户认为是自己的操作错误,导致他们从头提交请求,因为使命的一再提交,处事器资本大部门被占用,情节严重可能呈现近似死机现象。
  预期达到方针:
  1、当用户进行的是Refresh/Reload/Back/Forward操作、以及先Back再Submit操作时,仅仅是reloading先前的结不美观页。
  2、当用户一再提交统一个使命操作时,后台处事领受并措置第一次提交的使命,后面提交不起浸染(不转向也不提醒)。
  3、该功能具有公用性。
  根基形成思绪:
  1、在basic filter中实现公用性
  if(true){//问题1:若何确定是否为一再提交
  ...
  chain.doFilter(request,response);
  }else{
  //问题2:若何实现不转向、不提醒也不显示空白页
  }
  2、网上资料归纳综合
  a、提交表单后按钮变灰/潜匿提交按钮
  b、在js里设置全局变量,提交后改削该变量的值,依据变量的值判定是否一再提交
  var flag=true;
  function checkForm(){
  if (flag==false){
  return;
  }
  flag=false;
  document.form1.submit();
  }
  c、struts (webwork没有找到这个资料)
  //验证事务节制令牌,会自动按照session中标识生成一个隐含input代表令牌,防止两次提交
  在action中:
  //
  if (!isTokenValid(request))
  errors.add(ActionErrors.GLOBAL_ERROR,
  new ActionError("error.transaction.token"));
  resetToken(request); //删除session中的令牌
  action有这样的一个体例生成令牌华
  protected String generateToken(HttpServletRequest request) {
  HttpSession session = request.getSession();
  try {
  byte id[] = session.getId().getBytes();
  byte now[] =
  new Long(System.currentTimeMillis()).toString().getBytes();
  MessageDigest md = MessageDigest.getInstance("MD5");
  md.update(id);
  md.update(now);
  return (toHex(md.digest()));
  } catch (IllegalStateException e) {
  return (null);
  } catch (NoSuchAlgorithmException e) {
  return (null);
  }
  }
  d、用户使用浏览器时,可以经常使用向后的按钮,是以就有可能一再提交一个他们已经提交过的form,这样就会带来一个一再事务措置的问题。同样,一个用户也可能在领受到一个确认的页面之前按下遏制的按钮,接着再次提交统一个form。对于这些情形,我们都想跟踪而且禁止这些一再的提交,我们可以使用一个节制servlet来供给一个节制点,以解决这个问题。
  同步记号(Synchronizer (or Dvu) Token)
  这个策略是为体味决一再的form提交问题。一个同步的记号被设置在一个用户的Session中,而且包含在返回到客户的每一个form中。当form被提交时,form中的同步标识表记标帜就和Session中的同步标识表记标帜作对比。在form初度提交的时辰,这两个标识表记标帜应该是一样的。如不美观标识表记标帜纷歧样,那么该form就会禁止提交,一个错误就会返回给用户。在用户提交一个form时,如不美观按下浏览器中的猬缩后退按钮并考试考试从头提交统一个form时,标识表记标帜就会呈现不匹配的现象。
  另一方面,如不美观两个标识表记标帜值匹配,那么我们就可以确信整个流程是正确的。在这种情形下,
  另一方面,如不美观两个标识表记标帜值匹配,那么我们就可以确信整个流程是正确的。在这种情形下,Session中的标识表记标帜值就会被改削为一个新的值,同时许可提交该form。
  你也可以使用这个策略来节制对某些页面的直接访谒,就好象膳缦沔资本呵护中描述的一样。例如,假设一个用户将某个应用的页面A保藏到保藏夹中,而页面A只许可经由过程页面B和C访谒。当用户直接经由过程保藏夹来访谒页面A,这时页面的访谒挨次就是不正确的,这样同步标识表记标帜将处在一个分歧步的状况,或者它根柢就不存在。非论若何,访谒都被禁止了。
  e、做一个hidden框,名字自己定,提交后获得这个值放入session,提交前判定session是否为空
  解决方案:
  1、后台公共嘌扌实现前台的Form中自动生成两个hidden文本功能,一个是作page是否一再提交判定,并由系统自动附上关头值(如struts采用的方案);另一个作为button是否一再提交判定(struts中仿佛没有)。由后台公共类实现界面两个hidden text自动生成的益处在于公用性。
  2、在basic filter中按照两个hidden text值判定是否为一再提交。
  3、javascript中作一个公共体例,实现功能:如不美观需要判定是否一再提交,就给第二个hidden text附上关头值,并使该功能不成用。
页: [1]
查看完整版本: JAVA基础:防止重复提交java解决方法