Showing posts with label portletfilter. Show all posts
Showing posts with label portletfilter. Show all posts

Applying Global filter to all the portlets running in WPS

The WebSphere Application Server makes use of OSGi model for tying different pieces of application server together. One advantage of this approach is that even you can use the extension points to extend functionality of websphere application server

Before few days i was trying to build a Portlet Filter that can be applied to existing WebSphere Portlet Filter and Jerome suggested that i should use portlet global filter, that way i don't have to touch the existing portlet. So i tried that and it worked, to me it seems that Global Filter can be one of the most powerful tool in the portlet developers toolbox

I built this sample HelloGlobalFilter while i was trying to learn how to use Global Filter. This filter is very simple only thing that it does is calculate time spent in render() method of every portlet and prints that time along with WindowId, you can easily change it to create generic performance monitoring filter. You can download sample code from here

This is how my HelloGlobalFilter.java looks like

package com.webspherenotes.portlet.filter;

import java.io.IOException;

import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;

public class HelloGlobalFilter implements RenderFilter{
public void destroy() {
System.out.println("Inside HelloGlobalFilter.destroy()");

}
public void init(FilterConfig arg0) throws PortletException {
System.out.println("Inside HelloGlobalFilter.init()");
}

public void doFilter(RenderRequest request, RenderResponse response,
FilterChain filterChain)
throws IOException, PortletException {
System.out.println("Entering HelloGlobalFilter.doFilter()");
long beginTime = System.currentTimeMillis();
filterChain.doFilter(request, response);
System.out.println("Window ID " + request.getWindowID() +" Time to execute render() "
+ (System.currentTimeMillis() - beginTime));
System.out.println("Exiting HelloGlobalFilter.doFilter()");

}

}


Developing HelloGlobalFilter is like developing any other standard compliant Portlet Filter. In this case i am implementing RenderFilter interface and then inside the doFitler() method i am calculating time spent by the portlet in executing. Once the HelloGlobalFilter is developed i had to copy it in the shared library so that it can be accessed by portal across application.

Last step is to create plugin.xml file like this

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin id="com.webspherenotes.hello.filter" name="WS_Server"
provider-name="IBM" version="2.0.0">
<extension point="com.ibm.ws.portletcontainer.portlet-filter-config">
<portlet-filter-config
class-name="com.webspherenotes.portlet.filter.HelloGlobalFilter" order="100">
<description> Hello Global Filter, order = 101 </description>
<lifecycle>RENDER_PHASE</lifecycle>
</portlet-filter-config>
</extension>
</plugin>


In this case i am using com.ibm.ws.portletcontainer.portlet-filter-config extension point for injecting my custom HelloGlobalFilter. I want to apply the filter only to the RENDER_PHASE and that's the reason for value of lifecycle element. Copy the plugin.xml file in the root of the HelloGlobalFilter.

Getting name of the page where your portlet is getting rendered

Knowing name of the page where your portlet is getting rendered is one of the very common requirement, i know as per portlet specification your portlet should not be aware about where it is getting rendered but in reality there are requirements that portlet needs to behave differently based on the position where it is getting rendered.

The WebSphere Portal Server has concept of NavigationSelectionModel SPI that you can use to know about the current page.This SPI is used by the theme to know the page which should be displayed to the user. I built a PageNameFilter that makes use of the NavigationSelectionModel to find out where the page is getting rendered and passing it to the portlet as value of com.webspherenotes.filter.pageName request attribute, so that it works on both local portlet as well as cases when the portlet is getting consumed as WSRP (in case of WSRP, it will give you name of the page where portlet is getting consumed)


package com.webspherenotes.portlet.filter;

import java.io.IOException;
import java.util.Locale;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ibm.portal.ModelException;
import com.ibm.portal.content.ContentNode;
import com.ibm.portal.model.NavigationSelectionModelHome;
import com.ibm.portal.model.NavigationSelectionModelProvider;
import com.ibm.portal.navigation.NavigationNode;
import com.ibm.portal.navigation.NavigationSelectionModel;

