HelloWorld Portlet on PlutoThe Portlet specification defines a portlet as a "Java-technology-based web component, managed by a portlet container that processes requests and generates dynamic content." That's not the easiest thing to understand, is it? This article will explain what portlets are and what they do.
Figure 1 shows what your browser will look like when you access a portal server.

Figure 1. Typical portal server content (click for full-size image)
If you take a closer look at the browser content, you will see that this page is made up of different "windows." There is one window for the weather update, another window for news, a third for a stock price update, and so on. Each of these windows represents a portlet. If you take closer look, you will find that each of these windows has a title bar and a few buttons, including minimize and maximize buttons.
Under the covers, these windows are different applications, developed independently of each other. The developer of the news portlet will create an application and pack it into a .war file. Then the administrator of the portal server will install this .war file on the server and create a page. In the next stage, every user will choose which applications he wants on his page. For example, if the user is not interested in stock updates but is interested in the sports update, he can replace his "Stocks Update" window with a "Sports Update" window.
Portlet technology requires learning a lot of new concepts, and it won't be possible for us to cover everything in one article, so we have split this article into two parts. In this part, we will define portals and portlets and develop a simple "Hello World" portlet. We will talk about a few more advanced topics in the next part.
We will use Apache's Pluto server--the reference implementation of the Portlet API 1.0 specification--for testing our sample portlets. We will also spend some time talking about how to install and use the Pluto server.
Figure 2 shows the various elements of portal page.

