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

3 comments:

Santoshkumar said...

when i am implementing the filters in i am unable to get the tag in the portlet.xml that shows the following error..

cvc-complex-type.2.4.a: Invalid content was found starting with element 'filter'. One of '{"http://
java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd":portlet-preferences, "http://java.sun.com/xml/ns/
portlet/portlet-app_2_0.xsd":security-role-ref, "http://java.sun.com/xml/ns/portlet/portlet-
app_2_0.xsd":supported-processing-event, "http://java.sun.com/xml/ns/portlet/portlet-
app_2_0.xsd":supported-publishing-event, "http://java.sun.com/xml/ns/portlet/portlet-
app_2_0.xsd":supported-public-render-parameter, "http://java.sun.com/xml/ns/portlet/portlet-
app_2_0.xsd":container-runtime-option}' is expected.

Can you help out from this issue ...

Anonymous said...

The order of portlet.xml matters.
Make sure you follow this:

...
...


...


...

Anonymous said...

The order of portlet.xml matters.
Make sure you follow this:
1. portlet tag
and then close the portlet tag
2. now add the filter tag and then close it.

with this you will not get cvc-complex-type.2.4.a: Invalid content was found starting with element 'filter'.