To get an idea of the JBoss Portlet Bridge community, the developers, and for wiki information, checkout the project page.
What is the JBoss Portlet Bridge?
The JBoss Portlet Bridge (or JBPB for short) is an implementation of the JSR-301 specification which supports JSF within a portlet and with added enhancements to support other web frameworks (such as Seam and RichFaces). It basically allows any Java developer to get started quickly with their JSF web application running in a portal environment. The developer no longer needs to worry about the underlying portlet development, portlet concepts, or the API.
Understanding how JSF works with Portal
The portlet bridge isn't a portlet. It's the mediator between the two environments and allows JSF and Portal to be completely unaware of each other and live in their own seperate worlds. The bridge is used to execute Faces requests on behalf of the portlet. During each request, the Faces environment is setup and handled by the bridge. Part of this implementation acts as a Faces controller much as the FacesServlet does in the direct client request world. The other part of this implementation is provided by implementating a variety of (standard) Faces extensions.
JBoss Portlet Bridge not only gives you the ability to run JSF web applications in a portlet, but also gives you the benefit of running supported JBoss frameworks like Seam and RichFaces.
The JBoss Portlet Bridge currently supports JBoss Portal, JSF 1.2, JBoss Seam, and JBoss Richfaces. There are configurations that apply to supporting each framework. See section Chapter 2, Bridge Configuration for configuration instructions.
The JBoss Portlet Bridge project is also actively developing extensions that enhance or bring together features of JBoss Portal, Seam, and Richfaces. For example, the PortalIdentity seam component allows you to drop the jar in your classpath and you instantly have SSO between Seam and Portal. This extension can also be configured with additional attributes in your Seam application's components.xml file.
Don't forget that the bridge is still in Beta and so are any extensions. If you would like to contribute to any part of this project, we encourage you to be active on the user forum and bring issues/enhancements to attention.
An updated list of extensions can be located on the JBPB wiki
Current version and compatibilty information can be easily located on the JBPB wiki. Ensure you are using compatible versions of all integrated frameworks before you begin.
Easy Setup JBoss Portal provides it's latest distribution included in JBoss Application Server. All of the guesswork has been eliminated so that you can unzip and run Portal with a few clicks. Get the latest here (ensure you choose the JBoss Portal + JBoss AS link)
Next, all that is left is download the JBoss Portlet Bridge distribution and cofigure your portlet to use the bridge. Or, you can run a provided archetype Section 1.1, “Maven Archetypes” and deploy the generated war in a few easy steps. This will also give you an empty project to play around with or start from scratch.
For system requirements and setting up your JBoss Portal environment see the reference guide.
The JBPB project utilizes Maven archetypes which allow you get up and running with different flavors of the bridge quickly.
Archetype | Command | |||
---|---|---|---|---|
RichFaces Basic |
mvn archetype:generate -DarchetypeGroupId=org.jboss.portletbridge.archetypes -DarchetypeArtifactId=richfaces-basic -DarchetypeVersion=1.0.0.B2 -DgroupId=org.whatever.project -DartifactId=myprojectname -DarchetypeRepository=http://repository.jboss.org/maven2/ |
Table 1.1. Available Archetypes
The 301 specification is aimed at making the developers life as easy as possible with JSF+Portlet development. You will see below that there are minimal settings to getting any JSF web application up and running in the Portal environment.
These are the exact same settings for any JSR-301 portlet.
<portlet> <portlet-name>yourPortletName</portlet-name> <portlet-class> javax.portlet.faces.GenericFacesPortlet </portlet-class> <init-param> <name>javax.portlet.faces.defaultViewId.view</name> <value>/welcome.xhtml</value> </init-param> <init-param> <name>javax.portlet.faces.defaultViewId.edit</name> <value>/jsf/edit.xhtml</value> </init-param> <init-param> <name>javax.portlet.faces.defaultViewId.help</name> <value>/jsf/help.xhtml</value> </init-param>
When preserveActionParams is set to TRUE, the bridge must maintain any request parameters assigned during the portlet's action request. The request parameters are maintained in the"bridge request scope". When this attribute isn't present or is FALSE the action's request parameters are only maintained for the duration of theportlet request scope.
<init-param> <param-name>javax.portlet.faces.preserveActionParams</param-name> <param-value>true</param-value> <init-param>
The PortletViewHandler ensures that each JSF portlet instance is porperly namespaced.
<faces-config> <application> <view-handler> org.jboss.portletbridge.application.PortletViewHandler </view-handler> </application> <factory> <faces-context-factory> org.jboss.portletbridge.context.FacesContextFactoryImpl </faces-context-factory> </factory>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> ... <!-- This is optional parameters for a facelets based application --> <context-param> <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name> <param-value>org.jboss.portletbridge.application.FaceletPortletViewHandler</param-value> </context-param>
ALWAYS_DELEGATE
Indicates the bridge should not render the view itself but rather always delegate the rendering.
NEVER_DELEGATE
Indicates the bridge should always render the view itself and never delegate.
DEFAULT
Directs the bridge to first delegate the render and if and only if an Exception is thrown then
render the view based on its own logic. If the configuration parameter is not present or has an
invalid value the bridge renders using default behavior. I.e. as if DEFAULT is set.
<context-param> <param-name>javax.portlet.faces.renderPolicy</param-name> <param-value> ALWAYS_DELEGATE </param-value> </context-param>
The following configuration is designated for portlets using the RichFaces library. These settings will vary based on your individual needs. See this section of the RichFaces documentation for more details.
<context-param> <param-name>org.richfaces.LoadStyleStrategy</param-name> <param-value>NONE</param-value> </context-param> <context-param> <param-name>org.richfaces.LoadScriptStrategy</param-name> <param-value>NONE</param-value> </context-param>
The org.ajax4jsf.RESOURCE_URI_PREFIX
configuration
cross references a setting in your jboss-portal.xml
file (see below). These settings
are required for RichFaces.
<context-param> <param-name>org.ajax4jsf.RESOURCE_URI_PREFIX</param-name> <param-value>rfRes</param-value> </context-param> <filter> <display-name>Ajax4jsf Filter</display-name> <filter-name>ajax4jsf</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>ajax4jsf</filter-name> <servlet-name>FacesServlet</servlet-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> ... </web-app>
To avoid scripts loading more than once from different portlet windows you can define additional scripts in jboss-portlet.xml. *Note the "rfRes" URI prefix that is mapped in the web.xml.
<portlet> <portlet-name>ajaxPortlet</portlet-name> <header-content> <script src="/faces/rfRes/org/ajax4jsf/framework.pack.js" type="text/javascript"></script> <script src="/faces/rfRes/org/richfaces/ui.pack.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="/faces/rfRes/org/richfaces/skin.xcss"/> </header-content> </portlet>
Richfaces JSR-301 bridge can be used with a any compatible implementation ( for example, MyFaces implementation). Simply put the following into web.xml :
<context-param> <param-name>javax.portlet.faces.BridgeImplClass</param-name> <param-value>org.apache.myfaces.portlet.faces.bridge.BridgeImpl</param-value> </context-param>
The ExceptionHandler is used to clean Seam contexts and transactions after errors.
<context-param> <param-name>org.jboss.portletbridge.ExceptionHandler</param-name> <param-value> org.jboss.portletbridge.SeamExceptionHandlerImpl </param-value> </context-param>
There is workaround for Seam 2.0.0/2.0.1 distributions. This is not needed for Seam 2.1.x releases.
<context-param> <param-name>javax.faces.LIFECYCLE_ID</param-name> <param-value>SEAM_PORTLET</param-value> </context-param>