myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ernst Fastl" <ernst.fa...@gmail.com>
Subject Re: JSF and AJAX without custom components?
Date Tue, 05 Jun 2007 18:25:54 GMT
Hi Stan,

Thank you for the insights to your solution. It sounds very interesting
indeed. Hope we'll hear again from you on the list.

kind regards

Ernst

On 6/5/07, Stan Carney <stan.java.net@moohoffa.com> wrote:
> Thanks for your response Ernst!
>
> Yeah, I have looked around at pretty much every JSF AJAX framework out
> there and it isn't that I'm not impressed. There are definitely some
> smart people working to create generic components to be consumed by the
> masses. In our current position though I don't think these frameworks
> make a lot of sense for us to use. We have an extremely strong UI
> developer and we just want to be able to expose his talents, and in our
> current circumstance having to use pre-built AJAX components or having
> to create our own would severely hamper his abilities.
>
> So anyway I have solved my problem via the following process. It allows
> us to interact with JSF, i.e. forms, via AJAX without having to write
> components. It has some significant short comings if it was going to be
> used for general consumption by the JSF community (i.e. lacking
> configuration, you can shoot your foot off easily, etc...) but works for
> us. So keeping with good list etiquette I'm posting my solution below
> for those, if any, that get a hit on my initial question.
>
>
> I have created a PhaseListener that runs after the RESTORE_VIEW phase
> and checks for the presence of a known parameter. Every parameter on
> every request is checked which I'm not a fan of but from what I have
> seen most other JSF/AJAX solutions do the same and it appears to run
> super fast. If a 'known' parameter exists the PhaseListener instantiates
> the class associated with the parameter for processing. In my case all
> of these 'processor' classes implement a simple interface with one
> method, process(), that takes a CaseInsensitiveMap as an argument. This
> map contains the map returned value from the getParameterMap() method on
> HttpServletRequest:
>
> HttpServletRequest req = (HttpServletRequest)
> event.getFacesContext().getExternalContext().getRequest();
> CaseInsensitiveMap map = new CaseInsensitiveMap();
> map.putAll(req.getParameterMap());
>
> The process() method then does what it needs to do. Typically finding
> components by their ids in the restored view, that are either known by
> the class or sent as parameters, and updating their values accordingly.
> Then the class composes an XML document that our client side JavaScript
> (taconite and/or JQuery) understands and returns this XML string. The
> PhaseListener then determines if the returned string contains a
> javax.faces.ViewState placeholder we came up with and substitutes the
> placeholder with the new ViewState value generated below. If there is no
> placeholder, i.e. not interacting with a JSF form, we can omit the
> updating of the ViewState value. In that case though we typically do
> straight HTTP and bypass JSF completely.
>
>     try {
>             UIViewRoot viewRoot = context.getViewRoot();
>
>             StateManager stateMgr =
> context.getApplication().getStateManager();
>             ComponentSupport.removeTransient(viewRoot);
>
>             SerializedView serializedView =
> stateMgr.saveSerializedView(context);
>
>             Object[] savedState = new Object[3];
>             Object treeStruct = serializedView.getStructure();
>             if (treeStruct != null) {
>                 if (treeStruct instanceof String) {
>                     savedState[0] = treeStruct;
>                 }
>             }
>             savedState[2] = viewRoot.getViewId();
>             String viewState = StateUtils.construct(savedState,
> context.getExternalContext());
>
>             return viewState;
>         } catch (Exception e) {
>             throw new RuntimeException(e);
>         }
>
> The PhaseListener writes out the string to the response stream and marks
> the response as complete. The client JavaScript interprets the XML and
> updates the DOM. The DOM should now match the DOM stored on the server.
>
> It works well for us and results in the creation of only one class,
> after the initial PhaseListener creation, per Ajaxable event. The above
> code does tinker with the internal workings of MyFaces which may/will
> cause us issues on an upgrade. I haven't tested it for thread-safety yet
> but everything I have seen with other frameworks leads me to believe all
> is well.
>
> Thanks,
> Stan
>
>
> Ernst Fastl wrote:
> > Hi,
> >
> > I can understand you don't like to write your own component for
> > soving this problem (although seeing the stuff you posted I guess
> > you are skilled enough for that).
> >
> > Anyway, have you tried the
> > existing solutions like PPRPanelGroup from the tomahawk sandbox
> > or Ajax4JSF?
> >
> > regards
> >
> > Ernst
>

Mime
View raw message