Synchronizing on the session in a servlet filter is also how I'm doing
this. In my situation, there are synchronization issues beyond JSF,
like database access and other external resources.
I'm not concerned about it reprocessing the page twice. That
situation has to be solved even in non-parallel duplicate requests
(such as hitting the back button), and that's what tokens and such are
for.
Unresponsiveness might be a problem, but I'll have to address that at
a future point, if necessary. If so, it'll probably be handled by an
auto-refreshing page.
-Mike
On 11/9/05, Jeremy Green <[EMAIL PROTECTED]> wrote:
> On Wed, 9 Nov 2005 [EMAIL PROTECTED] wrote:
>
> > Hmm, I think the JSF spec has a flaw concerning this. The problem is not
> > the component itself, but the way the iteration is done. As e result you
> > are not allowed to:
> >
> > 1. bind the component to session or application scoped backing bean
> > 2. provide a session or spplication scoped DataModel
> >
> > Synchonizing access to session objects isn't that complicated, but
> > providing a thread-safe session scoped DataModel is really hard. Silmply
> > synchronizing isn't sufficent because UIData first sets the row for
> > processing and then retrieves the data. So you have to save the current
> > row for every thread. :(
> >
> > Alternatively you could return a individual DataModel for every thread
> > sharing the same data.
>
> I considered using database transactions to ensure that concurrent
> requests in the same session do not put data stored in the session into an
> inconsistent state, but decided it was overkill for my application.
>
> Instead, I used a Servlet filter that synchronized on the session object:
>
> public class SessionSynchronizationFilter implements Filter {
>
> public void doFilter(ServletRequest request,
> ServletResponse response,
> FilterChain chain) throws IOException, ServletException {
>
> HttpServletRequest httpRequest;
> HttpSession session;
>
> httpRequest = (HttpServletRequest) request;
> session = httpRequest.getSession();
>
> synchronized (session) {
> chain.doFilter(request, response);
> }
>
> }
>
> public void init(FilterConfig config) throws ServletException {
> }
>
> public void destroy() {
> }
>
> }
>
> While this should work in principle, I need to implement something closer
> to what Vesa Lindfors mentioned earlier in this thread, since double
> (multiple) submits are going to get queued up by this code, and the server
> is going to appear to be unresponsive if the requests take a significant
> amount of time to service.
>
> The following article and source code might be worth looking at for a more
> complete solution.
>
> http://www.onjava.com/pub/a/onjava/2004/03/24/loadcontrol.html
>
> I say "should work" above, since I still get "Cannot forward after
> response has been committed" errors even with this filter in place.
>
> Jeremy
>