public class PageNameFilter implements RenderFilter{
private static final Logger logger = LoggerFactory.getLogger(PageNameFilter.class);
public void doFilter(RenderRequest request, RenderResponse response,
FilterChain filterChain) throws IOException, PortletException {
logger.debug("Entering PageNameFilter.doFilter()");
String pageName = getPageTitle(request, response);
System.out.println("Page Name inside PageNameFilter " + pageName);
PageNameRenderRequestWrapper pageNameRequestWrapper = new PageNameRenderRequestWrapper(request);
pageNameRequestWrapper.setPageName(pageName);
filterChain.doFilter(pageNameRequestWrapper, response);
logger.debug("Exiting PageNameFilter.doFilter()");
}

private String getPageTitle(PortletRequest request, PortletResponse response){
try {
if (navigationSelectionModelHome != null) {
NavigationSelectionModelProvider provider =
navigationSelectionModelHome.getNavigationSelectionModelProvider();
NavigationSelectionModel model =
provider.getNavigationSelectionModel((ServletRequest)request, (ServletResponse)response);
NavigationNode navigationNode = (NavigationNode) model.getSelectedNode();
ContentNode contentNode = navigationNode.getContentNode();
if( contentNode.getObjectID().getUniqueName() != null){
logger.debug("The portlet is getting rendered on " + contentNode.getObjectID().getUniqueName());
}else{
logger.debug("The portlet is getting rendered on " + contentNode.getObjectID());
}
String pageTitle = contentNode.getTitle(request.getLocale());
if(pageTitle == null){
pageTitle = contentNode.getTitle(new Locale("en"));
if(pageTitle == null){
pageTitle = contentNode.getObjectID().getUniqueName();
if(pageTitle == null)
pageTitle = contentNode.getObjectID().toString();
}
}
return pageTitle;
}
} catch (ModelException e) {
logger.error("Error in PageNameFilter.getPageTitle() " + e.getMessage(),e);
}
return null;
}

private NavigationSelectionModelHome navigationSelectionModelHome;
public void init(FilterConfig filterConfig) throws PortletException {
try {
InitialContext context = new InitialContext();
navigationSelectionModelHome = (NavigationSelectionModelHome) context
.lookup(NavigationSelectionModelHome.JNDI_NAME);
} catch (NamingException e) {
logger.error("Error in PageNameFilter.init() " + e.getMessage(),e);
}
}
public void destroy() {
}
}


The PageNameFilter implements RenderFilter and in the doFilter() method it is passing control to getPageTitle method to get title of the page in the current locale or English. The getPageTitle, method is making use of the NavigationSelectionModel and callings its model.getSelectedNode() to first get the users current page and then reading the contentNode of the page from it.

I had to create PageNameRenderRequestWrapper that will override the actual RenderRequest and pass pageName as request attribute. This is how my PageNameRenderRequestWrapper looks like

package com.webspherenotes.portlet.filter;

import java.util.Enumeration;
import java.util.Vector;

import javax.portlet.RenderRequest;

public class PageNameRenderRequestWrapper extends javax.portlet.filter.RenderRequestWrapper{
private String pageName;
public static final String PAGENAME_ATTRIBUTE ="com.webspherenotes.filter.pageName";

public PageNameRenderRequestWrapper(RenderRequest request) {
super(request);
}

public Object getAttribute(String name) {
if(name.equals(PAGENAME_ATTRIBUTE)){
return pageName;
}
return super.getAttribute(name);
}

public Enumeration getAttributeNames() {
Enumeration originalAttributeEnum = super.getAttributeNames();
Vector wrappedEnum = new Vector();
while(originalAttributeEnum.hasMoreElements()){
wrappedEnum.add(originalAttributeEnum.nextElement());
}
wrappedEnum.add(PAGENAME_ATTRIBUTE);
return wrappedEnum.elements();
}

public String getPageName() {
return pageName;
}

public void setPageName(String pageName) {
this.pageName = pageName;
}



}


Inside the portlet you can read com.webspherenotes.filter.pageName request attribute to get name of the page where portlet is getting rendered

