Announcement Announcement Module
No announcement yet.
JSF and WebFlow Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • JSF and WebFlow


    Does anybody have already some experiences or ideas about using WebFlow together with JSF? We'd like to use WebFlow to describe the flow whereas the pages should be built with JSF components.


  • #2
    Flow for JSF

    Hi all,

    i am also more than interested in the integration of webflow into jsf. Heard that there should be an integration lib as work in progress???


    • #3
      JSF integration is a high priority for us, definitely.

      Neither Erwin or I are JSF experts, so we're certainly looking to work with some experts as part of this -- just like we did with Jose and Caesar on the Portlet integration.



      • #4

        what you think will be the benefit of integrating JSF into WebFlow? the only difference i think is that JSF are bundled with TagLibs but there are many TagLibs that do the same.

        or do you mean webflow support for JSF?


        mfg Gideon


        • #5
          JSF could be just another (component based) view technology. SWF can take care of the 'flow' responsabilities: what should happen when a button is clicked? Where (what page) do we need to go? ...

          So "integrating" just means: make it easy to use JSF as a view technology with SWF.



          • #6
            In some cases, I'd like to substitute the faces' flow control by web flow but still use JSF's component oriented web interface design mechanism. JSF itself doesn't know the notion of start and stop states, and therefore it can not verify that a flow starts at the correct state. Additionally it doesn't handle multiple submits or browsers back, forward and refresh buttons. Web flow seems to address all this limitations.

            On the other side, web flow dictates the flows' execution order in all cases, making it inappropriate to be used to describe general transitions between views on a "free flow" basis. IMO JSF flow and web flow complement each other providing means to express free flows as well as strictly guided flows.

            What are your feelings about that?
            or do you know any extensions to JSF that allow to define strictly guided flows as this is done in spring's web flow?



            • #7

              Your explanation makes al lot of sense to me. I don't know much about JSF (never used it IRL) so I can't really comment on it, but the way you explain it seems they complement each other very well indeed.



              • #8

                i have never used JSF, but looking into some books and on some Spring JSF examples. JSF looks onyle like a view technology with supports:

                rendering forms with good taglib support;
                validate forms;
                create a forms/site navigation.

                but by the way, jstl with spring taglib and display taglib etc. can do the same without having any configuration problems etc.

                so where is the benfit of using JSF (the display table is muc betten then jsf table etc)


                mfg Gideon


                • #9
                  Hi Gideon

                  JSF web interfaces are built by components. The idea is to compose pages just by dragging components from a palette to a web site (comparable to ASP.NET or VisualBasic GUI creation). Further, it standardises verification and conversion of input data, again using components. So JSF's strength is its component model (e.g. the synchronizer token can be implemented in a component and placed on pages where it's needed. You don't need to verify explicitly the tokens in your actions. This is done transparently by the component.).

                  But JSF's navigation model is limited in the sense that it doesn't address all the problems encountered in typical form series (wizards, see above). Web flow could do a great job here. Web Flow on the other side supports strictly guided flows only. A good JSF-web flow integration should provide both, JSF flows to do standard navigation and web flow for forms spanning over multiple pages.

                  btw: another JSF problem is the lack of good components and their abstraction in general. But both can be solved by writing new components.



                  • #10

                    ok i have read about this components, but at time for me the components are only a taglib. so the display taglibs are components too.

                    or do you mean that jsf is a taglib for a so called "visual studio" where you dont have to implement tha tags, because you can use drag and drop?

                    if it so, then i never use a gui (or something like Visual Studio) to code JSP JSF or simple HTML pages and so JSF have no benetif for me is this right?

                    mfg Gideon


                    • #11
                      In terms of experts...

                      I suggest:


                      I think first of all there are ideas here specifically regarding bean implementing actionlistener.

                      Based on that article do you guys have any ideas on integration?

                      I think the most simple place to integrate would be in classes like JstlView

                      JSFView, JSFJstlView, JSFTilesView and JSFJstlTilesView.

                      that then you could apply as the view resolver view class.

                      The challenge here I think is keeping the faces component tree in sync as you go through the flow and somehow hooking into web flow xml to resolve JSF actions rather than JSF built in navigation.

                      Basically as I understand it when going to a page the component tree would be created by FacesServlet in web.xml. I think that should be instead created by the view and stored in the session somehow delegating to the JSF classes that do it.

                      But I am no expert.... I think contacting the people on that page should get the integration off the ground.

                      Any ideas based on the article?


                      • #12
                        Of course it would be great if this works with portlets too.

                        Of course it would be great if this works with portlets too. :-)


                        • #13

                          Another very useful snippet of information. It appears to simulate FacesContext setup:



                          • #14
                            A more complete example



                            • #15
                              JSF Portlet integration problems....

                              I am running into a problem implementing JsfPortletView

                              Line here is failing with class cast.

                              facesContext = contextFactory.getFacesContext(portletContext, request, response, lifecycle);
                              I think this is occurring because
                              contextFactory is a portlet context factory because of jsf-portlet integration library.

                              request and response are not portlet compatible and hence class cast.

                              So either we've got to figure out a way to continue to use servlet context factory here or somehow convert servlet request and response into portlet request and response.

                              That's my 2cents... Any ideas?

                              Here is the code so far..

                              * Created on Apr 22, 2005
                              * TODO To change the template for this generated file go to
                              * Window - Preferences - Java - Code Style - Code Templates
                              package org.springframework.web.servlet.view;
                              import java.util.Map;
                              import javax.faces.FactoryFinder;
                              import javax.faces.component.UIViewRoot;
                              import javax.faces.context.FacesContext;
                              import javax.faces.context.FacesContextFactory;
                              import javax.faces.lifecycle.Lifecycle;
                              import javax.faces.lifecycle.LifecycleFactory;
                              import javax.portlet.PortletContext;
                              import javax.servlet.RequestDispatcher;
                              import javax.servlet.ServletException;
                              import javax.servlet.http.HttpServletRequest;
                              import javax.servlet.http.HttpServletResponse;
                              import org.springframework.web.portlet.context.PortletApplicationContext;
                              * @author jztb88
                              * TODO To change the template for this generated type comment go to
                              * Window - Preferences - Java - Code Style - Code Templates
                              public class JsfPortletView extends InternalResourceView {
                              * Render the internal resource given the specified model.
                              * This includes setting the model as request attributes.
                              protected void renderMergedOutputModel(
                              Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
                              // Expose the model object as request attributes.
                              exposeModelAsRequestAttributes(model, request);
                              // Expose helpers as request attributes, if any.
                              FacesContext facesContext = getFacesContext(request, response);
                              // you could just render the page here but since we are still in filter, it might be
                              // a better idea to forward to the actual page
                              // facesContext.getApplication().getViewHandler().renderView(facesContext, facesContext.getViewRoot() );
                              // Forward to the resource (typically a JSP).
                              // Note: The JSP is supposed to determine the content type itself.
                              RequestDispatcher rd = request.getRequestDispatcher(facesContext.getViewRoot().getViewId() );
                              if (rd == null) {
                              throw new ServletException(
                              "Could not get RequestDispatcher for [" + getUrl() + "]: check that this file exists within your WAR");
                              // If already included or response already committed, perform include, else forward.
                              if (useInclude(request, response)) {
                              rd.include(request, response);
                              if (logger.isDebugEnabled()) {
                              logger.debug("Included resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
                              else {
                              rd.forward(request, response);
                              if (logger.isDebugEnabled()) {
                              logger.debug("Forwarded to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
                              // You need an inner class to be able to call FacesContext.setCurrentInstance
                              // since it's a protected method
                              private abstract static class InnerFacesContext extends FacesContext 
                              protected static void setFacesContextAsCurrentInstance(FacesContext facesContext) {
                              private FacesContext getFacesContext(HttpServletRequest request, HttpServletResponse response) throws Exception {
                              // Try to get it first 
                              FacesContext facesContext = FacesContext.getCurrentInstance();
                              if (facesContext != null) return facesContext;
                              FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
                              LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); 
                              Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
                              PortletContext portletContext = ((PortletApplicationContext) getApplicationContext()).getPortletContext();
                              // Doesn't set this instance as the current instance of FacesContext.getCurrentInstance 
                              facesContext = contextFactory.getFacesContext(portletContext, request, response, lifecycle);
                              // Set using our inner class
                              // Determine the path for the request dispatcher.
                              String dispatcherPath = prepareForRendering(request, response);
                              // set a new viewRoot, otherwise context.getViewRoot returns null
                              UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, dispatcherPath);
                              return facesContext;