Red Hat

RichFaces 4 Overview. Part I – Ajax Request Queuing.

Posted by Ilya Shaikovsky    |       |    Tagged as

About RichFaces 4 Overview

This series of articles is intended to give you a short overview of all the work we've done in extending JSF 2 with advanced features and components.

Core Ajax components

The first part of the RichFaces components migration process contained mostly the a4j library core components, which provide enhanced Ajax functionality. I believe that most of the community knows the base RichFaces Ajax components well and has worked with them for a long time. So basically there is not much to cover in this area. It should be easy to use them in the same manner as it was in RichFaces 3.3.x, but considering the JSF 2 Ajax definitions standards. The first article is intended to provide a short usage overview for them and to describe the RichFaces 4 Ajax requests queuing mechanism, which is designed for easy optimizations of your page/server transactions.

Why do we need them?

So let's start from the beginning. Why we need our Ajax components in a JSF 2 world where Ajax is standardized and provided out of the box in implementations? The answer is simple: JSF is an open standard which provides basic functionality leaving much place for customizations and extensions. They have taken many implementation ideas from RichFaces 3.x and other frameworks and added common base functionality into the JSF 2 standard. However, there are still many use-cases with which implementation requires additional work from a JSF 2 developer. RichFaces intends to provide extensions which will cover most of the features that are absent in JSF but required for real-world web applications.

Simple Ajax usage

Let’s explore the simplest Ajax repeater example in order to start with queuing functionality:

<h:inputText id="myinput" value="#{queueBean.text}">
	<a4j:ajax event="keyup" render="outtext"/>
</h:inputText>  
<h:outputText value="#{queueBean.text}" id="outtext"/>

In this sample, as you can see from snippet, an Ajax request will be generated for every keyup event in the input text and the ''outtext'' will be updated with the new value. If you start typing fast and look at the firebug console, for example, you will see numerous requests rise every time you type a letter.

Good news: JSF 2 provides an Ajax requests queue out of the box! So the frequent requests will not became concurrent, and will be sent one by one and processed in the right order.

But hey, I still need to reduce the requests count. In order to do that I still need to work manually with the timer, and to send my requests using the Ajax API as in the example shown at this article .

Good news again: the RichFaces Ajax requests queue solves the problem, and you can just specify the requests combining rules and pre-sending waiting time declaratively with the page tags.

Let's queue them

The next code snippet defines queue for form or view (depending on where defined):

<a4j:queue requestDelay="1500"/>

requestDelay specifies the time interval in milliseconds before the next request can be sent to server.

So now if we type without delays (or with delays smaller that 1.5 seconds) and then check the requests console, we will see that there is only one request with the latest information that was sent. RichFaces Ajax requests are grouped by using the requestGroupingId option, which is equal to the client id of the component that initiated requests(by default). It’s pretty simple and highly useful for such cases.

A more complex case. How do you group requests from different sources?

Now let's imagine the registration form which contains a few inputs which are validated via Ajax immediately after any changes. Using queue as shown above, a single request appears per input. But what if I don't want to send them at all while the user is entering information and validate the form only when he stops to check the result? It's still simple to do. We just need to add attachQueue with additional parameter passed to the queue:

<h:form>

<a4j:queue requestDelay="1500"/>

<h:inputText id="myinput" value="#{queueBean.text}">
    <a4j:ajax event="keyup" render="fooMessages" execute="@form">
        <a4j:attachQueue requestGroupingId=”registrationForm”/>	
    </a4j:ajax>
</h:inputText>  
<h:inputText id="myinput2" value="#{queueBean.text2}">
    <a4j:ajax event="keyup" render="fooMessages" execute="@form">
        <a4j:attachQueue requestGroupingId="registrationForm"/>	
    </a4j:ajax>
</h:inputText>  
</h:form>
Note: In RichFaces 4 we moved all queue related attributes (requestDelay, requestGroupingId, ignoredupResponse and so on) to a special attachQueue tag in order to keep the components itself cleaner.

The previous code could be rewritten to become much simpler, as we could use wrapping behavior instead of nested:

<h:form>
<a4j:queue requestDelay="1500"/>

<a4j:ajax event="keyup" render="fooId1" execute="@form">
    <a4j:attachQueue requestGroupingId="registrationForm"/>	

    <h:inputText id="myinput" value="#{queueBean.text}"/>
    <h:inputText id="myinput2" value="#{queueBean.text2}"/>
</a4j:ajax
</h:form>

That's it. Now requests from those inputs are similar from the RichFaces queue's point of view. If the user types fast among different inputs, only a single validation request for form will be raised after 1.5 seconds of inactivity. So now optimizing requests sent to the server becomes as simple as defining them!

What's next on our way

In next releases we plan to add full support of named queues and possible implementation of the 3.3.x ignoreDupResponces feature(not ready for now as we rely at JSF script during updates and can't skip the update currently). Also we will discuss possible benefits and implementation ways of logical queues - which will not just pass the request to common queue with additional parameters but preprocess them in local logical queue before.

Get more information and try it on your own with:
back to top