Query String Filter

Before couple of days i built a Getting Query String of portal URL from inside the portlet to demonstrate how you can read query string appended to the portal URL inside your portlet. That solution works by getting access to underlying HttpServletRequest object and reading query string from it. The QueryStringPortlet portlet developed in that blog entry works when accessed locally on the same portal server but it does not work if you consume that portlet on some other server using WSRP.

I built QueryStringFilter that will read the query parameters added to the portal URl and set them as normal render parameter, then i applied to the WSRP Proxy portlet and it works


import javax.servlet.http.HttpServletRequestWrapper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class QueryStringFilter implements RenderFilter{
private static final Logger logger = LoggerFactory.getLogger(PageNameFilter.class);
public void doFilter(RenderRequest request, RenderResponse response,
FilterChain filterChain) throws IOException, PortletException {
logger.debug("Entering QueryStringFilter.doFilter()");
HttpServletRequest httpServletRequest = getHttpServletRequest(request);
System.out.println("Request parameter map " + httpServletRequest.getParameterMap());
QueryStringRenderRequestWrapper queryStringRequestWrapper = new QueryStringRenderRequestWrapper(request,httpServletRequest.getParameterMap());
filterChain.doFilter(queryStringRequestWrapper, response);
logger.debug("Exiting QueryStringFilter.doFilter()");
}
public void destroy() {
}
public void init(FilterConfig filterChain) throws PortletException {
}
private HttpServletRequest getHttpServletRequest(PortletRequest request){
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
while(httpServletRequest instanceof HttpServletRequestWrapper){
HttpServletRequestWrapper httpServletRequestWrapper =
(HttpServletRequestWrapper)httpServletRequest;
httpServletRequest = (HttpServletRequest)httpServletRequestWrapper.getRequest();
}
return httpServletRequest;
}
}


The QueryStringFilter implements RequestFilter and in the doFilter() method i am reading underlying HttpServletRequest object and reading its parameters.

I also built this QueryStringRenderRequestWrapper that takes the query parameter from underlying HttpServletRequest object and forwards them as normal render parameter to the WSRP Proxy portlet


package com.webspherenotes.portlet.filter;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import javax.portlet.RenderRequest;
import javax.portlet.filter.RenderRequestWrapper;

public class QueryStringRenderRequestWrapper extends RenderRequestWrapper{
Map queryParameterMap ;
public QueryStringRenderRequestWrapper(RenderRequest request, Map queryParameterMap) {
super(request);
this.queryParameterMap = queryParameterMap;
}
public String getParameter(String name) {
System.out.println("Getparameter " + name);
String[] value = queryParameterMap.get(name);
System.out.println("Getparameter value " + value);
if(value != null)
return value[0];
return super.getParameter(name);
}
public Map getParameterMap() {
System.out.println();
Map oldParamMap = super.getParameterMap();
Map newParamMap = new HashMap();
Iterator oldParamIt = oldParamMap.keySet().iterator();
while(oldParamIt.hasNext()){
String paramName = oldParamIt.next();
String[] paramValue = super.getParameterValues(paramName);
newParamMap.put(paramName, paramValue);
}
Iterator queryParamIt = queryParameterMap.keySet().iterator();
while(queryParamIt.hasNext()){
String paramName = queryParamIt.next();
String[] paramValue = queryParameterMap.get(paramName);
newParamMap.put(paramName, paramValue);
}
return newParamMap;
}
public Enumeration getParameterNames() {
Enumeration oldParameters = super.getParameterNames();
Vector newParameter = new Vector();
while(oldParameters.hasMoreElements()){
String paramName = oldParameters.nextElement();
newParameter.add(paramName);
}
Iterator queryParamIt = queryParameterMap.keySet().iterator();
while(queryParamIt.hasNext()){
newParameter.add(queryParamIt.next());
}
System.out.println("Get parameterNames " + newParameter);
return newParameter.elements();
}
public String[] getParameterValues(String name) {
System.out.println("getParameterValues " + name);
String[] value = queryParameterMap.get(name);
if(value != null)
return value;
return super.getParameterValues(name);
}
}


