Using JSF 4 Portlets

Before reading this document you should take a look to the Getting Started Guide.

Basic Configuration

Because a JSF Portlet Application is a normal JSF Web Application we need to configure the Faces Servlet and the state saving method:

Faces Servlet

<web-app ...>

  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-name>server</param-name>
  </context-param>

  <servlet>
    <servlet-name>FacesServlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>

    <load-on-startup>0</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>FacesServlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>

</web-app>

Default Bridge Implementation

Configure the default bridge that will be used if a given portlet is not specified with another diferent implementation in the file WEB-INF/web.xml:

<context-param>
  <param-name>javax.portlet.faces.BridgeClassName</param-name>
  <param-value>net.sf.jsf4portlets.BridgeImpl</param-value>
</context-param>    

This context init parameter is useful when we have more than one implementation of the JSF Portlet Bridge in the classpath, so we need to specify which of the current implementations of the Bridge interface must be used by our portlets.

Basic Portlet Configuration

So, the last work is to configure the javax.portlet.faces.GenericFacesPortlet. This portlet will delegate all work to the bridge implementation. This portlet needs at least one init parameter so it can know the default viewId to be rendered when no viewId has been requested. Following there is an example:

<portlet-app ...>

  <portlet>
    <portlet-name>MyFacesPortlet</portlet-name>
    <portlet-class>
      javax.portlet.faces.GenericFacesPortlet
    </portlet-class>

    <init-param>
      <name>javax.portlet.faces.defaultViewId.view</name>
      <value>/welcome.jsf</value>
    </init-param>

    ...
  </portlet>

</portlet-app>

Advanced Configuration

Bridge Parameters

JSF portlets have the ability to preserve its action parameters during the render phase and to perform redirects againts the portal. This two features are disabled by default so they must be configured so portlets can take advantage of them.

If you want to configure this two features to every portlet in the same web application you must set the following in your WEB-INF/web.xml file. You can also specify these parameters in the WEB-INF/portlet.xml file as portlet init parameters.

Performing redirects againts the portal page:
<context-param>
  <param-name>javax.portlet.faces.ENCODE_REDIRECT_URL</param-name>
  <param-value>true</param-value>
</context-param>
Preserving action parameters

This attribute is used when we need access the portlet parameters which caused the current view to be rendered during the render phase. This parameters can be accessed using EL expressions like #{param.[param_name]}.

<context-param>
  <param-name>javax.portlet.faces.preserveActionParams</param-name>
  <param-value>true</param-value>
</context-param>

Portlet Render Policy

This is a special feature of the JSF Portlet Bridge. The render policy stablishes if the bridge should delegate rendering to parent view handlers. Delegation of the render operation depends of 3 different possible values:

DEFAULT
Renders the current view delegating the render operation to the parent ViewHandler. If this operation throws any exception, then the bridge will try to render the output by itself.
ALWAYS_DELEGATE
Always delegate the render operation to the parent ViewHandler. If this operation throws any exception, it should be caught by the GenericFacesPortlet and rethrown as a PortletException.
NEVER_DELEGATE
Never delegate the render operation to the parent ViewHandler. The bridge will always try to render the current view by itself.

The default behaivour is DEFAULT, if we need to change this, we must stablish a portlet init parameter like below:

<portlet>
  ...
  
  <init-param>
    <name>javax.portlet.faces.renderPolicy</name>
    <value>NEVER_DELEGATE</value>
  </init-param>
  
  ...
</portlet>

This feature allows retaining the natural order of non-Faces and Faces output when both exists in the same JSP file. Because JSR-168 doesn't allows request/response wrapping, we need to configure a servlet filter around the Faces' servlet like following:

<filter>
  <filter-name>Faces Portlet Render Filter</filter-name>
  <filter-class>javax.portlet.faces.BridgeRenderFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>Faces Portlet Render Filter</filter-name>
  <servlet-name>FacesServlet</servlet-name>
  <dispatcher>INCLUDE</dispatcher>
</filter-mapping>

Portlet Modes

JSF 4 Porlets supports portlets with standard portlet modes (VIEW, EDIT and HELP) and custom portlet modes. Every portlet needs to configure the VIEW mode as the default, EDIT and HELP modes are optional. Custom portlet modes must be defined in portlet.xml to become available.

Each portlet mode has a corresponding portlet init parameter so portlet can stablish the default viewId for the current portlet mode. When a portlet receives a PortletRequest for portlet mode which has not been configured, a BridgeDefaultViewNotSpecifiedException is thrown.

View
<init-param>
  <name>javax.portlet.faces.defaultViewId.view</name>
  <value>/view.jsf</value>
</init-param>
Edit
<init-param>
  <name>javax.portlet.faces.defaultViewId.edit</name>
  <value>/edit.jsf</value>
</init-param>
Help
<init-param>
  <name>javax.portlet.faces.defaultViewId.help</name>
  <value>/help.jsf</value>
</init-param>
Custom Portlet Modes
<init-param>
  <name>javax.portlet.faces.defaultViewId.[custom_portlet_mode]</name>
  <value>/custom.jsf</value>
</init-param>