General Requirements

      This issue describes the general requirements for supporting Ajax features that exist in JSF 2.0/2.1/2.2.

      Developers add Ajax functionality to their JSF applications via the <f:ajax /> AjaxBehavior. For example:

          <h:commandButton value="#{i18n['submit']}>
              <f:ajax execute="@form" render="@form" />

      ExternalContext and PartialViewContext Requirements

      In order for the FacesBridge to support Ajax, the bridge will need to satisfy the "portlet" requirements of the ExternalContext.encodePartialActionURL(String) JavaDoc found in the JSF API:

      Portlet:Returns an encoded URL that, upon HTTP POST, will invoke the RESOURCE_PHASE of the portlet lifecycle

      In addition, the FacesBridge will need to ensure that ExternalContext.getRequestHeaderMap() and ExternalContext.getRequestHeaderValuesMap() methods return values such that the "Faces-Request" header value can be obtained. This is required in order for PartialViewContext.isAjaxRequest() and PartialViewContext.isPartialRequest() to work properly.

      (For more information regarding the difference between these two methods, see the answer provided by BalusC to a related StackOverflow question)

      Unable to Depend on Request Headers

      The problem is that the Portlet 3.0 ResourceRequest.getProperty() method does not explicitly require the portlet container implementation to return the value of any particular request header. Because of this, the FacesBridge cannot rely on the presence of the "Faces-Request" header but must still be able to detect whether or not a ResourceRequest should invoke the JSF lifecycle.

      Proposed Solution to Lack of Request Headers

      The proposed solution to this problem is to add the following constants to the javax.portlet.faces.Bridge interface:
      public static final String FACES_AJAX_PARAMETER = "_jsfBridgeAjax";
      public static final String FACES_PARTIAL_PARAMETER = "_jsfBridgePartial";

      These constants represent request parameters that can be set on a javax.portlet.ResourceURL in order to inform the FacesBridge that the javax.portlet.ResourceRequest should invoke the JSF lifecycle. A value of "true" for the "_jsfBridgeAjax" request parameter would cause ExternalContext.getRequestHeaderMap().get("Faces-Request") to return a value of "partial/ajax". Otherwise, the value would be null. Similarly, a value of "true" for the "_jsfBridgePartial" request parameter would cause ExternalContext.getRequestHeaderMap().get("Faces-Request") to return a value of "partial/process". Otherwise, the value would be null.

      The Mojarra and MyFaces Core implementations of JSF do not make use of ExternalContext.isPartialProcess() and do not set the "Faces-Request" header to "partial/process". ICEfaces, PrimeFaces, and RichFaces do not set the "Faces-Request" header to "partial/process", although a search of their respective Java sources indicate that ExternalContext.isPartialRequest() is called on occasion. Finally, the JSF 2.2 Specification document does not specify requirements for setting the "Faces-Request" header to "partial/process".

      Therefore, the FacesBridge will be required to ensure that the "_jsfBridgeAjax" request parameter be set, but it will not be required to set the "_jsfBridgePartial" parameter.

      The FacesBridge will set the value of the "_jsfBridgeAjax" parameter when ExternalContext.encodePartialActionURL(String) is called. The return value is written to the "javax.faces.encodedURL" hidden field by the form renderer. The jsf.js library is required to use the value of "javax.faces.encodedURL" as the URL when dispatching an XmlHttpRequest.

      The requirements for Bridge.doFacesRequest(ResourceRequest,ResourceResponse) will need to be modified so that Ajax requests attach the Faces Flows "client window" and execute the entire JSF lifecycle: RESTORE_VIEW, APPLY_REQUEST_VALUES, PROCESS_VALIDATIONS, UPDATE_MODEL, INVOKE_APPLICATION, RENDER_RESPONSE.

      Head Resources

      FACES-2696 gave the FacesBridge the ability to integrate with the HEADER_PHASE of the Portlet 3.0 lifecycle in order to add resources to the <head>...</head> section of the portal page. Head resources would include children of the <h:head> component tag and resources with target="head". Special considerations will need to be made when resources that are not already in the <head>...</head> section of the portal page are added within the scope of an Ajax request.

      Other Considerations

      For JSF 2.0/2.1/2.2 requirements regarding Ajax redirects, see FACES-3035.

      For JSF 2.0/2.1/2.2 requirements regarding Ajax and Flash, see FACES-3034.

      For JSF 2.2 file upload Ajax via <h:inputFile>, see FACES-3009.

      For JSF 2.0/2.1/2.2 requirements regarding <h:head>, see FACES-2696.

      For JSF 2/0/2.1/2.2 requirements regarding <h:body>, see FACES-3040.

      TCK: encodePartialActionURLTest (specified in FACES-3075)

      TCK: partialViewContextIsPartialRequestTest (bridge-tck-main-portlet)

      • Similar test to encodePartialActionURLTest.
      • ExternalContext wrapper class @Overrides encodePartialActionURL and adds "_jsfBridgePartial=true" to the specified URL prior to delegating for encoding. Note that the overridden method should only add the parameter if the partialViewContextIsPartialRequestTest is the current test being run.
      • Test ensures that PartialViewContext.isPartialRequest() returns true.


          Issue Links



              neil.griffin Neil Griffin
              neil.griffin Neil Griffin
              Participants of an Issue:
              0 Vote for this issue
              1 Start watching this issue




                  Version Package