JSF 2 provides a queuing mechanism out-of the box in order to sequence client side events with the built-in Ajax implementation. This queue is lacking in some very essential tuning options. The RichFaces a4j:queue provides these basic options in addition to other enhancements. There are two primary options available; 'requestDelay' and 'ignoreDupResponse'. These are explained more in the example below.
Many of the features of the RichFaces 3.3.X queue have been ported to RichFaces 4.0 version. However it is important to remember that the 4.0 queue is a logical queue on top of JSF's. There is only a single physical queue allowed and there is no way to override that (for now).
In this example you can tweak different queue options and see what effect that has on the number of events fired, and how often the DOM is updated. This provides a good way to learn about Ajax requests flood protection.
Attribute details:
<!DOCTYPE html> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich"> <rich:panel> <a4j:queue requestDelay="#{queueBean.requestDelay}" ignoreDupResponses="#{queueBean.ignoreDupResponces}" /> <h:form id="form"> <h:panelGrid columns="1" width="100%"> <h:panelGrid columns="2"> <h:outputText value="Type here:" /> <h:inputText id="myinput" value="#{queueBean.text}" onkeyup="addEvent();" disabled="#{not (facesContext.maximumSeverity==null)}"> <a4j:ajax onbegin="addRequest();" event="keyup" render="outtext" oncomplete="printCounts()" onbeforedomupdate="addUpdate()" /> </h:inputText> <h:outputText value="Repeated text:" /> <h:outputText value="#{queueBean.text}" id="outtext" style="font-weight:bold; word-break: break-all" /> <h:outputText value="Events count:" /> <h:outputText value="0" id="events" /> <h:outputText value="Requests count:" /> <h:outputText value="0" id="requests" /> <h:outputText value="DOM updates count:" /> <h:outputText value="0" id="updates" /> </h:panelGrid> <rich:message for="form:delay" style="color:red;" /> <h:panelGrid columns="2"> <h:outputText value="Request delay:" /> <h:inputText value="#{queueBean.requestDelay}" id="delay" converterMessage="Delay field should be a number (Demo input disabled till this resolved)"> <f:convertNumber integerOnly="true" /> </h:inputText> <h:outputText value="Ignore Duplicated Responces" /> <h:selectBooleanCheckbox value="#{queueBean.ignoreDupResponces}" /> <f:facet name="footer"> <h:commandButton value="Apply" action="#{queueBean.resetText}" /> </f:facet> </h:panelGrid> </h:panelGrid> </h:form> </rich:panel> <h:outputScript> var events = 0; var updates = 0; var outEvents = #{rich:element('events')}; var outUpdates = #{rich:element('updates')}; var outRequests = #{rich:element('requests')}; var requests=0; function addEvent(){ events++; } function addUpdate(){ updates++; } function addRequest(){ requests++; } function printCounts(){ outEvents.innerHTML=events; outUpdates.innerHTML=updates; outRequests.innerHTML=requests; } </h:outputScript> </ui:composition>
Queue scopes, and names:
You can define a queue so that it is the default queue for all requests from a complete view, a specific form, or even specific components.