The QueryStringRenderRequestWrapper class overrides RenderRequestWrapper and overrides its parameter related methods to inject some additional parameters that it got from the underlying HttpServletRequest

Debug/Log Portlet Filter

One of the nicest way to learn about how the portlet containers work is by looking at what type type of data is stored in PortletRequest and underlying HttpServletRequest, including data stored in PortletSession, HttpSession and PortletPreferences. So i built this DebugPortletFilter that you can copy in your project and apply to your portlet.

This Filter will be helpful even if your working with say a MVC framework like Spring Portlet MVC framework and your not sure about what request parameters or attributes are getting stored


package com.webspherenotes.portlet.filter;

import java.io.IOException;
import java.util.Enumeration;
import javax.portlet.PortletException;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DebugPortletFilter implements RenderFilter,ActionFilter,ResourceFilter{
private static final Logger logger = LoggerFactory.getLogger(DebugPortletFilter.class);
public void doFilter(RenderRequest request, RenderResponse response,
FilterChain filterChain) throws IOException, PortletException {
logger.debug("****************** Entering render phase *********************");
printPortletRelatedInfo(request);
printHttpServletRequestRelatedInfo(request);
filterChain.doFilter(request, response);
logger.debug("****************** Exiting render phase *********************");
}
public void doFilter(ResourceRequest request, ResourceResponse response,
FilterChain filterChain) throws IOException, PortletException {
logger.debug("****************** Entering resource phase *********************");
printPortletRelatedInfo(request);
printHttpServletRequestRelatedInfo(request);
filterChain.doFilter(request, response);
logger.debug("****************** Exiting resource phase *********************");
}
public void doFilter(ActionRequest request, ActionResponse response
FilterChain filterChain) throws IOException, PortletException {
logger.debug("****************** Entering action phase *********************");
printPortletRelatedInfo(request);
printHttpServletRequestRelatedInfo(request);
filterChain.doFilter(request, response);
logger.debug("****************** Exiting action phase *********************");
}

public void destroy() {
}

public void init(FilterConfig arg0) throws PortletException {
logger.debug("Inside DebugPortletFilter.init()");
}

private void printHttpServletRequestRelatedInfo(PortletRequest portletRequest){
logger.debug(" Information stored at HttpServlet level ");
HttpServletRequest httpServletRequest = getHttpServletRequest(portletRequest);
printHttpServletRequestParameter(httpServletRequest);
printHttpServletRequestAttribute(httpServletRequest);
printHttpSessionAttribute(httpServletRequest);
}
private void printPortletRelatedInfo(PortletRequest portletRequest){
logger.debug(" Information stored at portlet level ");
logger.debug( "Portlet Mode " + portletRequest.getPortletMode());
logger.debug( "Window State " + portletRequest.getWindowState());
logger.debug( "Window ID " + portletRequest.getWindowID());
printPortletRequestParameter(portletRequest);
printPortletRequestAttribute(portletRequest);
printPortletPreferences(portletRequest);
printPortletSessionInfo(portletRequest);
}
private void printPortletRequestParameter(PortletRequest portletRequest){
logger.debug(" Printing Portlet Parameters ");
Enumeration paramEnum = portletRequest.getParameterNames();
while(paramEnum.hasMoreElements()){
String paramName = paramEnum.nextElement();
String paramValue = portletRequest.getParameter(paramName);
logger.debug(paramName + " -> " + paramValue);
}
}
private void printPortletRequestAttribute(PortletRequest portletRequest){
logger.debug(" Printing Portlet Attributes ");
Enumeration attributeEnum = portletRequest.getAttributeNames();
while(attributeEnum.hasMoreElements()){
String attrName = attributeEnum.nextElement();
Object attrValue = portletRequest.getAttribute(attrName);
logger.debug(attrName + " -> " + attrValue );
}
}
private void printPortletPreferences(PortletRequest portletRequest){
logger.debug(" Printing PortletPreferences ");
PortletPreferences pref = portletRequest.getPreferences();
Enumeration prefEnum = pref.getNames();
while(prefEnum.hasMoreElements()){
String prefName = prefEnum.nextElement();
String prefValue = pref.getValue(prefName, "");
logger.debug(prefName +" -> " + prefValue);
}
}
private void printPortletSessionInfo(PortletRequest portletRequest){
logger.debug(" Printing PortletSession attributes ");
PortletSession session = portletRequest.getPortletSession();
Enumeration attribEnum = session.getAttributeNames();
while(attribEnum.hasMoreElements()){
String attrName = attribEnum.nextElement();
Object attrValue = session.getAttribute(attrName);
}
}
private HttpServletRequest getHttpServletRequest(PortletRequest request){
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
while(httpServletRequest instanceof HttpServletRequestWrapper){
HttpServletRequestWrapper httpServletRequestWrapper =
(HttpServletRequestWrapper)httpServletRequest;
httpServletRequest = (HttpServletRequest)httpServletRequestWrapper.getRequest();
}
return httpServletRequest;
}
private void printHttpServletRequestParameter(HttpServletRequest httpServletRequest){
logger.debug(" Printing HttpServletRequest parameter ");
Enumeration paramEnum = httpServletRequest.getParameterNames();
while(paramEnum.hasMoreElements()){
String paramName = paramEnum.nextElement();
String paramValue = httpServletRequest.getParameter(paramName);
logger.debug(paramName +" -> " + paramValue);
}
}
private void printHttpServletRequestAttribute(HttpServletRequest httpServletRequest){
logger.debug(" Printing HttpServletRequest attributes ");
Enumeration attrEnum = httpServletRequest.getAttributeNames();
while(attrEnum.hasMoreElements()){
String attrName = attrEnum.nextElement();
Object attrValue = httpServletRequest.getAttribute(attrName);
logger.debug(attrName + " -> " + attrValue);
}
}
private void printHttpSessionAttribute(HttpServletRequest httpServletRequest){
logger.debug(" Printing HttpSession attributes ");
HttpSession httpSession = httpServletRequest.getSession();
Enumeration attrEnum = httpSession.getAttributeNames();
while(attrEnum.hasMoreElements()){
String attrName = attrEnum.nextElement();
Object attrValue = httpSession.getAttribute(attrName);
logger.debug(attrName + " -> " + attrValue);
}
}
}


