HelloWorld Spring Portlet MVC Framework 3.0.1

Spring Portlet MVC Framework 3.0.1 has support for developing Portlet Specification 2.0 compliant portlets.

I want to learn about how to use Spring for developing Portlet Specification 2.0 compliant so i built this HelloWorld portlet. This portlet is very simple, it has one Controller for handling all View mode related requests ant that controller sets a string in request object and forwards control to JSP for displaying markup, but i am using it as starting point. You can download the sample code from here and follow these steps to create your own portlet


  1. First download the Spring Framework 3.0.2 from the Spring Framework Site

  2. Create a portlet and copy following jars in the WEB-INF/lib folder of your portlet, you can download the sample portlet from here and copy these jars from it

    • aopalliance-1.0.jar

    • commons-logging-1.1.1.jar

    • spring-aop-3.0.2.jar
    • spring-asm-3.0.2.RELEASE.jar

    • spring-beans-3.0.2.RELEASE.jar

    • spring-context-3.0.2.RELEASE.jar

    • spring-context-support-3.0.2.RELEASE.jar

    • spring-core-3.0.2.RELEASE.jar

    • spring-expression-3.0.2.RELEASE.jar

    • spring-web-3.0.2.RELEASE.jar

    • spring-webmvc-3.0.2.RELEASE.jar

    • spring-webmvc-portlet-3.0.2.RELEASE.jar


    If your using the Apache Maven as build tool then you can add following dependencies for your project and it will take care of downloading and packaging appropriate jars

    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
    <scope>compile</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc-portlet</artifactId>
    <version>${spring.version}</version>
    <scope>compile</scope>
    </dependency>
    </dependencies>



  3. Next step is to add org.springframework.web.portlet.DispatcherPortlet portlet in your portlet.xml like this. The DispatcherPorltet is Controller portlet and responsible for handling every portlet request

    <?xml version="1.0" encoding="UTF-8"?>
    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
    version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
    http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
    <portlet>
    <portlet-name>HelloSpring31Portlet</portlet-name>
    <display-name>Hello Spring 31 Portlet</display-name>
    <portlet-class>org.springframework.web.portlet.DispatcherPortlet
    </portlet-class>

    <expiration-cache>0</expiration-cache>
    <supports>
    <mime-type>text/html</mime-type>
    <portlet-mode>view</portlet-mode>
    </supports>
    <portlet-info>
    <title>Hello Spring 31 Portlet</title>
    <short-title>Hello Spring 31 Portlet</short-title>
    <keywords>Hello Spring 31 Portlet</keywords>
    </portlet-info>
    </portlet>
    </portlet-app>


  4. Now change your web.xml and add org.springframework.web.servlet.ViewRendererServlet to it like this, this step would make sure that you can use the Spring View layer in your portlet

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4"
    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">
    <display-name>HelloSpring31Portlet</display-name>
    <servlet>
    <servlet-name>ViewRendererServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>ViewRendererServlet</servlet-name>
    <url-pattern>/WEB-INF/servlet/view</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    </web-app>


  5. The next step is to create a Spring configuration file in the WEB-INF directory, the name of the file should be HelloSpring31Portlet-portlet.xml, basic idea is name of the configuration file should <portletname>-portlet.xml, where portletname is defined in portlet.xml,

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    <bean id="helloSpring31Action"
    class="com.webspherenotes.mvc.spring.action.HelloSpring31Action" />
    <bean id="portletModeHandlerMapping"
    class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
    <property name="order" value="1" />
    <property name="portletModeMap">
    <map>
    <entry key="view">
    <ref bean="helloSpring31Action" />
    </entry>
    </map>
    </property>
    </bean>
    <bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass">
    <value>org.springframework.web.servlet.view.JstlView</value>
    </property>
    <property name="prefix">
    <value>/WEB-INF/jsp/</value>
    </property>
    <property name="suffix">
    <value>.jsp</value>
    </property>
    </bean>
    </beans>

    This file has following 3 bean definitions

    • com.webspherenotes.mvc.spring.action.HelloSpring31Action This is Controller or Action class that i am going to develop next

    • org.springframework.web.portlet.handler.PortletModeHandlerMapping This bean is used for mapping controller class to the mode, It allows you to map only one Controller or Action class for every mode, in our sample code i am mapping helloSpring31Action to the VIEW mode, that means whenever this portlet gets called in VIEW mode it will pass control to helloSpring31Action for generating response

    • org.springframework.web.servlet.view.InternalResourceViewResolver: This bean is used for resolving a resource, In our case i am saying that i am going to use JSPs for view i.e. genearting markup and all my JSPs are placed inside WEB-INF/jsp folder, so i am setting value of prefix attribute to WEB-INF/jsp the value of suffix attribute is .jsp that means the extension for all my JSP file. Now inside my controller class when i forward control to ModelAndView("hello"), it will take that value and forward control to /WEB-INF/jsp/hello.jsp for generating markup



  6. Next create applicationContext.xml file in your WEB-INF folder, it will be valid spring configuration file like this but wont have any bean definition. Every Spring Web MVC application will look for it and will fail if its not able to find this file. You can use it to define application level beans

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    </bean>
    </beans>


  7. Next create HelloSpring31Action class like this

    package com.webspherenotes.mvc.spring.action;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;
    import org.springframework.web.portlet.ModelAndView;
    import org.springframework.web.portlet.mvc.AbstractController;
    public class HelloSpring31Action extends AbstractController{
    protected ModelAndView handleRenderRequestInternal(RenderRequest request,
    RenderResponse response) throws Exception {
    System.out.println("Entering HelloSpring31Action.handleRenderRequestInternal()");
    ModelAndView modelAndView = new ModelAndView("hello");
    modelAndView.addObject("userName", "Sunil");

    System.out.println("Exiting HelloSpring31Action.handleRenderRequestInternal()");
    return modelAndView;
    }
    }

    As you can see the HelloSpring31Action class extends org.springframework.web.portlet.mvc.AbstractController class and implements handleRenderRequestInternal method, inside this method i am not executing any business logic instead i am creating object of ModelAndView, setting userName attribute to it and then forwarding control to hello.jsp. Inside the hello.jsp the userName object would be available in renderRequest

  8. Last step is to create hello.jsp inside /WEB-INF/jsp folder like this

    &tl;%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" session="false"%≷
    <%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%≷
    <portlet:defineObjects /≷
    <h1≷Hello From Hello Spring 2.0.8 &tl;%=renderRequest.getAttribute("userName") %≷ < /h1≷

    The hello.jsp is very simple only thing that it does is read value of userName attribute set by HelloSpring31Action from renderRequest and display it to user,



3 comments:

Anonymous said...

Thanks for this short start-up article. Helped me find my initial footing in the world of spring portlets.

Ranga Reddy said...

Hi It is very useful for me. But i have a small doubt. You are not given proper way how to deploy this application. Can you provide how to deploy this application in tomcat.

Karan Aggarwal said...

Hi SUnil thanks for the article. But can I keep spring jars outside the ear means on PortalServer/shared/app folder. I am trying to achieve this but somehow webapp is not recognizing any spring jar available un share/app folder.