Prerequisites
- Working installation of JBoss AS and Eclipse. If you do not, check out Installing and Configuring JBoss AS.
- Working knowledge of:
- Java
- XML
- Eclipse
The Project
First, we will start by creating a new project called: HelloWorldPortletApp in Eclipse.
- Go to File > New > Project... This will open the New Project Wizard.
- Expand the 'Web' tree and select 'Dynamic Web Project'. Click Next.
- For the project name, type in HelloWorldPortletApp and click Finish.
The Portlet
We now have our project, but we cannot continue till we have our libraries added. If the user libraries have not been created, please read the corresponding section in Installing and Configuring JBoss AS. To add the libraries to our project:
- Right click on the project in the hierarchy and go to Build Path > Configure Build Path...
- Click on 'Add Library' and select 'User Library' from the menu. Click Next.
- Check mark the library that you created that contains the portlet jar. For me that is 'J2EE_Bundle'.
- Click Finish, then click OK.
Now that Eclipse will recognize the portlet API, we can begin coding our Hello World Portlet.
- Right click on the src directory, expand 'New', and click on Package.
- Name the package helloworld.
- Right click on the helloworld package, expand 'New', and click on Class.
- Name the class HelloWorldPortlet.
- Change the super class to javax.portlet.GenericPortlet and click Finish.
Eclipse should produce the following code:
import javax.portlet.GenericPortlet;
public class HelloWorldPortlet extends GenericPortlet {
}
There are several member functions we can override in the portlet, but the one that currently needs to be modified is the doView. doView takes two parameters: a RenderRequest and a RenderResponse object. For the purposes of this tutorial, we will only use the RenderResponse object because user input is not required. doView throws three different exceptions, which need to be handled, and they are: PortletException , IOException, and UnavailableException . The function does not return anything and should be preceded by the protected keyword so the function can be used from a subclass. The doView function should look like the following:
}
Do not forget to add the corresponding imports (Eclipse has a quick fix tool that is very handy for this). The imports required for this function are:
- java.io.IOException;
- javax.portlet.PortletException;
- javax.portlet.RenderRequest;
- javax.portlet.RenderResponse;
- javax.portlet.UnavailableException;
This is great, however, it will not do very much (granted HelloWorld doesn't do very much either). Let's add some content. To do so we need to specify a response type. Since we are displaying a web page, we need to set the type to be text/html. We do this by invoking the setResponseType on our response object as seen below:
Now all that is needed is a writer to print the text to the clients' screen. The writer is obtained through the response object as well and will need the java.io.PrintWriter import:
A message can now be sent to the end user. Do not forget to close the writer after this is done.
out.close();
The portlet should now look something like this:
import java.io.IOException;
import java.io.PrintWriter;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.UnavailableException;
public class HelloWorldPortlet extends GenericPortlet {
protected void doView( RenderRequest rRequest, RenderResponse rResponse ) throws PortletException, IOException, UnavailableException {
rResponse.setContentType( "text/html" );
PrintWriter out = rResponse.getWriter();
out.write( "Hello World!" );
out.close();
}
}
This is a good start, but we do not have a working portlet yet.
The Config
There are 3-4 xml files that are necessary for the JBoss AS to display the portlet correctly. All 4 files will go into the WebContent > WEB-INF folder in the project directory. These files are:
- web.xml
- portlet.xml
- portlet-instances.xml
- portlet-object.xml
The web.xml file is by far the simplest, but required none-the-less because this is a web application. If any servlets are used, their mappings would go here.
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>HelloWorldPortletApp</display-name>
</web-app>
The portlet.xml is where information about the Hello World Portlet is stored, such as the name, mime type, the portlet class to be used, the modes it supports, and the people who are allowed to view it. JBoss uses this file to link to the HelloWorldPortlet class and is how it knows that it exists. This is what the portlet.xml for this portlet should look like:
<?xml version="1.0" encoding="UTF-8"?>
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
version="1.0">
<!-- Hello World Portlet -->
<portlet>
<portlet-name>HellowWorldPortlet</portlet-name>
<portlet-class>helloworld.HelloWorldPortlet</portlet-class>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>
<portlet-info>
<title>Hello World Portlet</title>
</portlet-info>
<security-role-ref>
<role-name>User</role-name>
</security-role-ref>
</portlet>
</portlet-app>
The <portlet-name> tags specify how to access the portlet in the web browser. This is how JBoss associates actions with this portlet via URLS. It is also how JBoss associates the portlet with an instance. It is important to specify the full class path in the <portlet-class> tags, otherwise JBoss will not recognize the Hello World portlet. Next are the 'supports' tags. The nested <mime-type> is actually not necessary, as it is overrided programmatically by rResponse.setContentType( "text/html" ). I have included it so there would be no confusion as to what the content type of the portlet is. The HelloWorldPortlet only makes use of one mode, and that is VIEW, which corresponds with the doView function. There are more modes that will be discussed later. The <portlet-info> tags contain the title, which is displayed at the top of the portlet. I want everyone to be able to access this portlet, so it has the default User security role. The <portlet-app> tags may contain any number of portlet definitions, and is good practice to group portlets related to a specific application together in one file.
The next file, portlet-instances, is used by JBoss to make instances of portlet objects to be displayed in a portal. This will make the HelloWorldPortlet visible to the administrator and allow it to be selected and used in different portals.
<deployments>
<!-- Hello World Portlet -->
<deployment>
<instance>
<instance-id>HelloWorldPortletInstance</instance-id>
<portlet-ref>HelloWorldPortlet</portlet-ref>
</instance>
</deployment>
</deployments>
The two important tags to note here are <instance-id> and <portet-ref>. The <portlet-ref> tags need to contain the exact name in the <portal-name> tag of the portal.xml definition. If it is left out or is misspelled, the instance will not work. The <instance-id> tag provides a method to access this specific instance of our portlet. We could specify multiple instances with different ids of our HelloWorldPortlet. The id is what is available to the administrator in the admin portal. This is also what is available for a portlet object. It is good practice to define all portlet instances for a single applictation in this one file.
The Deployment
Up to this point, we should have a fully functional portlet, we just need to place it on the screen. There is two different ways this can be done: through the portlet-object.xml file or through the admin portal. First, I will explain how to display the portlet through the xml file.The last file, portlet-object.xml, generates "windows" of a portlet instance and tells them where they should go on the screen. It follows this structure:
<deployments>
<!-- Hello World Portlet -->
<deployment>
<if-exists>overwrite</if-exists>
<parent-ref>default.default</parent-ref>
<window>
<window-name>HelloWorldPortletWindow</window-name>
<instance-ref>HelloWorldPortletInstance</instance-ref>
<region>left</region>
<height>1</height>
</window>
</deployment>
</deployments>
The tags specify a new window to be displayed on the screen and references a specific instance of a portlet. It has to match exactly what is in the tags <instance-id> in the portlet-instance.xml file. The <if-exists> tag will replace the old window with this new one (if it already existed). This is handy when many changes are being made to a portlet and needs to be reflected immediately. The next tag, <parent-ref>, defines where the portlet window should be placed. Pay attention to the format of the inner text, "default.default". This may be confusing at first. What this represents is the target portal and the target tab, ie "portal.tab". By default, there is a portal named default, and a tab named default.
The <window-name> tag applies a name to the window to differentiate it from the other windows. The <instance-ref> tag needs to exactly match the <instance-id> tag in the portlet-instance.xml file in order for JBoss to find the portlet. The <region> tag assigns the portlet to a column on the page (possible values are left, center, right, depending on the number of columns defined by the admin, default is 2), and the <height> tag defines the vertical order of the portlets (ie 0 is at the top, 1 would be below 0, 2 would go below a 1, etc). Following this specification, this will place our portlet on the default page when the portal is accessed. Save your changes, export the project as a .war file into the deploy directory. Navigate to http://servername:8080/portal/portal/default and the HelloWorldPortlet should be visible there.
*Note: Feel free to change the <region> and <height> values to see how they position the portlet.
But why stop there? Lets create our own portal and place our newly created portlet-instance on a tabbed page. At the top right of the screen, click on Login. Login as the admin and click on the admin link to go to the admin portal. Click on the 'Portal Objects' tab and where it says 'Create a portal named:' type in MyPortal. Now click on the button labeled 'Create Portal'. This will add a new portal to the list. Click on the MyPortal link. This will take to a list of the pages contained within this portal. There should already be a page labeled 'default' in the list. Click on the link labeled 'Page Layout' next to this page. Type a name for the portlet window and scroll through the list till you find the HelloWorldPortletInstance. Select it and add it to the region you desire. You now have added the portlet to your own page in your own portal. To view your handiwork, navigate to http://servername:8080/portal/portal/MyPortal.
A Few Final Notes:
- To remove the portlet instance from the default portlet, just remove it from the portal-object.xml file. The instance in MyPortal, you'll have to delete it from the admin portal.
- The xml files, as far as I know, will not generate a portal or page/tab. You have to do that manually in the admin console before the portlet will appear.
- portlet.xml's <portlet-name> maps to portlet-instance.xml's <portlet-ref>, portlet-instance.xml's <instance-id> maps to portlet-object.xml's <instance-ref>. This was one of the harder things to learn with no documentation... so remember this.






Comments
Write New Comment ▼
Write New Comment
Sorry! This knol's owner(s) have blocked you from editing, making suggestions, or commenting here.