如何在呈现响应之前处理多个提交? [英] How to handle multiple submits before response is rendered?

查看:60
本文介绍了如何在呈现响应之前处理多个提交?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据测试报告,如果响应速度不够快,有时可能会多次按下一个按钮,从而导致多次调用我们不希望的后端代码.

It has been reported from testing that it is occasionally possible to press a button more than once if the response is not rendered fast enough, causing several invocations of the back-end code, which we do not want.

应用程序是在Glassfish 3.1.1中使用JSF 2.0的Java EE 6 Web Profile.

Application is Java EE 6 Web Profile using JSF 2.0 inside Glassfish 3.1.1.

我想知道应该如何正确处理该问题,并想到了以下几种情况:

I was wondering how this should be properly dealt with, and have thought of a few scenarios:

  • 在呈现响应时,提交应禁用所有使用javascript的按钮.
  • Session范围中的一个标记,表明它已经处于活动状态,因此跳过了敏感代码,仅继续重新呈现上一次提交的响应.
  • 一个同步块将处理延迟到上一个请求完成为止.然后应该检测到它已经被处理并跳过了.
  • 使用诸如转换之类的新"范围之一来处理检测吗?

我的直觉是,最好的方法是使敏感代码块成为原子,但是问题在于呈现正确的响应.

My immediate gut feeling is that the best approach is to have sensitive code blocks atomic, but then the problem is with rendering the correct response.

我应该如何处理?

推荐答案

在呈现响应时,提交应使用javascript禁用所有按钮.

这是最简单的通用方法.如果碰巧专门使用<f:ajax>,则可以使用jsf.ajax.addOnEvent()以通用方式执行作业.一种替代的JavaScript方法是创建一种加载"叠加层,该叠加层会阻止UI,以便最终用户不再能够与基础页面进行交互.这基本上是一个绝对定位的隐藏<div>,它以opacity(透明度)跨越整个视口.您可以在提交时显示它,而在渲染时隐藏它.此技术的关键字是模式对话框" .面向UI的JSF组件库至少已经有这样的组件.例如. PrimeFaces 放在 <p:blockUI>

This is the easiest to implement in a generic manner. If you happen to use <f:ajax> exclusively, you could use the jsf.ajax.addOnEvent() to perform the job in a generic manner. An alternative JavaScript approach is to create kind of an "Loading" overlay which blocks the UI so that the enduser won't be able to interact with the underlying page anymore. This is basically an absolutely positioned hidden <div> which spans the entire viewport with some opacity (transparency). You could show it on submit and hide it on render. The keyword for this technique is "modal dialog". UI-oriented JSF component libraries have at least such a component already in their assortiment. E.g. PrimeFaces with a <p:dialog modal="true"> inside a <p:ajaxStatus>, or the <p:blockUI>

唯一的缺点是,如果客户端禁用了JS或不使用JS,它将无法正常工作,因此不会阻止HTTP客户端重复提交.

The only disadvantage is that it won't work if the client has JS disabled or don't use it and it thus won't prevent HTTP clients from double submits.

Session范围中的一个标记,表示该标记已经处于活动状态,因此将跳过敏感代码,而仅继续对先前提交的响应进行重新呈现.

这被称为同步器令牌模式" 规格问题559 曾被请求用于JSF,目前该票据已针对2.2,但似乎没有任何活动.检测和阻止部分在技术上易于实现,但是如果您希望最终用户最终检索由初始请求生成的响应,那么同步响应处理部分就不容易实现.异步响应处理很容易:只需不指定要更新的任何组件即可,即清空PartialViewContext#getRenderIds()返回的集合.毕竟,这比使用JS禁用按钮或阻止UI更为可靠.

This is more known as "synchronizer token pattern" and has ever been requested for JSF by spec issue 559 which is currently on the ticket targeted for 2.2, but there doesn't seem to be any activity on it. The detection and blocking part is technically easy to implement, but the synchronous response handling part is not easy to implement if you want that the enduser ultimately retrieves the response as generated by the initial request. The asynchronous response handling is easy: just don't specify any components to update, i.e. empty the collection as returned by PartialViewContext#getRenderIds(). After all, this is more robust than using JS to disable the buttons or block the UI.

据我所知, Seam 2 是唯一为此提供可重用的JSF组件的 <s:token> .但是,我必须承认,对于新的 OmniFaces 组件,这是一个有趣的想法.也许我会亲自看看.

As far as I know, Seam 2 was the only who offered a reuseable JSF component for this, the <s:token>. I must however admit that this is an interesting idea for a new OmniFaces component. Maybe I will personally take a look at it.

一个同步块,将处理延迟到上一个请求完成为止.然后应该检测到它已经被处理并跳过了.

通常这不容易实现,这将需要更改所有操作方法以检查作业是否已经完成.如果该Web应用程序在多台服务器上运行,它也将不起作用.同步器令牌更容易,因为它将在调用操作方法之前执行.同步令牌也更便宜,因为您不会在队列中遇到多个请求,而这只会消耗线程/资源.

This is not easy to implement generically, this would require a change in all action methods to check if the job is already done. It also won't work if the webapp runs on multiple servers. A synchronizer token is easier as it would be performed before the action methods are invoked. A synchronizer token is also less expensive as you don't end up with multiple requests in the queue which would only cost threads/resources.

使用诸如转换之类的新"范围之一来处理检测吗?

不能通过使用托管bean范围来解决此问题.托管Bean范围具有不同的用途:Bean实例的生存期.

This problem cannot be solved by playing around with managed bean scopes. Managed bean scopes serve a different purpose: the lifetime of the bean instance.

这篇关于如何在呈现响应之前处理多个提交?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