Figure 2. Elements of a portal page
Every portlet page is made up of one or more than one portlet windows. Every portlet window is made up of two parts: one is the decoration, which will decide how the title bar, controls, and borders of portlet windows will appear. The second part is the portlet fragment, which is the part contributed by the portlet application.
Your portal server decides the overall look and feel of the portal page, such as the logo, the colors of the title bars, the images for the controls, etc. By changing a few standard JSPs and .css files, you can change the complete look and feel of your portal. We will talk more about this in the "How a Portal Page is Created" section.
|
Related Reading Java Servlet & JSP Cookbook |
|
In order to understand what a portlet is, it is very necessary to understand what a portal is. According to the Portlet Specification, "a portal is a web application that commonly provides personalization, single sign on, content aggregation from different sources, and hosts the presentation layer of information systems. Aggregation is the act of integrating content from different sources within a web page."
Portal functionality can be divided into three main parts:
Single sign on: Allows you to get access to all other applications once you log into the portal server, meaning you don't have to log into every application separately. For example, once I log in to my intranet site, I should get access to my mail application, IM messaging application, and other intranet applications, without having to log into each of these applications separately.
A portal server will provide you with a secured credentials store. What you do is to go to the mail application and specify your user name and password once. This information will be stored in the credentials store in encrypted form. From the next time onwards, when you log into your intranet site, the portal server will read your credentials from the store and log into your mail server on your behalf. The same goes for other applications.
Personalization: The basic implementation of personalization service allows a user to customize her page in two ways. First, the user can decide what colors she wants for title bars and what icons she wants for controls. Second, the user can decide which portlets she wants on her page. For example, if I'm a big sports fan, I will probably replace the stock and news update portlets with a portlet that lets me track my favorite team.
There are also a few advanced commercial implementations of personalization services that allow you to decide which applications should be displayed to user based on criteria such as his income or interests. In this case, you can create some business rules like "Show the premium products portlet to any user with X amount of income" and "Show the discount deals portlet to users with Y amount of income."
There are a few more common services such as machine translation, in which case the portal server will take content generated by portlet in one language and machine translate it into a language requested by user. Most of the commercial portal servers provide access via handheld devices and are capable of generating different content for different browsers.
Similar to servlets, portlets are web components that are deployed inside of a container and generate dynamic content. On the technical side, a portlet is a class that implements the javax.portlet.Portlet interface and is packaged and deployed as a .war file inside of a portlet container.
Portlets are similar to servlets, in that:
Portlets are different from servlets, in that:
html/text, then all portlets should generate text/html content. On the other hand, if the portal server is asking for WML, then each portlet should generate WML content.
|
Portlets do provide some additional functionality.
Persistent storage for preferences: Portlets provide a PortletPreferences object for storing user preferences. These preferences are stored in a persistent data store, so they will be available across server restarts. As a developer, you don't have to worry about the actual implementation of how it is stored.
Request processing: Portlets provide much more refined request handling. A portlet may get a request when user takes some action on it (a state called action phase), or because the user took action on some other portlet and the page needs to be refreshed. A portal server provides different callback methods for handling both situations.
Portlet modes: Portlets use a concept of mode to indicate what user is doing. When using a mail application, you may be using it for reading, composing, or checking mail messages--this is the expected functionality of a mail application. Portlets normally provide this in VIEW mode. But there are other activities, like specifying a refresh time or (re-)setting the username and password. These activities allow the user to configure the behavior of the application, so they come under EDIT mode. Help functionality of the mail application comes under HELP mode.
If you think about it, you will find none of these represents new functionality. Instead, most of these are common business requirements. The only thing the portlet specification is doing is providing you one layer of abstraction, so that it will be useful for all stake holders end users, developers and administrators.
As a developer, I put all my business logic related to VIEW mode in a method called doView(), and I put business logic related to the configuration of my application in a doEdit() method, with help-related logic in a doHelp() method.
This makes it simple for an administrator to control access in the portlet application, because all he has to do is change access rights of the portlet to dictate what things a user is allowed to do. For example, a user of a mail application is supposed to specify his username and password in EDIT mode, so it makes sense for him to have access to EDIT mode.
But consider the case where I am the administrator of an intranet site and my company bought a third-party portlet application that displays news updates. This application allows a user to specify the URL from where it can retrieve updates. I want to use this application for displaying internal company news to users. Another requirement is that I don't want users to use this application for tracking any other news source. So as the administrator, I can specify the URL of an internal news update site for all users, and take out their edit privileges by changing the deployment descriptor of this portlet application.
Using portlets makes my website much more appealing to the end user because she will get a similar UI for all her portlet applications. If she wants to read help information about any of the applications, she can click the help button. She will also know that clicking on an edit button will take her to a configure screen for that application. Standardizing the user interface will make your portlet application more appealing.
Window state: The window state determines how much space should be given to content generated by a portlet on a portal page. If you click on the maximize button, the portlet will take up the entire screen and it will become the only portlet that will be available to the user. In minimized state, the portlet will be displayed as only a title bar. As a developer, you should customize your content based on the space available to you.
User information: Commonly, portlets provide content personalized to the user making the request. To do this effectively, they may require access to user attributes such as name, email, phone, etc. The Portlet API provides the concept of user attributes for this. A developer can access these attributes in a standard way, and it is the responsibility of the administrator to map these attributes to an actual user information repository (usually an LDAP server).
We will talk more about some of these features--request processing, user information, and portlet modes--in the second part of this series.
|
Now it is time to develop a sample HelloWorld portlet.
HelloWorld web project. Similar to a normal servlet project, it should have a /WEB-INF/web.xmlfile that will be the deployment descriptor of the project.HelloWorld.java file, like this:
public class HelloWorld extends GenericPortlet{
protected void doView(RenderRequest request,
RenderResponse response) throws
PortletException, IOException {
response.setContentType("text/html");
response.getWriter().println("Hello Portlet");
}
}
Every portlet should implement the Portlet interface. This interface defines the life cycle methods for a portlet. Since you don't want to override all of those methods, we will extend the GenericPortlet class, which is an adapter class implementing the Portlet interface. It provides default implementations of all life cycle methods, so we only have to implement necessary methods.
The only thing that we want to do in our HelloWorld portlet is to display "Hello Portlet." So we will override the doView() method of the GenericPortlet class. This method takes a PortletRequest and a PortletResponse as arguments. Call response.setContentType() first thing in the doView() method to inform the portlet container about what content type the portlet is going to generate--failure to do so will result in an IllegalStateException. Once the content type is set, you can get a PrintWriter from the response object and start writing into it.
<portlet>
<description>HelloWorldDescription
</description>
<portlet-name>HelloWorld
</portlet-name>
<display-name>Hello World
</display-name>
<portlet-class>com.test.HelloWorld
</portlet-class>
<expiration-cache>-1
</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW
</portlet-mode>
</supports>
<supported-locale>en
</supported-locale>
<portlet-info>
<title>Hello World</title>
<short-title>Hello World
</short-title>
<keywords>Hello,pluto</keywords>
</portlet-info>
</portlet>
The <portlet-name> element declares the name of the portlet. The <portlet-class> element specifies the fully qualified class name of portlet. The <expiration-cache> element specifies the time in seconds after which content is considered to be stale. This is a little bit more complicated than that: if you perform some action on the portlet, then new content will be generated, irrespective of cache time.
The <supports> element specifies which modes are supported for a given <mime-type>. In our example, we are saying that HelloWorld can only generate content of the text/html content type, and for the text/html content type, only the view mode is supported. If you decide to add support for other content types, then you should add new <support> elements and specify what modes are supported for that MIME type. It is very common for a portlet to have VIEW, EDIT, and HELP modes for text/html, and only VIEW mode for the WML MIME type.
You can also specify what locales the portlet supports by using the <supported-locale> element. The <title> element is used to specify a title for the portlet. If you want an internationalized title, then you can specify the name of the resources (i.e., a .properties) file using the <resource-bundle> element. In that case, the container will choose a title from the appropriate .properties file, based on the user's locale.
<web-app>
<display-name>Hello World Portlet
</display-name>
<welcome-file-list
<welcome-file>index.jsp
</welcome-file>
</welcome-file-list>
</web-app>
|
HelloWorld Portlet on PlutoPluto is in the early stages of development, so it does not have a set of easy-to-use administrative tools. In order to use the Pluto server, you will have to download both the binary and source versions. Please note that these instructions are for Windows; Unix users can get similar results by changing slashes and using .sh shell scripts rather than .bat batch files.
You are ready to access your Pluto server at http://localhost:8080/pluto/portal.
maven distribute:all.. This should build and download necessary dependencies required for running common admin tasks.
Now it is time to install our HelloWorldPortlet.war as a portlet.
maven.tomcat.home points to the Pluto binary installation. In our example, this will be maven.tomcat.home=C:/PlutoInstallation/pluto-1.0.1-rc1.maven deploy -Ddeploy=c:\PlutoInstallation\portlets\HelloWorldPortlet.war. You should get a "build successful" message.<servlet>
<servlet-name>HelloWorld</servlet-name>
<display-name>HelloWorld Wrapper</display-name>
<description>Automated generated
Portlet Wrapper</description>
<servlet-class>org.apache.pluto.core.PortletServlet
</servlet-class>
<init-param>
<param-name>portlet-class</param-name>
<param-value>com.test.HelloWorld
</param-value>
</init-param>
<init-param>
<param-name>portlet-guid</param-name>
<param-value>HelloPluto.HelloWorld
</param-value>
</init-param>
</servlet> <application id="5">
<definition-id>HelloWorld</definition-id>
<portlet id="1">
<definition-id>HelloWorld.HelloWorld</definition-id>
</portlet>
</application>
The <definition-id> of the application should be the name of the web application folder. The portlet's <definition-id> should be equal to the generated portlet-guid in web.xml.
<fragment name="p2" type="portlet">
<property name="portlet" value="5.1"/>
</fragment>shutdown and then startup. Now go back to http://localhost:8080/pluto/portal and click on "Test Link"--it should show our HelloWorld portlet.The right side of Figure 3 shows what your HelloWorld portlet will look like.

