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.
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.
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.