Portlet filters

Since the release of JSR 286: Portlet Specification 2.0, it is possible to intercept and manipulate the request and response before they are delivered to a portlet in a given phase. Using Portlet filters you can block the rendering of a portlet if a specific condition occurs. Also, you can use portlet filters to decorate a request and a response within a wrapper to modify the behavior of the portlet.

Portlet filter usage

To use the portlet filter feature, you must first complete the following actions:
  • Implement one or more of the following interfaces of the javax.portlet.filter package:
    • RenderFilter
    • ActionFilter
    • ResourceFilter
    • EventFilter
    You must implement the appropriate filter based on the method or phase of the portlet that you want to filter.
  • Register the filter within the portlet.xml file for the portlets in your web application.
The following sample code illustrates a portlet filter to screen the processAction method of a portlet:
package my.pkg;

import java.io.IOException;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.filter.ActionFilter;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;

public class MyPortletFilter implements ActionFilter {
     public void init(FilterConfig config) throws PortletException {
          String myInitParameter = config.getInitParameter("myInitParameter");
          // ...
     }

     public void doFilter(ActionRequest request, ActionResponse response,
               FilterChain chain) throws IOException, PortletException {
          preProcess(request, response);
          chain.doFilter(request, response);
          postProcess (request, response);
     }

     private void preProcess(ActionRequest request, ActionResponse response) {
          //For example, create a javax.portlet.filter.PortletRequestWrapper here
     }

     public void destroy() {
          // free resources
     }
}
The following sample code illustrates how you can declare the previous portlet filter in the portlet.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" 
version="2.0" id="demo_app_id">
     <portlet >
          <portlet-name>MyPortlet1</portlet-name>
          <!-- [...] -->
     </portlet>

     <portlet >
          <portlet-name>MyPortlet2</portlet-name>
          <!-- [...] -->
     </portlet>

     <filter>
          <filter-name>PortletFilter</filter-name>
          <filter-class>my.pkg .MyPortletFilter</filter-class>
          <lifecycle>ACTION_PHASE</lifecycle>
          <init-param>
               <name>myInitParameter</name>
               <value>myValue</value>
          </init-param>
     </filter>

     <filter-mapping>
          <filter-name>PortletFilter</filter-name>
          <portlet-name>MyPortlet1</portlet-name>
          <portlet-name>MyPortlet2</portlet-name>
     </filter-mapping>

</portlet-app>
If you implement the RenderFilter interface, for example, add the <lifecycle>RENDER_PHASE</lifecycle> code to the filter section. This addition is analogous to the other filter interfaces. The following values are valid for the <lifecycle> parameter:
  • RESOURCE_PHASE
  • RENDER_PHASE
  • EVENT_PHASE
  • ACTION_PHASE

Global portlet filters

The portlet container for WebSphere® Application Server extends the portlet filter feature, which is provided by JSR 286, to allow you to register filters on a global level. These global filters apply to all portlets that are running within the portlet container, including both plain portlets and console modules.

To use global portlet filters, add the following code to the root folder of your Java™ archive (JAR) file or in the WEB-INF directory of your web application and name it plugin.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin id="portlet-filter-config" name="WS_Server" provider-name="IBM" 
version="1.0.0">

     <extension point="com.ibm.ws.portletcontainer.portlet-filter-config">

          <portlet-filter-config class-name="my.pkg.PortletFilter" order="22000">
               <description>Description of global PortletFilterImpl</description>
                    <lifecycle>ACTION_PHASE</lifecycle>
                    <lifecycle>EVENT_PHASE</lifecycle>
                    <lifecycle>RENDER_PHASE</lifecycle>
                    <lifecycle>RESOURCE_PHASE</lifecycle>
                    <init-param>
                         <name>MyInitParam1</name>
                         <value>MyInitValue1</value>
                    </init-param>
                    <init-param>
                         <name>MyInitParam2</name>
                         <value>MyInitValue2</value>
                    </init-param>
          </portlet-filter-config>
     </extension>
</plugin>
The order attribute of the portlet-filter-config element defines when in the filter chain to run the filter. The higher the value, the later the filter runs in the filter chain. Global filters are triggered before local portlet filters.
Avoid trouble:
  • Because global portlet filters are applied to all portlets within the container, when you call the FilterConfig#getPortletContext method within the init method the return value is null for global portlet filters.
  • Do not confuse this feature with the portlet document filters for WebSphere Application Server. Those portlet document filters are, technically speaking, servlet filters that you can apply to rendered output only. For more information about the portlet document filters, see the documentation about converting portlet fragments to an HTML document.
  • Because global portlet filters affect all portlets running in the given portlet container, the console modules that are contained in the Integrated Solutions Console are also filtered. It is important to test your filter implementation for undesired side effects on console modules or portlets. One approach is to test by checking the context path of the request in your filter logic.