You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by simon <sk...@apache.org> on 2008/08/30 13:34:44 UTC

Ajax+JSF functionality

Hi All,

I would appreciate some general "architectural" background on how ajax
libraries for JSF are implemented.

As I currently understand it, JSF ajax libraries use one of two ways of
generating an ajax response:

(a)
On the server, find a JSF component object that is the "base component"
for the response.

Then walk the JSF tree beneath the "base component" and builds a
response that contains just the *raw values* of the jsf components, NOT
HTML. In other words, normal rendering does not occur. The raw response
can be xml, JSON, or other format.

Then on the client, javascript walks the data returned by the response
and pokes it into the existing nodes in the html document object. Or
possibly creates new html document nodes based upon the response data.

(b)
On the server, find a JSF component object that is the "base component"
for the response.

Then run a normal rendering phase, generating html - but only for the
"base component" and its children. The result is an "html fragment", ie
html but not a complete page.

On the browser, an existing html node in the document is then replaced
with the html fragment from the server.


Questions:
* Is this right?
* Are there more solutions?
* Is there a good document online somewhere that describes this?
* which approach does Trinidad, Tomahawk, RichFaces (aka a4j) use?
* Does anyone know what approach NetAdvantage uses?

Thanks,
Simon



Re: Ajax+JSF functionality

Posted by Matthias Wessendorf <ma...@apache.org>.
Hi Simon,

some quick comments, inline;

On Sat, Aug 30, 2008 at 1:34 PM, simon <sk...@apache.org> wrote:
> Hi All,
>
> I would appreciate some general "architectural" background on how ajax
> libraries for JSF are implemented.
>
> As I currently understand it, JSF ajax libraries use one of two ways of
> generating an ajax response:
>
> (a)
> On the server, find a JSF component object that is the "base component"
> for the response.
>
> Then walk the JSF tree beneath the "base component" and builds a
> response that contains just the *raw values* of the jsf components, NOT
> HTML. In other words, normal rendering does not occur. The raw response
> can be xml, JSON, or other format.
>
> Then on the client, javascript walks the data returned by the response
> and pokes it into the existing nodes in the html document object. Or
> possibly creates new html document nodes based upon the response data.
>
> (b)
> On the server, find a JSF component object that is the "base component"
> for the response.
>
> Then run a normal rendering phase, generating html - but only for the

you mean the lifecycle, right ?

> "base component" and its children. The result is an "html fragment", ie
> html but not a complete page.
>
> On the browser, an existing html node in the document is then replaced
> with the html fragment from the server.
>
>
> Questions:
> * Is this right?

Trinidad does something that is close to (b).
Quick/raw notes:

-Trinidad has a PhaseListener (for now) that "installs" a
HttpServletResponseWrapper
(==> org.apache.myfaces.trinidadinternal.config.xmlHttp.XmlHttpServletResponse)
This is done BEFORE PhaseId.RESTORE_VIEW.

-The regular JSF lifecycle is executed and the "interesting" components render
(I think that is what you said with "The result is an "html fragment",
ie html but not a complete page.").
-The CoreRenderKit returns (when ajax) a PPRResponseWriter in
"createResponseWriter()".
-The responsewriter will renders some XML PIs, like:

<?xml version="1.0" ?>
<?Tr-XHR-Response-Type ?>   <=== basically, to mark our stuff :)

A complete ajax response looks like:


<?xml version="1.0" ?>
<?Tr-XHR-Response-Type ?>
<content action="/trinidad-demo/faces/demos/pprDemos.jspx">
<fragment>
  <![CDATA[<span id="itTarget" class="x0">Hello Simon K!</span>]]>
</fragment>
<fragment>
  <![CDATA[<span id="tr__idJsp1_Postscript">
  <input type="hidden" name="org.apache.myfaces.trinidad.faces.STATE"
value="!-746078bd">
  <input type="hidden" name="source"></span>]]>
</fragment>
<script>
  <![CDATA[TrPage.getInstance()._addResetFields('_idJsp1',["source"]);]]>
</script>
<script>
  <![CDATA[var _idJsp1_SF={};]]>
</script>
</content>


On the client there is an "ajax engine" that now replaces the bit.
Note this line in the above rich/ajax response:
<span id="itTarget" class="x0">Hello Simon K!</span>

the client lib looks for itTarget (document.getElementById()) and
replaces it (the <span> itself),
not the content. This is true for complexer components (like
laaaaaaaaaaaaaaaaaaarge tables)
as well.

@client lib (ajax engine):
we have quite a small little framework on the client.
A requestQueue submits back an ajax (XHR) postback (or IFrame, when
uploads are inclided),
etc. More documentation on the wiki, site would be cool.

> * Are there more solutions?

You could (in JSF 1.2 or like Tobago, via utils) have an optimized lifecycle.
The lifecycle would invoke the components lifecycle methods (processXyz())
only on "ajax" component (meaning those that are effected by the "ajax
postback").
This is possible via the invokeOnComponent(facesContext, ajaxClientId, callback)

Callback is different for the different Phases of the JSF Lifecycle, like
private class ProcessValidationsCallback implements ContextCallback
  {
    public void invokeContextCallback(FacesContext context,
                                      UIComponent target)
    {
      _LOG.fine("Running process validation on {0}", target);
      target.processValidators(context);
    }
  }

Oracle's ADF Faces RichClient uses such an optimized Lifecycle.
Apache MyFaces Tobgao does that as well (yeah, that lib is JSF 1.1 only,
but Volker/Börnd added some extra utils/callbacks.

Some other libs have an PhaseListener to NOT execute the lifecycle
and just write back the *response* (Tomahawk does that AFAIK).

> * Is there a good document online somewhere that describes this?
not that I know.
> * which approach does Trinidad, Tomahawk, RichFaces (aka a4j) use?
see above ;-)
I should create a (detailed) wiki page, containing diagramm etc.
That would be very good. A good resource as well.

Trinidad has a little user guide, that says something more, but really
impl details:
http://myfaces.apache.org/trinidad/devguide/ppr.html

-Matthias

> * Does anyone know what approach NetAdvantage uses?
>
> Thanks,
> Simon
>
>
>



-- 
Matthias Wessendorf

Need JSF and Web 2.0?
http://code.google.com/p/facesgoodies

further stuff:
blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
mail: matzew-at-apache-dot-org