Figure 3. Screen shot of portlet screen (click for full-size image)
|
Figure 4 shows how the separate portlets are assembled by the portal container to create the page.

Figure 4. Portal page creation
Most portal servers are basically web applications deployed in an application server, using a servlet for handling requests to the portal server. If you take a look inside of your Pluto installation, you will find out that Pluto is a normal web application, deployed in your Tomcat server. Take a look at C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\web.xml and you will find that org.apache.pluto.portalImpl.Servlet is mapped to get all requests pointed at the Pluto server.
Earlier, in "Elements of a Portal Page," we said that a portal page is made up of two types of content. One is content generated by various portlets on the page, and other is content generated by portal server.
In Pluto, whenever the user makes a request, control will go to the servlet. Depending on what page is requested by user, it will determine a list of portlets that need to be displayed. Once it has this list, it will pass control to these portlets in different threads and will collect content generated by them.
As for content contributed by the portal server (things like look and feel of the portal site and the decoration and controls for each portlet), the portal server depends on JSPs in the C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\aggregation folder. RootFragment.jsp is the main JSP, which decides the overall look and feel, and alignment. It includes Heads to decide what should be included in the <HEAD> tag of the generated page. Then it uses Banner.jsp to choose what should be displayed in the banner--by default, it will include pluto.png for displaying the banner. TabNavigation.jsp is used to decide the navigation scheme of the portal site. What this means is that you just need to change a few JSPs in this folder to change the whole look and feel of your portal site.
Depending on settings in pageregistry.xml, Pluto will decide how many rows a page should have, and use RowFragment.jsp to render it. It will use ColumnFragment.jsp to render each column. Then PortletFragmentHeader.jsp is used to render the header of every portlet; i.e., the title bar and the controls for minimize and maximize. footer.jsp is used to render the footer of the JSP. If you look at the HTML generated by portal page, you will find out that every portlet window is nothing but content inside a <TD> tag.
For any new technology to be successful, it should have few qualities: first, it should leverage existing technology; second, it should solve common problems of existing technology; and third, it should provide you one more layer of abstraction. (As they say, every layer of abstraction solves half of the problems.)
The Portlet API has a very good chance of succeeding servlet technology, because it is capable of using the existing application server infrastructure. You can call an EJB from your portlet, or you can start and participate in a global transaction controlled by the application server. In other words, your portlet can do pretty much every thing that a servlet can do, in a much more business-logic-centric way.
Portlets provide you with a layer of abstraction because now you no longer have to worry about what HTTP method is used by the client, or create your own infrastructure to capture client events like button clicks. Last but not least, portlets solve most of the common problems of servlets by providing services for things like single-sign-on, personalization, etc.
Sunil Patil has worked on J2EE technologies for more than five years. His areas of interest include object relational mapping tools, UI frameworks, and portals.
Return to ONJava.com.
Copyright © 2009 O'Reilly Media, Inc.