Streamline Your Portlet Development with MVCPortlet Framework Blog



    The MVCPortlet Framework and the MVC Pattern
    ControllerPortletLifecycle/Control Flow
       Portlet Initialization
       Render Request Processing
       Action Request Processing
    Portlet Development Example
       Defining Render Types
       Defining Action Types
       Setting Up Access Control
       ConfiguringRenderProcessors andActionProcessors
       Forms and Input Validation
       Writing JSP Files
       Portlet Deployment

    The Model-View-Controller (MVC) pattern is one of the most commonly used patterns for designing complex web applications. Several MVC frameworks (e.g., Struts) exist for building servlet-based web applications, but these frameworks do not support portlet development. This article provides an overview of MVCPortlet, a framework that addresses this need.

    MVCPortlet is a framework for developing JSR-168-compliant portlets using a pattern similar to MVC. The framework provides aControllerPortlet that receives allprocessAction() and render() requests. A request is delegated to a processor that implements the business logic for a specific request type. The processors may manipulate the model by directly accessing a relational database or via Java/EJBs. The view is generated by forwarding the render requests to JSPs.

    Features offered by MVCPortlet framework at the time of writing this article include:

    • Support for the JSR 168 standard
    • Server- and client-side input validation
    • Internationalization
    • Extensible permissioning module for action/render type level access control
    • No coding required for simple database-driven portlets
    • Device-specific display generation (XHTML/WAP/HTML)
    • Tag library for navigation, form elements
    • Support for seamless file uploads

    Please note that this article assumes familiarity with concepts related to portlets and the JSR 168 standard. Uninitiated readers are strongly recommended to read at least the JSR 168 standards specification before going further.

    The MVCPortlet Framework and the MVC Pattern

    The main idea behind the MVC design pattern is the separation of

    • The system state (Model)
    • The mechanism used to pass on model manipulation requests (Controller)
    • The presentation (Views)

    Decomposing the system in this fashion helps in maintaining system integrity while providing multiple ways of viewing and editing the system.


    The Model in an MVC-based system maintains system state and provides operations to manipulate that state. Model state is commonly stored in a relational database. Two-tier systems use database's SQL interface to manipulate the state. Most of the newer implementations create an object-oriented abstraction layer that represents the model.

    The current release of MVCPortlet providesActionProcessor and RenderProcessorimplementations that perform the database operations used in a typical data-driven application. In the future we will add the ability to work with Java Beans and EJBs. In any case, larger applications should have their own business objects that implement the model independent of any external framework. In such cases, the processor classes would simply delegate the real work to these business objects.


    The View portion of a MVCPortlet-based application is commonly constructed using JSP technology. Technically, you can also include output generated by plain HTML files or other servlets. MVCPortlet provides a number of JSP tags geared towards use of JSPs in portlet-based applications. MVCPortlet tags facilitate internationalization, form input element generation, creation of navigation links, etc. Developers can also leverage all of the features available in standard JSP technologies, but one has to operate within the constraints and guidelines imposed by the portlet API specification. For example, request parameters must not be obtained from the request object available in a JSP page. The parameters must be accessed from theRenderRequest object that is available either via the request attribute javax.portlet.renderRequest or by using a defineObjects tag that defines arenderRequest system variable.


    The Controller portion of MVCPortlet, theControllerPortlet class, handles all incomingprocessAction() and render() requests. In both methods, the controller selects a processor based on a request parameter named request_type. The association between request type and a processor is defined in theportlet-config.xml file, typically located at the top level in the portlet base directory. The render() method delegates incoming requests to objects implementingcom.nabhinc.portlet.mvcportlet.core.RenderProcessorinterface. The processAction() method delegates requests to objects implementing thecom.nabhinc.portlet.mvcportlet.ActionProcessorinterface. Processors return a logical name indicating the result of their execution. The configuration file maps the logical name to the JSP file responsible for generating the display for the current request type. ControllerPortlet includes content generated by this JSP file to complete the request processing.

    ControllerPortletLifecycle/Control Flow

    In most cases, developing a portlet application using MVCPortlet simply involves configuring and installing an instance ofControllerPortlet. This section presents an overview of the lifecycle of such a portlet application, including initialization, the handling of render() andprocessAction() methods, and portlet destruction.

    Portlet Initialization

    ControllerPortlet initialization mainly consists of reading portlet configuration files and constructing instances of supporting classes needed for portlet operation.ControllerPortlet expects at least one parameter,configFile, in its portlet configuration, defined in the portlet.xml file. The value of this parameter must be the context-relative path for the portlet configuration file. In addition, you can also specify the messageFileparameter. This parameter specifies the location of the file that defines internationalized message strings. If this path starts with a "/", then it is assumed to be relative to the web application root directory. Otherwise, it is assumed to be in the portlet base directory specified in the portlet configuration file.

    Render Request Processing

    The portlet container invokes the render() method on ControllerPortlet whenever a page containing the portlet is loaded. Figure 1 shows the high-level steps in generating markup during this method. WhenControllerPortlet receives a render request, it first looks at the request type, i.e., the value of therequest_type parameter. It checks if the current caller has the necessary permission to access the current request type. The MVCPortlet framework offers a very expressive permissioning mechanism that allows access control based on user IDs, client IP, roles, relationships, etc. APortletSecurityException is thrown if the client does not have access for the current request type.

    Figure 1
    Figure 1. Steps in render request processing

    If there is a RenderProcessor associated with this request type, ControllerPortlet invokes theprocess method on the RenderProcessor. The process method can choose to return a key that specifies the next step in business logic execution. The key can either map to an include path or to anotherRenderProcessor. The mapping is specified in theportlet-config.xml file for that portlet. This feature can be used to quickly assemble business functionality from a set of reusable RenderProcessor components.

    If the key returned by a RenderProcessor maps to an include path, we move on to the view generation step. Portlet developers can specify a client-specific mapping for such a key. At the time of this writing, the framework allows the generation of HTML, WML, and XHTML Mobile Profile displays. Typically, these will be JSP files that generate the requested markup based on request attributes and parameters set by the RenderProcessorobjects for the current request type.

    Action Request Processing

    Execution of the processAction() method (depicted in Figure 2) is similar to the render requests. It begins with a permission check for the current request type, identified by the request_type request parameter. If there is a form associated with the current request type, the form fields are validated. A series of ActionProcessorobjects can be chained together to execute the business logic in a manner similar to the chaining of RenderRequestobjects in the render() method. After the lastActionProcessor finishes its request handling, the processor result key is mapped to either a request redirect or a render type. In case of a redirect, the portlet container will redirect the current request to the specified URL. In case of a render type, the render parameter request_type is set to that value. This value will specify the request type in the subsequent render requests on the portlet showing the results of the current action.

    Figure 2
    Figure 2. Steps in action request processing


    The portlet container calls the destroy() method on a ControllerPortlet instance at the end of its lifecycle. This method in turn calls the destroy()method on all registered ActionProcessor andRenderProcessor objects. This method can be used to release any resources that are acquired by processor objects.

    Portlet Development Example

    To illustrate the portlet development process, we consider the steps involved in creating the FAQ portlet included in MVCPortlet distribution. Figure 3 shows the home page for the FAQ portlet inVIEW mode. The home page shows a list of FAQ categories. When the user clicks on a category, questions and answers belonging to the category are displayed, as shown in Figure 4.

    Figure 3
    Figure 3. FAQ portlet home page (VIEWmode)

    Figure 4
    Figure 4. FAQ portlet questions page (VIEWmode)

    Defining Render Types

    The first step in portlet development is to figure out the portlet modes and render types to be supported by the portlet. In this case, our portlet needs to support a VIEW mode and an ADMIN mode. The portlet will display the FAQ information as shown in Figures 3 and 4 in the VIEWmode. ADMIN mode will allow the manipulation of FAQ categories and questions. Note that the admin screens are not included in this article to keep it concise. The view mode supports the following render types:

    • ViewIndex: Portlet home page that displays a list of FAQ categories.
    • ViewCategory: Page displaying questions and answers belonging to the specified category.
    The ADMIN mode needs to support the following render types:
    • AdminIndex: Home page for ADMIN mode. Provides links for creation, deletion, and editing categories.
    • CreateCategory: Displays a form for creating a new FAQ category.
    • EditCategory: Displays a form for editing an existing category.
    • EditQuestions: Main page for manipulating questions belonging to a category.
    • CreateQuestion: Displays a form for creating a FAQ question.
    • EditQuestion: Displays a form for editing a FAQ question.

    The corresponding configuration in the portlet-config.xmlfile is shown in Listing 1. Notice that the JSP file used for generating portlet markup is specified by theinclude-path element. The directory path for the JSP file is specified by the base-dir element (not shown in the listing). In addition, there is a navigation node assigned to each render type, as specified in the nav element. Discussion of navigation implementation is out of scope for this article, but interested readers can look up the MVCPortlet User Guide for more details.

     <render-types> <render-type name="ViewIndex"> <nav label="faq.view_index_header" reset="true" /> <include-path name="default" path="ViewIndex.jsp" /> </render-type> <render-type name="ViewCategory"> <nav label="faq.view_category_header" idParam="cat_id" nameParam="cat_title" /> <include-path path="ViewCategory.jsp" /> </render-type> <render-type name="EditCategory" portletMode="admin"> <nav label="faq.edit_category_header" idParam="cat_id" nameParam="cat_title" /> <include-path path="EditCategory.jsp" /> </render-type> <render-type name="CreateCategory" portletMode="admin" preCondition="admin"> <nav label="faq.create_category_header" /> <include-path path="CreateCategory.jsp" /> </render-type> <render-type name="AdminIndex" portletMode="admin" preCondition="admin" > <nav label="faq.admin_index_header" reset="true" /> <include-path name="default" path="AdminIndex.jsp" /> </render-type> <render-type name="EditQuestions" portletMode="admin" preCondition="admin" > <nav label="faq.edit_questions_header" idParam="cat_id" nameParam="cat_title" /> <include-path path="EditQuestions.jsp" /> </render-type> <render-type name="EditQuestion" portletMode="admin" preCondition="admin" > <nav label="faq.edit_question_header" idParam="q_id" nameParam="q_title" /> <include-path path="EditQuestion.jsp" /> </render-type> <render-type name="CreateQuestion" portletMode="admin" preCondition="admin" > <nav label="faq.create_question_header" /> <include-path path="CreateQuestion.jsp" /> </render-type> </render-types>

    Listing 1. Configuration of FAQ portlet render types

    Defining Action Types

    Category and question data used by the FAQ portlet is stored in a relational database, and implementing admin functionality requires a number of action types that create, delete, and modify database records. These action types are passed toprocessAction() method via the request parameterrequest_type. We need the following action types in the FAQ portlet:

    • CreateCategory: Create a new category record.
    • UpdateCategory: Update category information.
    • DeleteCategory: Delete a category record.
    • EditCategory: Used to populate the render parameters for the subsequent EditCategory render request.
    • CreateQuestion: Create a new question record.
    • UpdateQuestion: Update question information.
    • DeleteQuestion: Delete a question record.
    • EditQuestion: Used to populate the render parameters for the subsequent EditQuestion render request.

    A fragment of the configuration for the action types listed above is shown in Listing 2. Let's look at the configuration of the action type CreateCategory to understand this process. The action processor for this type returns the key "success" if a new category record is successfully created. The configuration maps the key "success" to the render type AdminIndex. If the CreateCategory action succeeds, the render type will be set to AdminIndex, showing in the admin home page to the user. If there is a form validation error, the render type will be set to CreateCategory. This will result in the category creation form displayed along with the form validation error message. If the user cancels the operation, s/he will be taken back to the admin home page, as specified by the mapping for the key cancel.

     <action-types> <action-type name="CreateCategory" form="category" preCondition="admin" > <processor-result-mapping key="success" value="AdminIndex" message="faq.create_category_success_message" /> <processor-result-mapping key="cancel" value="AdminIndex" /> <processor-result-mapping key="validation-error" value="CreateCategory" /> </action-type> <action-type name="DeleteCategory" preCondition="admin" > <processor-result-mapping key="success" value="AdminIndex" /> <processor-result-mapping key="check-error" value="QuestionsExistError" /> </action-type> : : : </action-types>

    Listing 2. Configuration of FAQ portlet action types

    Setting Up Access Control

    MVCPortlet allows portlet deployers to specify access control for each render or action type. The configuration file has a separate section that defines named access control conditions. The permissions section for the FAQ portlet is shown in Listing 3. The configuration defines one precondition that allows access only for the user admin. For the FAQ portlet, we want to allow anyone to view non-admin functionality; i.e., render types corresponding to the VIEW mode. All other screens and actions should only be accessible to the user admin. This is achieved by specifying admin as the precondition name specified by thepreCondition attribute of applicable render and action types.

     <pre-conditions> <pre-condition name="admin" class="com.nabhinc.rules.UserPrecondition"> <users>admin</users> </pre-condition> </pre-conditions>

    Listing 3. Permissions configuration for the FAQ portlet

    ConfiguringRenderProcessors andActionProcessors

    The MVCPortlet framework provides a number of built-in processors for performing database-related operations. In many cases, including the above FAQ portlet, you can develop fully functional portlets without writing any Java code. As a result, implementing the business logic of a portlet is reduced to simply configuring existing processors. Configuration and mapping ofActionProcessors and RenderProcessors is very similar. A fragment of RenderProcessorconfiguration for the FAQ portlet is shown in Listing 4. The fragment shows the RenderProcessor for the render typeViewIndex. The render processor name isViewIndex, which allows MVCPortlet to associate it with the render type with the same name. The configuration specifies the SelectRecords render processor that retrieves a vector of database records and sets the attributemvcportlet.records to the record vector. The SQL for fetching the records is specified in <sql>element specified in the processor configuration.

     <render-processors> <render-processor name="ViewIndex" class="com.nabhinc.portlet.mvcportlet.renderprocessor.SelectRecords"> <sql>SELECT catid, cattitle, catrank FROM SB_FAQ_CATEGORIES ORDER BY catrank</sql> </render-processor> : : </render-processors>

    Listing 4. ViewIndexRenderProcessor configuration

    Forms and Input Validation

    The FAQ portlet requires user input when a category/question is being created or edited. Correspondingly, we have a form for accepting category information and a form for accepting question information. Listing 5 shows the forms configuration for the FAQ portlet. The configuration defines two forms: categoryand question. A form is associated with an action type by specifying its name in the form attribute of the<action-type> element, as shown inCreateCategory action type configuration shown in Listing 2.

     <forms> <form name="category"> <field name="cat_id" /> <field name="cat_title" validators="required,maxNameLength" /> <field name="cat_rank" validators="int" default="0" /> </form> <form name="question"> <field name="cat_id" /> <field name="q_id" /> <field name="q_title" validators="required,maxNameLength" /> <field name="q_answer" validators="required,maxDescrLength" /> <field name="q_rank" validators="int" default="0" /> </form> </forms>

    Listing 5. Forms configuration for the FAQ portlet

    The form named category defines three fields: category ID, category title, and category rank. Each field is optionally associated with one or more validators. For example, the field cat_title references two validators namedrequired and maxNameLength, respectively. This is specified as a comma-delimited list in thevalidators attribute of the <field>element. The validators configuration section defines corresponding validators, as shown in Listing 6. Each validator has a name that must match the name specified in the form configuration. In addition, a validator can have additional attributes and sub-elements specific to that validator. For example, themaxNameLength validator uses the validator classcom.nabhinc.portlet.mvcportlet.validator.MaxLengthValidatorwith a configuration attribute, maxLength, that provides the maximum length for the form field value.

     <validators> <validator name="required" class="com.nabhinc.portlet.mvcportlet.validator.RequiredValidator" /> <validator name="int" class="com.nabhinc.portlet.mvcportlet.validator.IntegerValidator" /> <validator name="maxNameLength" class="com.nabhinc.portlet.mvcportlet.validator.MaxLengthValidator" maxLength="100" /> <validator name="maxDescrLength" class="com.nabhinc.portlet.mvcportlet.validator.MaxLengthValidator" maxLength="4000" /> </validators>

    Listing 6. Validators configuration for the FAQ portlet

    Writing JSP Files

    JSP files used to generate markup fragments can use all available aids, such as JSP tag libraries. The MVCPortlet framework provides a tag library and helper JSPs to facilitate this task. As an example, consider the JSP file shown in Listing 7 that displays the category creation form. The file first includes a helper JSP file, nav.jsp. This JSP file inserts various information messages set by Action/RenderProcessorobjects invoked during the current requests. It also inserts navigation links at the top of the page. The file also uses a number of JSP tags provided by the MVCPortlet framework, including:

    • <mp:form>: This tag results in an HTML form tag with the form action set to the action URL for the current portlet. In addition, if the attributevalidationMethod is specified, it generates client-side validation code for form fields.
    • <mp:formLabel>: This tag produces internationalized form field labels. If there was a validation error for the named form field, it also highlights those fields, depending on the portal theme styles.
    • <mp:input>: This tag generates a text input field and populates it based on the corresponding render parameter.
     <%@include file="../include/nav.jsp" %> <% String catTitle = rReq.getParameter("cat_title"); if (catTitle == null) catTitle = ""; String catRank = rReq.getParameter("cat_rank"); if (catRank == null) catRank = "0"; PortletURL actionURL = rRes.createActionURL(); %> <table width="100%"> <mp:form name="category" validationMethod="validateCreateCategory"> <input type="hidden" name="request_type" value="CreateCategory" /> <tr> <td class="portlet-font"> <b><mp:formLabel key="faq.title_label" name="cat_title" /></b> </td> <td class="portlet-font"> <mp:input name="cat_title" /> </td> </tr> <tr> <td class="portlet-font"> <b><mp:formLabel key="faq.rank_label" name="cat_rank" /></b> </td> <td class="portlet-font"> <mp:input name="cat_rank" /> </td> </tr> <tr> <td class="portlet-font" align="right" colspan="2"> <br/> <mp:submit value="faq.create_category_button"/>  <mp:cancel value="mvcportlet.cancel_button" />  </td> </mp:form> </table>

    Listing 7. Example JSP

    Portlet Deployment

    At this point we have completed all portlet development tasks and the FAQ portlet is ready for deployment. Actual deployment steps will, of course, depend on the chosen portal server. We tested the FAQ portlet in Stringbeans, an open source portal server. To deploy the FAQ portlet in this container, a portlet entry (shown in Listing 8) is copied to the portlet.xml file located in WEB-INF directory of the portal web application. We then copied all JSP and configuration files to theportlets/faq directory under the web application root, and restarted the server. Finally, we added the portlet to an appropriate portal page to complete the portlet development and deployment process.

     <portlet> <description>Displays Site FAQ.</description> <portlet-name>FAQ</portlet-name> <portlet-class> com.nabhinc.portlet.mvcportlet.core.ControllerPortlet </portlet-class> <init-param> <name>configFile</name> <value>/portlets/faq/portlet-config.xml</value> </init-param> <supports> <mime-type>text/html</mime-type> <portlet-mode>ADMIN</portlet-mode> </supports> <supports> <mime-type> application/vnd.wap.xhtml+xml </mime-type> </supports> <portlet-info> <title>Frequently Asked Questions</title> <keywords>Collaboration</keywords> </portlet-info> </portlet>

    Listing 8. FAQ portlet configuration in portlet.xml