The DebugPortletFilter is implementing only RenderFilter, ActionFilter and ResourceFilter in all three methods it first prints all the portlet related information first and then it finds out the underlying HttpServletRequest object and prints the information related to it

You can apply the filter to your portlet by adding a filter declaration and mapping in your portlet.xml like this

<filter>
<filter-name>DebugPortletFilter</filter-name>
<filter-class>com.webspherenotes.portlet.filter.DebugPortletFilter</filter-class>
<lifecycle>RENDER_PHASE</lifecycle>
</filter>
<filter-mapping>
<filter-name>DebugPortletFilter</filter-name>
<portlet-name>DemoPortlet</portlet-name>
</filter-mapping>


Important Note Please be aware that the DebugPortletFilter generates huge amount of log information so use it only during development

Hello PortletFilter Sample

I built this sample Filter to demonstrate how you can use portlet Filter.

First i did create a simple HelloPortletFilterPortlet portlet like this.


package com.webspherenotes.jsr286.filter;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class HelloPortletFilterPortlet extends GenericPortlet{
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Inside HelloPortletFilterPortlet.doView()");
response.setContentType("text/html");
getPortletContext().getRequestDispatcher("hello.jsp").include(request, response);
}
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, IOException {
System.out.println("Inside HelloPortletFilterPortlet.processAction()");
}
}


The HelloPortletFilterPortlet portlet has doView() method that forwards control to hello.jsp for generating markup and processAction() method, that does not do any thing.

The hello.jsp is very simple only thing that it does is generate actionURL like this

<%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" session="false"%>
<%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<portlet:defineObjects />

<a href='<portlet:actionURL/>' >Action Request</a><br/>



Now next part is the interesting one HelloPortletFilter java, this is my Portlet Filter

