• Hello World Spring MVC Portlet with annotations

    Posted on February 16, 2015 by Hamidul Islam in Liferay.

    Spring MVC Portlet


    aimIf you are a Liferay developer then you might have developed portlets in Liferay MVC which is very easy to use and its also very light weight. However Spring MVC is well known framework to develop java based enterprise applications. The Spring MVC not only famous for developing java based web applications but also it can be used in portlet development because of its cool features. By this Hello World Spring MVC Portlet I will try to explain how to create your first Spring Portlet and necessary annotations.


    7 Steps

    Step 1:  At first we will create a simple portlet say its spring-hello-world-portlet by Liferay IDE. After that we will convert it as a spring portlet.

    Step 2:  Open your portlet.xml file. Change the portlet class from com.liferay.util.bridges.mvc.MVCPortlet to  org.springframework.web.portlet.DispatcherPortlet which is shown in below. This step is very important.  Without DispatcherPortlet a portlet can not be a spring portlet.

    Portlet Class Changed

    So after changing the class name your portlet.xml should look like this

    <?xml version="1.0"?>
    
    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" 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" version="2.0">
    	<portlet>
    		<portlet-name>spring-hello-world</portlet-name>
    		<display-name>Spring Hello World</display-name>
    		<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
    		<expiration-cache>0</expiration-cache>
    		<supports>
    			<mime-type>text/html</mime-type>
    		</supports>
    		<portlet-info>
    			<title>Spring Hello World</title>
    			<short-title>Spring Hello World</short-title>
    			<keywords>Spring Hello World</keywords>
    		</portlet-info>
    		<security-role-ref>
    			<role-name>administrator</role-name>
    		</security-role-ref>
    		<security-role-ref>
    			<role-name>guest</role-name>
    		</security-role-ref>
    		<security-role-ref>
    			<role-name>power-user</role-name>
    		</security-role-ref>
    		<security-role-ref>
    			<role-name>user</role-name>
    		</security-role-ref>
    	</portlet>
    </portlet-app>
    

    Explanation:

    Step 3: Spring portlet needs one xml file where we generally define our beans. We need to create this file under WEB-INF directory of the portlet. The name of this xml file is generally depends on the name of the portlet and its format is [portlet-name]-portlet.xml. For example

    i) For the portlet name Spring-MVC the xml file should be SpringMVC-portlet.xml

    ii) For the portlet name spring-hello-world the xml file should be springhelloworld-portlet.xml

    iii) For the portlet name My-Spring-MVC the xml file should be MySpringMVC-portlet.xml

    iv) For the portlet name My-Spring-MVC-portlet the xml file should be MySpringMVCportlet-portlet.xml

    and so on.....Since our portlet name is spring-hello-world, so we will create the file springhelloworld-portlet.xml. At the time of deployment of the portlet

    DispatcherPortlet will try to load this file automatically. If its not found then it will throw exception. 

    Note: If there is hyphen in the portlet name then we have to ignore it while creating the xml file. 

    Step 4: Since we are developing spring portlet so we must have spring dependency in our WEB-INF/lib folder. The good thing is that we are not required to download any jars. Liferay already provides those jars.

    required-jars-for-spring-portlet

    We just need to mention which jars are required. This can be done by adding portal-dependency-jars in liferay-plugin-package.properties which is under WEB-INF directory of the portlet. So mention those jars as below

    name=Spring Hello World
    module-group-id=liferay
    module-incremental-version=1
    tags=
    short-description=
    change-log=
    page-url=http://www.liferay.com
    author=Hamidul Islam
    licenses=LGPL
    portal-dependency-jars=\
        spring-web-portlet.jar,\
        spring-web-servlet.jar,\
        spring-web.jar,\
        spring-context.jar,\
        spring-beans.jar,\
        spring-core.jar,\
        spring-asm.jar,\
        spring-expression.jar,\
        jstl-api.jar
    long-description=
    liferay-versions=6.2.0+
    

    At the time of portlet deployment those dependency will be placed in WEB-INF/lib directory.

    Step 5: In this step update the web.xml as below

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.5"
    	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    	<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>
    </web-app>
    

    Explanation:

    i)ViewRendererServletacts as a bridge between a Portlet request and a Servlet request.

    ii) It allows a Spring Portlet MVC application to leverage the full capabilities of Spring Web MVC for creating, defining, resolving and rendering views.

    iii) Therefore we are able to use the same ViewResolver and View implementations.

    iv) If  ViewRendererServlet is not mentioned in the web.xml then view page wont be displayed.

     Step 6: The xml file springhelloworld-portlet.xml should be updated as 

    <?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:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans</pre>
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd</pre>
    http://www.springframework.org/schema/context
    <pre>
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <pre>
    	<context:component-scan  base-package="com.proliferay.demo.controller" />
    
    	<bean
    		class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    	<bean
    		class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
    
    	<bean id="viewResolver"
    		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="viewClass"
    			value="org.springframework.web.servlet.view.JstlView" />
    		<property name="prefix" value="/WEB-INF/jsp/" />
    		<property name="suffix" value=".jsp" />
    	</bean>
    </beans>
    

    Explanation:

    i)  By  context:component-scan we declaring that scan only particular package or packages for spring annotated files like controller, beans etc . Multiple packages can be separated by comma. 

    ii) DefaultAnnotationHandlerMapping helps DispatcherPortlet to find out the appropriate controller which full fills the request. 

    iii) Spring Controller generally returns logical view. The logical view will be resolved by the viewResolver as shown in the code. For example if the controller returns a string "view" then it will be resolved as view.jsp under  /WEB-INF/jsp/ directory. 

    Step 7: Write a controller 

    A spring controller is a java class which is annotated by @Controller. A spring controller generally handles various request based on certain conditions. We can give any name of the controller. Say its HelloWorldController 

    package com.proliferay.demo.controller;
    
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.portlet.bind.annotation.RenderMapping;
    
    import com.liferay.portal.kernel.log.Log;
    import com.liferay.portal.kernel.log.LogFactoryUtil;
    
    /**
     *
     * @author Hamidul Islam
     *
     */
    @Controller("helloWorldController")
    @RequestMapping(value="VIEW")
    public class HelloWorldController {
    
    	private Log log = LogFactoryUtil.getLog(HelloWorldController.class.getName());
    
    	 @RenderMapping
    	    public String viewHomePage(RenderRequest request, RenderResponse response){
    
    	       log.info("#############################Calling viewHomePage##################################");
    
    	      return "view";
    
    	    }
    }
    

    Explanation:

    i)By @Controller("helloWorldController") we declaring that its a spring controller and helloWorldController is the alias name which is optional. 

    ii) By @RequestMapping(value="VIEW") we are saying this class handles VIEW mode of the portlet. 

    iii) By @RenderMapping we are declaring that the method is render method. 

    iv) The render method returns  a String value "view" which is the logical view and it will be resolved to view.jsp as mentioned in the Step 6

     

     Download Source Code 

4 Responses so far.

  1. sravan says:

    Hi,

    IF i use annotation portlet is working fine, but in themes or web content beans are not populating.

  2. Sandeep says:

    Hi,
    I need the folder structure(project structure)for developing Spring portlet MVC application (without Liferay IDE).
    Can you please help me for simple hello world example.

Top
%d bloggers like this: