Type: New Feature
Affects Version/s: None
This issue describes the general requirements for supporting Ajax features that exist in JSF 2.0/2.1/2.2.
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)
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.
The proposed solution to this problem is to add the following constants to the javax.portlet.faces.Bridge interface:
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.
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.
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
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.