package com.webspherenotes.jsr286.filter;

import java.io.IOException;

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

public class HelloPortletFilter implements RenderFilter, ActionFilter{
public void destroy() {
System.out.println("Inside HelloPortletFilter.destroy()");
}
public void init(FilterConfig filterConfig) throws PortletException {
System.out.println("Inside HelloPortletFilter.init()");
}
public void doFilter(RenderRequest request, RenderResponse response,
FilterChain filterChain) throws IOException, PortletException {
System.out.println("Before render() method");
filterChain.doFilter(request, response);
System.out.println("After render() method");
}
public void doFilter(ActionRequest request, ActionResponse response,
FilterChain filterChain) throws IOException, PortletException {
System.out.println("Before processAction() method");
filterChain.doFilter(request, response);
System.out.println("After processAction() method");
}
}


The HelloPortletFilter implements ActionFilter and RenderFilter, the ActionFilter, allows you to add filter for action phase and RenderFilter allows you to add filter for render phase. Similarly there is a ResourceFilter and EventFilter that you can use for adding filter to resource and event phase

Each of these filter interfaces have 3 methods

  • init() This method gets called with the FilterConfig object and portlet container will call it before calling doFilter() method of your filter, it gives you chance to execute initialization logic before your filter starts handling request

  • destroy() The destroy() method is executed at the end before filter is taken out of service and it gives you chance to cleanup resources opened by filter

  • doFilter() Even filter interface introduces a doFilter() method which request and response object corresponding to that phase. Ex. The RenderFilter has doFilter() method that takes RenderRequest and RenderResponse, where as ActionFilter has doFilter() method that takes ActionRequest and ActionResponse. In my sample code i am implementing both ActionFilter and RenderFilter so i have two separate doFilter() methods



In the doFilter() method for both action and render phase i am just writing few debug messages to the System.Out.

Last step is to attach the Filters to portlet in the portlet.xml

<?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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
<portlet>
<portlet-name>HelloPortletFilterPortlet</portlet-name>
<display-name>Hello PortletFilter</display-name>
<portlet-class>com.webspherenotes.jsr286.filter.HelloPortletFilterPortlet</portlet-class>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<portlet-mode>edit</portlet-mode>
</supports>
<portlet-info>
<title>Hello PortletFilter</title>
<short-title>Hello PortletFilter</short-title>
<keywords>Hello PortletFilter</keywords>
</portlet-info>
</portlet>
<filter>
<filter-name>HelloPortletFilter</filter-name>
<filter-class>com.webspherenotes.jsr286.filter.HelloPortletFilter</filter-class>
<lifecycle>ACTION_PHASE</lifecycle>
<lifecycle>RENDER_PHASE</lifecycle>
</filter>
<filter-mapping>
<filter-name>HelloPortletFilter</filter-name>
<portlet-name>HelloPortletFilterPortlet</portlet-name>
</filter-mapping>
</portlet-app>


The filter element declares name of the Filter class and the request phases that it wants to filter. In my case i want to filter render and action phase so i have two lifecycle element.

The filter-mapping element is used for mapping a filter to the portlet. In my sample code i am mapping HelloPortletFilter to the HelloPortletFilterPortlet

What is Portlet Filter

The Portlet Specification 2.0 has introduced concept of Portlet Filters similar to the Servlet filter, basic idea is Filters will get chance to execute some business logic before and after your portlet.

Portlet Filters can be used for implementing following type of functionality

  • The modification of request data by wrapping the request in customized versions of the request object

  • The modification of response data by providing customized versions of the response object.

  • The interception of an invocation of a portlet after its call



Even though the Portlet Filters try to copy the concept of Filters from Servlet Filters these are some of the main differences

  • The Servlet filters are mapped to particular URL, but since the Portlet Filters are not URL addressable, you will have to map filter to portlet

  • The Servlet life cycle has only one entry point which is service() method which calls either doGet, doPost based on HTTP method. In case of portlet the request processing can be divided into 4 types, render, action, resource and event and there is a separate filter for each of those types