论坛首页 Java企业应用论坛

关于如何处理类似"刷新"等重复提交的问题

浏览 10833 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-08-23  
我是看到下面xylohouse的关于“当用户关闭浏览器,如何kill掉服务器端为其执行的程序”想到的,他其中提到一点 -- 如果用户“刷新" 的情况

这一点应该是可以做到,参见“Using a Request Filter to Limit the Load on Web Applications”
http://www.onjava.com/pub/a/onjava/2004/03/24/loadcontrol.html

当已有request未处理完,有新的request进来,保存之,即使之前已有被保存的对象,也将其替换。就是说永远只有一个待处理的request。

举个例子:无耐心的用户点击标题新闻,没等到新页面打开,又点击了天气预报,然后又点击了体育栏目。事实上server只应该给用户看到的是体育栏目,标题新闻已经在处理中就无法避免,但是天气预报可以不用处理,而直接处理体育栏目,类似的统一页面刷新应该也是这样处理。


关键代码如下:
synchronized( getSynchronizationObject( session ););
{
  // if another request is being processed,
  // then wait
  if( isRequestInProcess( session ); );
  {
    // Put this request in the queue and wait
    enqueueRequest( httpRequest );;
    if( !waitForRelease( httpRequest ); );
    {
      // this request was replaced in the
      // queue by another request so it need
      // not be processed
      return;
      }
    }

    // lock the session, so that no other
    // requests are processed until this
    // one finishes
    setRequestInProgress( httpRequest );;
  }

  // process this request, and then release the
  // session lock regardless of any exceptions
  // thrown farther down the chain.
  try
  {
    chain.doFilter( request, response );;
  }
  finally
  {
    releaseQueuedRequest( httpRequest );;
  }
   发表时间:2004-08-23  
对了,要有选择的进行filter,图片或是其他的静态页面就没有必要了,通过对同一session的request的控制,应该也可以在一定程度上避免恶意攻击脚本。
0 请登录后投票
   发表时间:2004-08-23  
dhj1 写道
lllyq 写道
对了,要有选择的进行filter,图片或是其他的静态页面就没有必要了,通过对同一session的request的控制,应该也可以在一定程度上避免恶意攻击脚本。



通过对同一session的request的控制,应该也可以在一定程度上避免恶意攻击脚本。这是对的!

但是如果想提升性能,用SESSION和上面的方法,反而只会大大降低性能. 当用户点开一个网页时,不等待,再点另外的网页,这种情况不可能占访问用户的50%以上.如果再作专门处理,呵呵,情况只会更坏!


我想任何一种技术都有它适用的范围,那么以上这个范例我觉得比较适合用在很耗时的某几个页面(因为它是filter,用在什么地方你自己决定),也就是说由这个filter所增加的时间占整个处理时间的比重来决定,所占比重越小越有意义,不知道是不是还要举个例子说明:)
0 请登录后投票
   发表时间:2004-08-24  
"当用户关闭浏览器,如何kill掉服务器端为其执行的程序"

这样能节省多少系统资源?

应当从瓶颈入手。
0 请登录后投票
   发表时间:2004-08-24  
HTTP1.1其实是可以有态的,只不过在很多时候不需要而罢了,有态的速度无法让人接受(像FTP).

session是不单单可记录一些基本信息,你可以让它记录很多其它的东西,它在客户端只不过是用url或者cookies记录了一个sessionID,再到server端找到这个对象(或者想要的东西,有点类似hash表).

只不过觉得维护这个session有点麻烦.又不能夸域.
0 请登录后投票
   发表时间:2004-08-24  
对了,我没有试过上面的例子(对不起,这点我很不对).

我想楼主应该试过的.是吗?

我想问,如果我是用同一个IE window,打开其它的几个不同的连接(shift  + click on link),情况会怎么样?
如果像dhj1所说的那样,通过对同一session的request的控制.
那么我说的其它几个连接就会被终止是吗?

例如:
假设置csdn采用了这种技术.
我看到csdn的头条新闻有好几条我没有看过,在等待的时候,我想把其它的几个也打开,就会按住shift 点击连接(其实csdn的会自动打开一个窗口),这时候,是不是我早前打开的(但还没有被完成),是不是就会被终止呢???
0 请登录后投票
   发表时间:2004-08-24  
我也是觉得不太实用才说的....

其实我觉得用js在客户端控制刷新会更好一点(如果是解决刷新问题,不过这也只能用到浏览器特别有的api才行,我不知道还有没有其它的方法,如果有希望贴上).
0 请登录后投票
   发表时间:2004-08-24  
xiaoyu 写道
对了,我没有试过上面的例子(对不起,这点我很不对).

我想楼主应该试过的.是吗?

我想问,如果我是用同一个IE window,打开其它的几个不同的连接(shift  + click on link),情况会怎么样?
如果像dhj1所说的那样,通过对同一session的request的控制.
那么我说的其它几个连接就会被终止是吗?

例如:
假设置csdn采用了这种技术.
我看到csdn的头条新闻有好几条我没有看过,在等待的时候,我想把其它的几个也打开,就会按住shift 点击连接(其实csdn的会自动打开一个窗口),这时候,是不是我早前打开的(但还没有被完成),是不是就会被终止呢???


呵呵,我也没用过,只是看了他的源程序。我摘要的是他的核心思想,还有一些包括时间的控制我没有提到,其实我们都可以扩展,包括同时处理的Request数量,Request在保存队列中的最大允许数量(原来提到的是1,就是直接替换老request了)Request之间所允许的最小时差,等等。

我们可以控制特定时间内允许的用户最大请求数,其余的全部放到队列中(为了不抛弃用户的请求,我们可以允许一个比较大的队列),用户感觉基本是一样的,但是对服务器的意义就是不一样了,例如用户同时打开10个页面,但是真正在服务器端执行的只有5个,后面的5个会依次在前面的程序执行完执行,而如果等待超过2秒后无论怎样都执行。这些都是可以控制的。
0 请登录后投票
   发表时间:2004-08-24  
这个问题的解决办法是Core J2EE Patterns第二版的“Introduce Synchronizer Token”重构手法。一个“古而有之”的问题和解决方案。
0 请登录后投票
   发表时间:2004-08-25  
WebWork2自带的拦截器:
com.opensymphony.webwork.interceptor.TokenInterceptor
com.opensymphony.webwork.interceptor.TokenSessionStoreInterceptor
就是用来防止重复提交Action请求的。
“当用户关闭浏览器,如何kill掉服务器端为其执行的程序”我认为是实现不了的,服务器怎么会知道你关闭了浏览器?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics