Ajax4jsf
Architecture Overview
Introduction
Benefits of Using
For Application Developers: - Production quality Open Source
- Does Open Source and has an Open Architecture
- Compatible with any JSF Implementation - MyFaces?, JSF1.1, JSF1.2
- Allows to Ajaxify JSF application without writing Javascript
- Works with standard and third party components
- Adds the Ajax capability to existing non-Ajax components
For Component Developers:
- Ajax4jsf is Open Source and has an Open Architecture
- Gives an API to create components with built-in Ajax support
- Has a Component Development Kit for rapid development
- Allows to skinning the look-n-feel using both CSS and set of skin-parameters
- Automatically generates the unit test-cases for developing components
- Allows to pack javascript code, images, css inside the final jar
Key Definitions
Ajax View
Root
Ajax4jsf extends the View Root. The custom View Root plays
a role of trigger for ajax and non-ajax request. During the regular non-Ajax
request or list of the active regions is empty, the custom View Root delegates
functionality to the default View Root. Otherwise, Ajax4jsf processes only the
active region. I.e. invokes decode/validation/mode update only on the defined
region
Ajax View Handler
Ajax View Handler is wrapper for the default View Handler. It enhances the
behaviour of the default one in case of Ajax requests. Specifically, it does
the following:
-
checks the session is expired. if so, form the special response with
warning. Developer can provide the own client side behaviour using a
javascript API.
-
just before rendering (in the renderView method) initiates the delivery of
the AjaxEvent
-
checks if Ajax Container is configured for rendered from the component tree
(with selfRendered flag). If so, skip the further rendering of the
page, but renders right from the component tree
-
stores the status marker in the Ajax Context. The marker will be
include tin the response in the XML Filter
-
convert the resource request defined with the resource:// prefix
inside the JSF component attributes into the specific resource calls
Ajax
Component
Ajax components are the components that trigger
Ajax
requests. They belong to the
UICommand
component family. So, Ajax components produce the same behavior that any other
UICommand
components on the server side.
Additionally,
they point to the area of the view that should be re-rendered when
the the Ajax response comes. The examples of the Ajax Components are
a4j:commandButton, a4j:commandLink, a4j:poll, a4j:support.
a4j:support is most typical Ajax component. It is used to add Ajax capability
to existing standard and third party non-Ajax components
[ ]
Ajax
Context
Ajax Context keeps the Ajax related information about the actual Ajax request
such as the active Ajax container,
the
component to be re-rendered, list of clientIds rendered components , list
of Javascript code to be included. Ajax Context has several public methods that
allows developers to get information about the Ajax request.
Ajax
Container
Ajax4jsf allows to process only part of the component tree instead of the whole
one. Ajax Container is a local View Root for the Ajax request processing. On the
page level, the active area is defined with the a4j:region tag. When Ajax
request is triggered, the Ajax Component adds the Ajax flag to the request
parameter list. This flag contains the reference to the local region to be
processed. On the server side, Ajax View Root analyzes this flag and delegates
the processing to the referenced Ajax Container.
The a4j:region components might be nested. If no one region presents on the
view, the whole View Root becomes a region.
By default, Ajax Container limits the area to be re-rendered. Increasing the
performance is a major motivation for such limitation. However, developer can
set renderRegionOnly to false if she wants to re-render something outside of the
region.
Ajax Output
Ajax Output allows to mark the area of the View that might be re-rendered by own
flag (ajaxRendered) additional to be referenced explicitly with reRender
attribute. On the page, Ajax Output is represented with a4j:outputPanel tag. In
most cases, using Ajax Output is optional as far as Developer can be reference
to any component id directly.
For the simplicity reason, Ajax4jsf only replaces the existing nodes in the
component tree, but does not insert them. So, using the Ajax Output for wrapping
such nodes is a most common use-case. For example,
<a4j:outputPanel ajaxRendered="true">
<h:messages />
</a4j:outputPanel>
|
< .... reRender="panel">
....
<a4j:outputPanel layout="none">
<h:panelGrid id="panel" rendered="#{foo.bar}">
.....
</h:panelGrid>
</a4j:outputPanel>
|
Ajax Listener
Ajax Navigation
Ajax4jsf allows to reuse the standard JSF navigation defined
in the JSF configuration file. If the action method returns a string
outcome and this outcome match the navigation rule, Ajax4jsf renders the whole
new view and sends it back to the client. Ajax4jsf replaces the whole document
with the new one.
If the action method outcome does not match any navigation rule or action method
does not invoke at all, for example, in case of Validation phase is failed,
Ajax4jsf performs the regular Ajax behaviour. I.e. renders and send to the
client only the area marked for re-render. Therefore, the common scenario for
using Ajax Navigation might be the form submission with invoking the server side
navigation, but without the whole page refreshing. If validation is failed, only
the area with error message will be re-rendered. Otherwise, the navigation
performs and user will see the next page.
Ajax4jsf allows to use the standard JSF navigation not only for replacing the
whole page, but only part of it. The common scenario is organizing the wizards
inside the page. Ajax4jsf has a special component that is used for this purpose.
It is ui:include. If the Ajax Component is located inside the ui:include
component hierarchy and action method returns matched with navigation rule
outcome, only the part of the page is replaced. See description for ui:include
below for more details.
Ajax Filter
Ajax4jsf requires the Ajax Filter to be register in the project descriptor file
(web.xml). Ajax Filter does the following:
-
Sets response type to text/xml in case of Ajax Response
-
Inserts references to the Javascript code and CSS used by components. The
list of the references are prepared by Ajax View Handler earlier during the
Render Response Phase.
-
Corrects and converts the HTML to the well-formatted XHTML
-
Calls the resource generator if the request for getting the resource
(Javascript, CSS, images, pdf and so on)
-
replaces the markers with their actual values
-
inserting some service information (State, )
Browser required to have a well-formatted XHTML, because it does not do the
correction of the code during the direct inserting to the DOM tree . Ajax4jsf
does the corrects on the server side in the Ajax Filter. By
default, Ajax filter always does the correction to avoid problems with different
interpretation of the same code during the Ajax and non-Ajax requests. However,
the developer can set 'forceparser' to false as a Filter configuration parameter
to turn off the correction during the non-Ajax requests. This might be helpful
if developer does not want to spend time to correct the part of the HTML that is
not going to be in the Ajax re-rendered areas.
By default, the Tidy code-base is used in the filter to correct html code. The
other option is using the filter that is based on the Nekko code-base. This
filter does not correct anything except inserting TBODY to the table is it is
missing. This filter works faster, but missing the HTML corrections might causes
the visual defect on the client side and developer should care about it by
herself.
Ajax
Queries Queuing
Ajax4jsf allows to queue the Ajax events. The feature is enabled with defining
the eventsQueue attribute explicitly defined.The requestDelay attribute defines
the delay before the request pushed in the queue is sent. The queuing is a
page-wide feature. So, developer can define the same queue name for the
different Ajax components on the same page.
Ajax4jsf has a protection against the unnecessary Ajax request that might cause
a request flood on the server. The good example is a suggest box use case when
user does not expect that server will response with suggestion for the earlier
typed characters if she already typed the next ones. Ajax4jsf removes all the
similar requests from the request queue and sends only the latest one. The
similarity is based on the two parameters: the queue name and the event
name. If the similar event is already in the queue, the request is not
sent but deleted.
Additional Ajax Component's attribute ignoreDupResponses allows to avoid the
Ajax response triggered by the similar Ajax request if the newest Ajax request
is already in the queue. I.e. the defined eventsQueue allows to remove the
similar event, but ignoreDupResponses allows to ignore the response on the
similar event if the request is sent already. ignoreDupResponses is a client
side functionality. It does not stop or rollback the server side behaviour
anyhow.
Ajax Processing Cycle
Non-Ajax
Response
Additional to the regular JSF implementation behaviour during the non-Ajax
request-response, Ajax View Handler analyzes the tree structure and create the
list of the Ajax regions. Also, Ajax View Handler marks the components which use
javascript insets to move those insets to the header later in the Ajax Filter.
By default, the non-Ajax response passes though Ajax Filter. Developer might
disable this with setting the forceparse initial parameter for the Ajax filter
to false.
For non-Ajax responses the Filter:
-
moves the javascript insets marked by the Ajax View Handler to the header
section of the page
-
repairs the incorrect HTML code. The strictness of this correction depends
of the filter type and configuration parameters for them
Ajax Request
On the client side, Ajax Component invokes A4J.AJAX.Submit javascript method to
perform an Ajax request. Ajax request is similar to the standard JSF request.
Additionally to the request parameter map based on the JSF form, Ajax4jsf send
one more parameter with name "ajaxrequest" that contains value of the client id
of the local Ajax Region
Ajax Component can has ajaxSingle attribute set to true. In this case,
request parameter list will contains only the value of the Ajax Component (or
its parent component value if it is a a4j:support), but not the whole form
fields. The request parameter map also contains the "ajaxrequest" and the State
Data in case of using the client side state saving method.
Ajax
Decoding
Ajax View Root checks the "ajaxrequest" request parameter and
if point to the Ajax Region, the decoding performs only for this part of the
component tree. Otherwise, the decode is invoked on the View Root
itself.
Decoding only the part of the component tree allows to increase the performance
and avoiding performing the validation, conversation and update model for the
form element updating with the Ajax Request
Event Handling
Ajax4jsf uses the standard JSF Lifecycle. So, all possible standard events, such
as Value Changed and Action events are brodcasted and fired as in the regular
JSF postback request.
Adiitionally, Ajax4jsf brodcasts the special
AjaxEvent to the active Ajax
Region and the Ajax Component that fires the Ajax Request. This event is
scheduled to be received before the Render Response phase
Ajax Response
Ajax Response is formed by the Ajax View Handler on the
RenderResponse? phase.
Ajax View Handler iterates through the list of component ids that include:
-
components referenced by Ajax Component reRender attribute;
-
Ajax Output areas that are marked to refreshed by the own ajaxRendered flag.
There are two strategies how the response is generated. The stratagy is switched
by the selfRendered flag on Ajax Region.
If selfRendered flag is set to true, Ajax View Hander walk though the
nodes starting from the required for re-rendering ids on the existing component
tree and invokes the renderers for them. With this rendering strategy, the
component tree and its parts is not recreated. This allows to increase the
performance, but requires to avoid to use transient components including non-jsf
stuff. If so, they will be missed in the result page update.
If selfRendered flag is set to false (default value), Ajax View Handler find and
invokes the renderes for each component from the list. It causes recreating
those part sof the component tree and invoking the standard JSF rendering
mechanism
The results of the components rendering is formed as a response package that
includes rendered code and corresponded components ids. Also, it includes the
new state data and data for javascript code. If on the Invoke Application phase
the action method returns non-null string and this string matches one of the
navigation rule, the viewId is changed and Ajax4jsf does not iterates though the
list, but re-renders the whole view. This result of rendering is included in the
response. In case of using a4j:include, the coresponded id is set to id of the
include. Otherwise, it is set to the root of the component tree
Response Code Filtering
The response package are comming though the Ajax Filter that:
-
sets "text/xml" as a response mime-type
-
converts the renderers result to the well-format xml
Also, Ajax Filter detects if the response contains redirect instruction. If so,
it forms the special redirect package with nessesary information for client to
process the redirect
Response
Completion
The Ajax4jsf client part is based on the Sarissa javascript library codebase.
When the respose package is arrived, it is checked for redirect or the
navigation flag is set.
If is it a partual page update, the javascript code:
-
looks for references to the external javascript or CSS. If they exists they
are added to the document
-
processes the list of the client ids from the response package. For each
client id, Ajax4jsf looks the corresponded node in the document DOM. If it
exists the DOM node content is replaced with the new one.
-
looks for <script> tags inside the updated DOM nodes. If found those
scripts are launched.
-
replaces the state data in the each form available on the page
-
calls the oncomplete methods on the Ajax Component that fire the Ajax
request
-
checks the Ajax Query Queue. If it contains other request to process,
Ajax4jsf process the next event from the queue
Extra
Features
Skinability
Resource Management
Component Development
Kit
GWT-JSF Integration
-- Main.edburns - 21 Dec 2006