The JSR-168 Portlet Specification aims at defining portlets that can be used by any JSR-168 portlet container, also known as a portal. There are different portals with commercial and non-commercial licenses. This chapter gives a brief overview of the JSR-168 Portlet Specification. Portlet developers are strongly encouraged to read the JSR-168 Portlet Specification.
JBoss Portal is fully JSR-168 compliant, which means any JSR-168 portlet behaves as it should inside the portal.
A portal can be seen as pages with different areas, and inside areas, different windows, and each window having one portlet:
![]() |
A portlet can have different view modes. Three modes are defined by the JSR-168 specification, but a portal can extend those modes. The three modes are:
view - generates markup reflecting the current state of the portlet.
edit - allows a user to customize the behavior of the portlet.
help - provides information to the user as to how to use the portlet.
Window states are an indicator of how much page real-estate a portlet consumes on any given page. The three states defined by the JSR-168 specification are:
normal - a portlet shares this page with other portlets.
minimized -a portlet may show very little information, or none at all.
maximized - a portlet may be the only portlet displayed on this page.
The tutorials contained in this chapter are targetted toward portlet developers. Although they are a good starting and reference point, it is highly recommend that portlet developers read and understand the JSR-168 Portlet Specification. Use the JBoss Portal User Forums for user-to-user help.
This section describes how to deploy a portlet in JBoss Portal. Before proceeding, download the HelloWorldPortlet from JBoss PortletSwap.
Like other Java Platform, Enterprise Edition (Java EE) applications, portlets are packaged in WAR files. A typical portlet WAR file can include servlets, resource bundles, images, HTML, JavaServer™ Pages (JSP™), and other static or dynamic files. The following is an example of the directory structure of the HelloWorldPortlet portlet:
![]() |
The following is the HelloWorldPortlet/src/main/org/jboss/portlet/hello/HelloWorldPortlet.java Java source file, which comes bundled with the HelloWorldPortlet:
package org.jboss.portlet.hello; import javax.portlet.GenericPortlet; import javax.portlet.PortletException; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import javax.portlet.UnavailableException; import java.io.IOException; import java.io.PrintWriter; public class HelloWorldPortlet extends GenericPortlet { protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException { rResponse.setContentType("text/html"); PrintWriter writer = rResponse.getWriter(); writer.write("Hello World!"); writer.close(); } }
public class HelloWorldPortlet extends GenericPortlet
All portlets must implement the javax.portlet.Portlet interface. The portlet API provides a convenient implementation of this interface, in the form of the javax.portlet.GenericPortlet class, which among other things, implements the Portlet render method to dispatch to abstract mode-specific methods to make it easier to support the standard portlet modes. As well, it provides a default implementation for the processAction, init and destroy methods. It is recommended to extend GenericPortlet for most cases.
protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException
As we extend from GenericPortlet, and are only interested in supporting the view mode, only the doView method needs to be implemented, and the GenericPortlet render implemention calls our implementation when the view mode is requested.
rResponse.setContentType("text/html");
As in the servlet world, you must declare what content-type the portlet will be responding in. Do this before starting to write content, or the portlet will throw an exception.
PrintWriter writer = rResponse.getWriter(); writer.write("Hello World!"); writer.close();
This produces the Hello World! text in our portlet window.
Portlets are responsible for generating markup fragments, as they are included on a page and are surrounded by other portlets. In particular, this means that a portlet outputting HTML must not output any markup that cannot be found in a <body> element.
JBoss Portal requires certain descriptors to be included in a portlet WAR file. Some of these descriptors are defined by the JSR-168 Portlet Specification, and others are specific to JBoss Portal. The following is an example of the directory structure of the HelloWorldPortlet portlet:
![]() |
To create the WEB-INF/ and META-INF/ directories, extract the helloworldportlet.war file.
The following is an example of the HelloWorldPortlet/WEB-INF/portlet.xml file. This file must adhere to its definition in the JSR-168 Portlet Specification. You may define more than one portlet application in this file:
<?xml version="1.0" encoding="UTF-8"?> <portlet-app 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"> <portlet> <portlet-name>HelloWorldPortlet</portlet-name> <portlet-class>org.jboss.portlet.hello.HelloWorldPortlet</portlet-class> <supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports> <portlet-info> <title>HelloWorld Portlet</title> </portlet-info> </portlet> </portlet-app>
<portlet-name>HelloWorldPortlet</portlet-name>
Define the portlet name. It does not have to be the class name.
<portlet-class>org.jboss.portlet.hello.HelloWorldPortlet</portlet-class>
The Fully Qualified Name (FQN) of your portlet class must be declared here.
<supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports>
The <supports> element declares all of the markup types that a portlet supports in the render method. This is accomplished via the <mime-type> element, which is required for every portlet. The declared MIME types must match the capability of the portlet. As well, it allows you to pair which modes and window states are supported for each markup type. All portlets must support the view portlet mode, so this does not have to be declared. Use the <mime-type> element to define which markup type your portlet supports, which in this example, is text/html. This section tells the portal that it only outputs text and HTML, and that it only supports the view mode.
<portlet-info> <title>HelloWorld Portlet</title> </portlet-info>
When rendered, the portlet's title is displayed as the header in the portlet window, unless it is overridden programmatically. In this example, the title would be HelloWorld Portlet.
The HelloWorldPortlet/WEB-INF/portlet-instances.xml file is a JBoss Portal specific descriptor, that allows you to create instances of portlets. The <portlet-ref> value must match the <portlet-name> value given in the HelloWorldPortlet/WEB-INF/portlet.xml file. The <instance-id> value can be named anything, but it must match the <instance-ref> value given in the *-object.xml file, which in this example, would be the HelloWorldPortlet/WEB-INF/helloworld-object.xml file.
The following is an example of the HelloWorldPortlet/WEB-INF/portlet-instances.xml file:
<?xml version="1.0" standalone="yes"?> <!DOCTYPE deployments PUBLIC "-//JBoss Portal//DTD Portlet Instances 2.6//EN" "http://www.jboss.org/portal/dtd/portlet-instances_2_6.dtd"> <deployments> <deployment> <instance> <instance-id>HelloWorldPortletInstance</instance-id> <portlet-ref>HelloWorldPortlet</portlet-ref> </instance> </deployment> </deployments>
The *-object.xml file is a JBoss Portal specific descriptor that allow users to define the structure of their portal instances, and create and configure their windows and pages. In the following example:
a portlet window is created.
specifies that the window displays the markup generated by the HelloWorldPortletInstance portlet instance.
the window is assigned to the default.default page.
the <region> element specifies where the window appears on the page.
The following is an example HelloWorldPortlet/WEB-INF/helloworld-object.xml file:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE deployments PUBLIC "-//JBoss Portal//DTD Portal Object 2.6//EN" "http://www.jboss.org/portal/dtd/portal-object_2_6.dtd"> <deployments> <deployment> <parent-ref>default.default</parent-ref> <if-exists>overwrite</if-exists> <window> <window-name>HelloWorldPortletWindow</window-name> <instance-ref>HelloWorldPortletInstance</instance-ref> <region>center</region> <height>1</height> </window> </deployment> </deployments>
<parent-ref>default.default</parent-ref>
Tells the portal where this portlet appears. In this case, default.default specifies that the portlet appears in the portal instance named default, and on the page named default.
<if-exists>overwrite</if-exists>
Instructs the portal to overwrite or keep this object if it already exists. Accepted values are overwrite and keep. The overwrite option destroys the existing object, and creates a new one based on the content of the deployment. The keep option maintains the existing object deployment, or creates a new one if it does not exist.
<window-name>HelloWorldPortletWindow</window-name>
A unique name given to the portlet window. This can be named anything.
<instance-ref>HelloWorldPortletInstance</instance-ref>
The value of <instance-ref> must match the value of one of the <instance-id> elements found in the HelloWorldPortlet/WEB-INF/portlet-instances.xml file.
<region>center</region> <height>1</height>
Specifies where the window appears within the page layout.
The following diagram illustrates the relationship between the portlet.xml, portlet-instances.xml, and helloworld-object.xml descriptors:
![]() |
JBoss Portal 2.6 introduces the notion of content-type, which is a generic mechanism to specify what content displayed by a given portlet window. The window section of the previous example, HelloWorldPortlet/WEB-INF/helloworld-object.xml, can be re-written to take advantage of the new content framework. The following is an example deployment descriptor that uses the new content framework:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE deployments PUBLIC "-//JBoss Portal//DTD Portal Object 2.6//EN" "http://www.jboss.org/portal/dtd/portal-object_2_6.dtd"> <deployments> <deployment> <parent-ref>default.default</parent-ref> <if-exists>overwrite</if-exists> <window> <window-name>HelloWorldPortletWindow</window-name> <content> <content-type>portlet</content-type> <content-uri>HelloWorldPortletInstance</content-uri> </content> <region>center</region> <height>1</height> </window> </deployment> </deployments>
This declaration is equivalent to the previous HelloWorldPortlet/WEB-INF/helloworld-object.xml example. Use <content-type> to specify the content to display. In this example, the content being displayed by the HelloWorldPortletWindow is a portlet. The <content-uri> element specifies which content to display, which in this example, is the HelloWorldPortletInstance:
<content> <content-type>portlet</content-type> <content-uri>HelloWorldPortletInstance</content-uri> </content>
To display certain content or a file, use the cms content-type, with the <content-uri> element being the path to the file in the CMS. This behavior is pluggable: you can plug in almost any type of content.
The HelloWorldPortlet.zip file contains a pre-compiled helloworldportlet.war file; however, to manually build the helloworldportlet.war file:
Change into the HelloWorldPortlet/ directory, and remove the existing helloworldportlet.war file.
If required, edit the HelloWorldPortlet/src/main/org/jboss/portlet/hello/HelloWorldPortlet.java file, and the application descriptors in the HelloWorldPortlet/src/resources/helloworldportlet-war/WEB-INF/ directory.
Change into HelloWorldPortlet/ directory, and run the ant deploy command. On Windows, the output will be similar to the following:
![]() |
Note: the directory names will be different for your system.
Expanding the helloworldportlet.war file allows you to deploy the portlet as an expanded directory, which makes development easier. As well, it gives you access to the application descriptors, resource files, JSF, and JSP pages. To expand the helloworldportlet.war file:
If you do not have the HelloWorldPortlet/helloworldportlet.war file, change into the HelloWorldPortlet/ directory, and run the ant deploy command. This creates the helloworldportlet.war file.
To expand the WAR file, change into the HelloWorldPortlet/ directory, and run the ant explode command. On Windows, the output will be similar to the following:
![]() |
Note: the directory names will be different for your system.
The ant explode command creates a directory structure such as the following:
![]() |
The expanded WAR file and the application descriptors are located in the HelloWorldPortlet/output/lib/exploded/helloworldportlet.war/WEB-INF/ directory.
If you did not expand the helloworldportlet.war file, copy the HelloWorldPortlet/helloworldportlet.war file into the correct JBoss AS or JBoss EAP deploy/ directory. If you expanded the helloworldportlet.war file, copy the HelloWorldPortlet/output/lib/exploded/helloworldportlet.war/ directory into the correct JBoss AS or JBoss EAP deploy/ directory. For example, if you are using the default JBoss AS profile, copy the WAR file or the expanded directory into the $JBOSS_HOME/server/default/deploy/ directory.
Performing this step on a running instance of JBoss AS or JBoss EAP, and JBoss Portal, triggers a hot-deploy of the portlet:
INFO [TomcatDeployer] deploy, ctxPath=/helloworldportlet, warUrl=.../tmp/deploy/tmp35219helloworldportlet-exp.war/
To see the HelloWorldPortlet, navigate to http://localhost:8080/portal/, or, if the default JBoss Portal page is already open, refresh the page. The HelloWorldPortlet is added to the bottom of the default JBoss Portal page:
![]() |
To re-deploy the portlet, for example, if you have made changes to any of the application descriptors, touch the $JBOSS_HOME/server/configuration/deploy/helloworldportlet.war/WEB-INF/web.xml file. This only works if you copied the HelloWorldPortlet/output/lib/exploded/helloworldportlet.war/ directory into the JBoss AS or JBoss EAP deploy/ directory. On Linux, run the touch $JBOSS_HOME/server/configuration/deploy/helloworldportlet.war/WEB-INF/web.xml command to re-deploy the HelloWorldPortlet.
Re-deploying the HelloWorldPortlet produces output to the JBoss AS or JBoss EAP console, similar to the following:
INFO [TomcatDeployer] undeploy, ctxPath=/helloworldportlet, warUrl=.../deploy/helloworldportlet.war/ INFO [TomcatDeployer] deploy, ctxPath=/helloworldportlet, warUrl=.../deploy/helloworldportlet.war/
This section describes how to deploy a JSP™ portlet in JBoss Portal. Before proceeding, download the HelloWorldJSPPortlet from JBoss PortletSwap. The HelloWorldJSPPortlet demonstrates how to use JSP pages for view rendering, and the portlet tag library (taglib) for generating links.
The application descriptors for the HelloWorldJSPPortlet portlet are similar to those from the HelloWorldPortlet (Section 5.2.1.4, “Application Descriptors”). Refer to Section 6.2, “Portlet Descriptors” for further information about application descriptors.
The HelloWorldJSPPortlet portlet contains the traditional portlet and JBoss Portal specific application descriptors. The following is an example of the directory structure of the HelloWorldJSPPortlet portlet:
![]() |
To create the WEB-INF/ and META-INF/ directories, extract the helloworldjspportlet.war file.
The HelloWorldJSPPortlet contains the HelloWorldJSPPortlet/src/main/org/jboss/portlet/hello/HelloWorldJSPPortlet.java file:
package org.jboss.portlet.hello; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; import javax.portlet.GenericPortlet; import javax.portlet.PortletException; import javax.portlet.PortletRequestDispatcher; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import javax.portlet.UnavailableException; import java.io.IOException; public class HelloWorldJSPPortlet extends GenericPortlet { protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException { rResponse.setContentType("text/html"); String sYourName = (String) rRequest.getParameter("yourname"); if(sYourName != null) { rRequest.setAttribute("yourname", sYourName); PortletRequestDispatcher prd = getPortletContext() .getRequestDispatcher("/WEB-INF/jsp/view2.jsp"); prd.include(rRequest, rResponse); } else { PortletRequestDispatcher prd = getPortletContext() .getRequestDispatcher("/WEB-INF/jsp/view.jsp"); prd.include(rRequest, rResponse); } } public void processAction(ActionRequest aRequest, ActionResponse aResponse) throws PortletException, IOException, UnavailableException { String sYourname = (String) aRequest.getParameter("yourname"); // do something aResponse.setRenderParameter("yourname", sYourname); } protected void doHelp(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException { rResponse.setContentType("text/html"); PortletRequestDispatcher prd = getPortletContext() .getRequestDispatcher("/WEB-INF/jsp/help.jsp"); prd.include(rRequest, rResponse); } protected void doEdit(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException { rResponse.setContentType("text/html"); PortletRequestDispatcher prd = getPortletContext() .getRequestDispatcher("/WEB-INF/jsp/edit.jsp"); prd.include(rRequest, rResponse); } }
protected void doHelp(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException
protected void doEdit(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException
Support for these modes must be declared in the HelloWorldJSPPortlet/WEB-INF/portlet.xml file. They are triggered when a user clicks on the respective icons in the portlet window titlebar, or through generated links within the portlet.
public void processAction(ActionRequest aRequest, ActionResponse aResponse) throws PortletException, IOException, UnavailableException { String sYourname = (String) aRequest.getParameter("yourname"); // do something aResponse.setRenderParameter("yourname", sYourname); }
This method is triggered when a user clicks on an actionURL, which is defined in the HelloWorldJSPPortlet/WEB-INF/jsp/view.jsp file. This retrieves yourname from the HTML form, and passes it as a aResponse.setRenderParameter to the doView() method.
rResponse.setContentType("text/html");
As in the servlet world, you must declare what content-type the portlet will be responding in. Do this before starting to write content, or the portlet throws an exception.
protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException
The doView implementation is responsible for dispatching to the appropriate JSP, HelloWorldJSPPortlet/WEB-INF/jsp/view.jsp or HelloWorldJSPPortlet/WEB-INF/jsp/view2.jsp, depending on the existence of the yourname parameter passed in from processAction.
The HelloWorldJSPPortlet/WEB-INF/jsp/view.jsp and HelloWorldJSPPortlet/WEB-INF/jsp/view2.jsp JSP™ files are included in the HelloWorldJSPPortlet portlet. The view.jsp file allows a user to input their name. This is then posted to the processAction method in the portlet class, which is set as a aResponse.setRenderParameter. The doView render method is invoked, which dispatches to the view2.jsp JSP:
![]() |
The following is an example of the HelloWorldJSPPortlet/WEB-INF/jsp/view.jsp file:
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %> <portlet:defineObjects/> <div align="center"> This is a simple HelloWorld JSP Portlet. Type in a name and it will dispatch to the view2.jsp to print out your name. <br/> <form action="<portlet:actionURL><portlet:param name="page" value="mainview"/> </portlet:actionURL>" method="POST"> Name:<br/> <input type="text" name="yourname"/> </form> <br/> You can also link to other pages, using a renderURL, like <a href="<portlet:renderURL><portlet:param name="yourname" value="Roy Russo"> </portlet:param></portlet:renderURL>">this</a>. </div>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
Define the portlet taglib. You do not need to bundle the portlet taglib - JBoss Portal handles this for you.
<portlet:defineObjects/>
Calling defineObjects makes available implicit objects in the JSP, such as renderRequest, actionRequest, and portletConfig.
<form action="<portlet:actionURL><portlet:param name="page" value="mainview"/> </portlet:actionURL>" method="POST">
A HTML form is created. This form posts to the URL defined by the portlet taglib. In this example, an actionURL is created, that activates the processAction method, which passes the input parameters from the form.
<a href="<portlet:renderURL><portlet:param name="yourname" value="Roy Russo"> </portlet:param></portlet:renderURL>">
You can create a link to the doView method by creating a renderURL, which passes the yourname parameter.
The HelloWorldJSPPortlet.zip file contains a pre-compiled helloworldjspportlet.war file; however, to manually build the helloworldjspportlet.war file:
Change into the HelloWorldJSPPortlet/ directory, and remove the existing helloworldjspportlet.war file.
If required, edit the HelloWorldJSPPortlet/src/main/org/jboss/portlet/hello/HelloWorldJSPPortlet.java file, and the application descriptors in the HelloWorldJSPPortlet/src/resources/helloworldjspportlet-war/WEB-INF/ directory.
Change into HelloWorldJSPPortlet/ directory, and run the ant deploy command. On Linux, the output will be similar to the following:
![]() |
Note: the directory names will be different for your system.
Expanding the helloworldjspportlet.war file allows you to deploy the portlet as an expanded directory, which makes development easier. As well, it gives you access to the application descriptors, resource files, JSF, and JSP™ pages. To expand the helloworldjspportlet.war file:
If you do not have the HelloWorldJSPPortlet/helloworldjspportlet.war file, change into the HelloWorldJSPPortlet/ directory, and run the ant deploy command. This creates the helloworldjspportlet.war file.
To expand the WAR file, change into the HelloWorldJSPPortlet/ directory, and run the ant explode command. On Linux, the output will be similar to the following:
![]() |
Note: the directory names will be different for your system.
The ant explode command creates a directory structure such as the following:
![]() |
The expanded WAR file and the application descriptors are located in the HelloWorldJSPPortlet/output/lib/exploded/helloworldjspportlet.war/WEB-INF/ directory.
If you did not expand the helloworldjspportlet.war file, copy the HelloWorldJSPPortlet/helloworldjspportlet.war file into the correct JBoss AS or JBoss EAP deploy/ directory. If you expanded the helloworldjspportlet.war file, copy the HelloWorldJSPPortlet/output/lib/exploded/helloworldjspportlet.war/ directory into the correct JBoss AS or JBoss EAP deploy/ directory. For example, if you are using the default JBoss AS profile, copy the WAR file or the expanded directory into the $JBOSS_HOME/server/default/deploy/ directory.
Performing this step on a running instance of JBoss AS or JBoss EAP, and JBoss Portal, triggers a hot-deploy of the portlet:
INFO [TomcatDeployer] deploy, ctxPath=/helloworldjspportlet, warUrl=.../deploy/helloworldjspportlet.war/
To see the HelloWorldJSPPortlet, navigate to http://localhost:8080/portal/, or, if the default JBoss Portal page is already open, refresh the page. The HelloWorldJSPPortlet is added to the bottom of the default JBoss Portal page:
![]() |
To re-deploy the portlet, for example, if you have made changes to any of the application descriptors, touch the $JBOSS_HOME/server/configuration/deploy/helloworldjspportlet.war/WEB-INF/web.xml file. This only works if you copied the HelloWorldJSPPortlet/output/lib/exploded/helloworldjspportlet.war/ directory into the JBoss AS or JBoss EAP deploy/ directory. On Linux, run the touch $JBOSS_HOME/server/configuration/deploy/helloworldjspportlet.war/WEB-INF/web.xml command to re-deploy the HelloWorldJSPPortlet.
Re-deploying the HelloWorldJSPPortlet produces output to the JBoss AS or JBoss EAP console, similar to the following:
INFO [TomcatDeployer] undeploy, ctxPath=/helloworldjspportlet, warUrl=.../deploy/helloworldjspportlet.war/ INFO [TomcatDeployer] deploy, ctxPath=/helloworldjspportlet, warUrl=.../deploy/helloworldjspportlet.war/
This section describes how to deploy a JSF portlet in JBoss Portal, using the Apache MyFaces JSF implementation in JBoss AS and JBoss EAP. Before proceeding, download the HelloWorldJSFSunRIPortlet from JBoss PortletSwap.
JBoss Portal requires certain descriptors to be included in a portlet WAR file. Some of these descriptors are defined by the JSR-168 Portlet Specification, and others are specific to JBoss Portal. Like a typical JSF application, the HelloWorldJSFSunRIPortlet package contains a faces-config.xml file that defines managed-beans, converters, validators, navigation rules, and so on. The following is an example of the directory structure of the HelloWorldJSFSunRIPortlet portlet:
![]() |
To create the WEB-INF/ and META-INF/ directories, extract the helloworldjsfsunriportlet.war file.
JBoss AS version 4.2.x and JBoss EAP bundle the Sun™ JSF RI libraries in the $JBOSS_HOME/server/default/deploy/jboss-web.deployer/jsf-libs/ directory. Therefore, you do not need to package the Sun JSF RI libraries with your portlet application.
Only the portlet.xml, faces-config.xml, and web.xml descriptors are described here. For more information about application descriptors, refer to Section 5.2.1.4, “Application Descriptors” and Section 6.2, “Portlet Descriptors”.
The following is an example of the HelloWorldJSFSunRIPortlet/WEB-INF/portlet.xml file. This file must adhere to its definition in the JSR-168 Portlet Specification. You may define more than one portlet application in this file:
<?xml version="1.0" encoding="UTF-8"?> <portlet-app 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"> <portlet> <portlet-name>HelloWorldJSFPortlet</portlet-name> <portlet-class>com.sun.faces.portlet.FacesPortlet</portlet-class> <init-param> <name>com.sun.faces.portlet.INIT_VIEW</name> <value>/WEB-INF/jsp/index.jsp</value> </init-param> <supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports> <portlet-info> <title>HelloWorld JSF Portlet</title> </portlet-info> </portlet> </portlet-app>
<portlet-class>com.sun.faces.portlet.FacesPortlet</portlet-class>
This specifies that the com.sun.faces.portlet.FacesPortlet handles all requests and responses from the users. This class is part of the HelloWorldJSFSunRIPortlet/WEB-INF/lib/jsf-portlet.jar file.
<init-param> <name>com.sun.faces.portlet.INIT_VIEW</name> <value>/WEB-INF/jsp/index.jsp</value> </init-param>
You must initialize the portlet with a default page to render, similar to a welcome page.
<supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports>
The <supports> element allows you to declare all of the markup types that a portlet supports in the render method. This is accomplished via the <mime-type> element, which is required for every portlet. The declared MIME types must match the capability of the portlet. As well, it allows you to pair which modes and window states are supported for each markup type. All portlets must support the view portlet mode, so this does not have to be declared. Use the <mime-type> element to define which markup type your portlet supports, which in this example, is text/html. This section tells the portal that it only outputs text and HTML, and that it only supports the view mode.
The following is an example HelloWorldJSFSunRIPortlet/WEB-INF/faces-config.xml file:
<?xml version="1.0"?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> <faces-config> <managed-bean> <description>Basic UserBean</description> <managed-bean-name>user</managed-bean-name> <managed-bean-class>org.jboss.portlet.hello.bean.User</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <navigation-rule> <navigation-case> <from-outcome>done</from-outcome> <to-view-id>/WEB-INF/jsp/result.jsp</to-view-id> </navigation-case> </navigation-rule> </faces-config>
Without the faces-config.xml file, the application would work the same outside of the portlet as it would inside a portlet container. In this example, a basic user bean, <managed-bean-name>user</managed-bean-name>, and a navigation rule are defined, which handle the submission of the original form in the HelloWorldJSFSunRIPortlet/WEB-INF/jsp/index.jsp file.
The following is an example of the Faces Servlet and Faces Servlet Mapping sections from the HelloWorldJSFSunRIPortlet/WEB-INF/web.xml file:
<?xml version="1.0"?> <!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> <!-- Faces Servlet --> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <!-- Faces Servlet Mapping --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> </web-app>
For Sun JSF RI portlets, the Faces Servlet and Faces Servlet Mapping sections are required to associate files with the .jsf extension to the Apache MyFaces servlet.
Unlike Apache MyFaces, the classes for the JSF-Portlet bridge are not included in the JSF implementation, JBoss AS, or JBoss EAP. This library must be available in your application package. Navigate to the JSF-Portlet bridge webpage to download the JSF-Portlet bridge library.
The HelloWorldJSFSunRIPortlet.zip file contains a pre-compiled helloworldjsfsunriportlet.war file; however, to manually build the helloworldjsfsunriportlet.war file:
Change into the HelloWorldJSFSunRIPortlet/ directory, and remove the existing helloworldjsfsunriportlet.war file.
If required, edit the HelloWorldJSFSunRIPortlet/src/main/org/jboss/portlet/hello/bean/User.java file, and the application descriptors in the HelloWorldJSFSunRIPortlet/src/resources/helloworldjsfsunriportlet-war/WEB-INF/ directory.
Change into HelloWorldJSFSunRIPortlet/ directory, and run the ant deploy command. On Linux, the output will be similar to the following:
![]() |
Note: the directory names will be different for your system.
Expanding the helloworldjsfsunriportlet.war file allows you to deploy the portlet as an expanded directory, which makes development easier. As well, it gives you access to the application descriptors, resource files, JSF, and JSP pages. To expand the helloworldjsfsunriportlet.war file:
If you do not have the HelloWorldJSFSunRIPortlet/helloworldjsfsunriportlet.war file, change into the HelloWorldJSFSunRIPortlet/ directory, and run the ant deploy command. This creates the helloworldjsfsunriportlet.war file.
To expand the WAR file, change into the HelloWorldJSFSunRIPortlet/ directory, and run the ant explode command. On Linux, the output will be similar to the following:
![]() |
Note: the directory names will be different for your system.
The expanded WAR file and the application descriptors are located in the HelloWorldJSFSunRIPortlet/output/lib/exploded/helloworldjsfsunriportlet.war/WEB-INF/ directory.
If you did not expand the helloworldjsfsunriportlet.war file, copy the HelloWorldJSFSunRIPortlet/helloworldjsfsunriportlet.war file into the correct JBoss AS or JBoss EAP deploy/ directory. If you expanded the helloworldjsfsunriportlet.war file, copy the HelloWorldJSFSunRIPortlet/output/lib/exploded/helloworldjsfsunriportlet.war/ directory into the correct JBoss AS or JBoss EAP deploy/ directory. For example, if you are using default JBoss AS profile, copy the WAR file or the expanded directory into the $JBOSS_HOME/server/default/deploy/ directory.
Performing this step on a running instance of JBoss AS or JBoss EAP, and JBoss Portal, triggers a hot-deploy of the portlet:
INFO [TomcatDeployer] deploy, ctxPath=/helloworldjsfsunriportlet, warUrl=.../tmp/deploy/tmp9138helloworldjsfsunriportlet-exp.war/
To see the HelloWorldJSFSunRIPortlet, navigate to http://localhost:8080/portal/, or, if the default JBoss Portal page is already open, refresh the page. The HelloWorldJSFSunRIPortlet is added to the bottom of the default JBoss Portal page:
![]() |
To re-deploy the portlet, for example, if you have made changes to any of the application descriptors, touch the $JBOSS_HOME/server/configuration/deploy/helloworldjsfsunriportlet.war/WEB-INF/web.xml file. This only works if you copied the HelloWorldJSFSunRIPortlet/output/lib/exploded/helloworldjsfsunriportlet.war/ directory into the JBoss AS or JBoss EAP deploy/ directory. On Linux, run the touch $JBOSS_HOME/server/configuration/deploy/helloworldjsfsunriportlet.war/WEB-INF/web.xml command to re-deploy the HelloWorldJSFSunRIPortlet.
Re-deploying the HelloWorldJSFSunRIPortlet produces output to the JBoss AS or JBoss EAP console, similar to the following:
INFO [TomcatDeployer] undeploy, ctxPath=/helloworldjsfsunriportlet, warUrl=.../deploy/helloworldjsfsunriportlet.war/ INFO [TomcatDeployer] deploy, ctxPath=/helloworldjsfsunriportlet, warUrl=.../deploy/helloworldjsfsunriportlet.war/
This section describes how to deploy a JSF portlet in JBoss Portal, using the Apache MyFaces JSF implementation in JBoss AS and JBoss EAP. Before proceeding, download the HelloWorldJSFMyFaces42Portlet from JBoss PortletSwap.
Apache MyFaces can be used globally for the entire server, replacing the Sun JSF RI libraries, but the HelloWorldJSFMyFaces42Portlet uses its own libraries, but does not affect the application server.
JBoss Portal requires certain descriptors to be included in a portlet WAR file. Some of these descriptors are defined by the JSR-168 Portlet Specification, and others are specific to JBoss Portal. Like a typical JSF application, the HelloWorldJSFMyFaces42Portlet package contains a faces-config.xml file that defines managed-beans, converters, validators, navigation rules, and so on. The following is an example of the directory structure of the HelloWorldJSFMyFaces42Portlet portlet:
![]() |
To create the WEB-INF/ and META-INF/ directories, extract the helloworldjsfmyfacesportlet.war file. The WEB-INF/lib/ directory must contain the Apache MyFaces libraries, along with the dependent libraries.
Only the portlet.xml, faces-config.xml, and web.xml descriptors are described here. For more information about application descriptors, refer to Section 5.2.1.4, “Application Descriptors” and Section 6.2, “Portlet Descriptors”.
The following is an example of the HelloWorldJSFMyFaces42Portlet/WEB-INF/portlet.xml file. This file must adhere to its definition in the JSR-168 Portlet Specification. You may define more than one portlet application in this file:
<?xml version="1.0" encoding="UTF-8"?> <portlet-app 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"> <portlet> <portlet-name>HelloWorldJSFPortlet</portlet-name> <portlet-class>org.apache.myfaces.portlet.MyFacesGenericPortlet</portlet-class> <init-param> <name>default-view</name> <value>/WEB-INF/jsp/index.jsp</value> </init-param> <supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports> <portlet-info> <title>HelloWorld JSF Portlet</title> </portlet-info> </portlet> </portlet-app>
<portlet-class>org.apache.myfaces.portlet.MyFacesGenericPortlet</portlet-class>
This specifies that the org.apache.myfaces.portlet.MyFacesGenericPortlet handles all requests and responses from the users. Therefore, there is no need to develop a specific portlet class, as Apache MyFaces provides a generic implementation which bridges the JSF and portlet worlds.
<init-param> <name>default-view</name> <value>/WEB-INF/jsp/index.jsp</value> </init-param>
You must initialize the portlet with a default page to render, similar to a welcome page.
<supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports>
The <supports> element allows you to declare all of the markup types that a portlet supports in the render method. This is accomplished via the <mime-type> element, which is required for every portlet. The declared MIME types must match the capability of the portlet. As well, it allows you to pair which modes and window states are supported for each markup type. All portlets must support the view portlet mode, so this does not have to be declared. Use the <mime-type> element to define which markup type your portlet supports, which in this example, is text/html. This section tells the portal that it only outputs text and HTML, and that it only supports the view mode.
To add functionality to an Apache MyFaces JSF portlet, sub-class it and create your own class.
The following is an example HelloWorldJSFMyFaces42Portlet/WEB-INF/faces-config.xml file:
<?xml version="1.0"?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> <faces-config> <managed-bean> <description>Basic UserBean</description> <managed-bean-name>user</managed-bean-name> <managed-bean-class>org.jboss.portlet.hello.bean.User</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <navigation-rule> <navigation-case> <from-outcome>done</from-outcome> <to-view-id>/WEB-INF/jsp/result.jsp</to-view-id> </navigation-case> </navigation-rule> </faces-config>
Without the faces-config.xml file, the application would work the same outside of the portlet as it would inside a portlet container. In this example, a basic user bean, <managed-bean-name>user</managed-bean-name>, and a navigation rule are defined, which handle the submission of the original form in the HelloWorldJSFMyFaces42Portlet/WEB-INF/jsp/index.jsp file.
The following is an example of the <context-parm> element from the HelloWorldJSFMyFaces42Portlet/WEB-INF/web.xml file:
<context-param> <param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name> <param-value>true</param-value> </context-param>
These extra parameters let the application server know that the portlet embeds its own libraries. This avoids collision with the Sun JSF RI libraries bundled with JBoss AS and JBoss EAP. For more information, refer to the JBossFaces page on the JBoss Wiki.
The HelloWorldJSFMyFaces42Portlet.zip file contains a pre-compiled helloworldjsfmyfacesportlet.war file; however, to manually build the helloworldjsfmyfacesportlet.war file:
Change into the HelloWorldJSFMyFaces42Portlet/ directory, and remove the existing helloworldjsfmyfacesportlet.war file.
If required, edit the HelloWorldJSFMyFaces42Portlet/src/main/org/jboss/portlet/hello/bean/User.java file, and the application descriptors in the HelloWorldJSFMyFaces42Portlet/src/resources/helloworldjsfmyfacesportlet-war/WEB-INF/ directory.
Change into HelloWorldJSFMyFaces42Portlet/ directory, and run the ant deploy command. On Linux, the output will be similar to the following:
![]() |
Note: the directory names will be different for your system.
Expanding the helloworldjsfmyfacesportlet.war file allows you to deploy the portlet as an expanded directory, which makes development easier. As well, it gives you access to the application descriptors, resource files, JSF, and JSP pages. To expand the helloworldjsfmyfacesportlet.war file:
If you do not have the HelloWorldJSFMyFaces42Portlet/helloworldjsfmyfacesportlet.war file, change into the HelloWorldJSFMyFaces42Portlet/ directory, and run the ant deploy command. This creates the helloworldjsfmyfacesportlet.war file.
To expand the WAR file, change into the HelloWorldJSFMyFaces42Portlet/ directory, and run the ant explode command. On Linux, the output will be similar to the following:
![]() |
Note: the directory names will be different for your system.
The expanded WAR file and the application descriptors are located in the HelloWorldJSFMyFaces42Portlet/output/lib/exploded/helloworldjsfmyfacesportlet.war/WEB-INF/ directory.
If you did not expand the helloworldjsfmyfacesportlet.war file, copy the HelloWorldJSFMyFaces42Portlet/helloworldjsfmyfacesportlet.war file into the correct JBoss AS or JBoss EAP deploy/ directory. If you expanded the helloworldjsfmyfacesportlet.war file, copy the HelloWorldJSFMyFaces42Portlet/output/lib/exploded/helloworldjsfmyfacesportlet.war/ directory into the correct JBoss AS or JBoss EAP deploy/ directory. For example, if you are using the default JBoss AS profile, copy the WAR file or the expanded directory into the $JBOSS_HOME/server/default/deploy/ directory.
Performing this step on a running instance of JBoss AS or JBoss EAP, and JBoss Portal, triggers a hot-deploy of the portlet.
To see the HelloWorldJSFMyFaces42Portlet, navigate to http://localhost:8080/portal/, or, if the default JBoss Portal page is already open, refresh the page. The HelloWorldJSFMyFaces42Portlet is added to the bottom of the default JBoss Portal page:
![]() |
To re-deploy the portlet, for example, if you have made changes to any of the application descriptors, touch the $JBOSS_HOME/server/configuration/deploy/helloworldjsfmyfacesportlet.war/WEB-INF/web.xml file. This only works if you copied the HelloWorldJSFMyFaces42Portlet/output/lib/exploded/helloworldjsfmyfacesportlet.war/ directory into the JBoss AS or JBoss EAP deploy/ directory. On Linux, run the following command to re-deploy the HelloWorldJSFMyFaces42Portlet:
touch $JBOSS_HOME/server/configuration/deploy/helloworldjsfmyfacesportlet.war/WEB-INF/web.xml