Integrate struts 2 in Liferay portlet

Liferay is a Open Source Content Management System and it’s popularity increasing day by day  but there are no much tutorials on this. Sometimes we find some examples but it may not work exactly the way have been written in the websites. Sometimes the tutorial steps have not been started from the scratch and it results confusion. I am going to give an example here step by step on how to integrate struts2 with liferay portlet or plugin project. I have extracted it from the Original Tutorial.

There are two modes in the original post but I have only worked with “edit” mode. I also had many confusions when I first read the original post and it did not work for me so I decided to jot down here.
1. First create a Liferay Plugin Project. Go to File->New->Other. Select from wizard Liferay->Liferay Plugin Project.

Input the mandatory fields as shown below and click Next.
struts 2 integration example with liferay
2. Select Liferay MVC in the next screen as shown below. Click Finish.
struts 2 integration example with liferay

3. Now you will see skeleton for the project will be generated. Now download the corresponding jars and put under WEB-INF/lib directory as show below in the screen-shot.
struts 2 integration example with liferay

4. Modify the web.xml file as given 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">
<listener>
<listener-class>com.liferay.portal.kernel.spring.context.PortletContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>struts2servlet</servlet-name>
<servlet-class>org.apache.struts2.dispatcher.ng.servlet.StrutsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>struts2servlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>struts2Resources</servlet-name>
<servlet-class>org.apache.struts2.dispatcher.ng.servlet.StrutsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>struts2Resources</servlet-name>
<url-pattern>/struts/*</url-pattern>
</servlet-mapping>
</web-app>

 
5. modify portlet.xml as shown below

<?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>Struts2</portlet-name>
<display-name>Struts2</display-name>
<!-- use struts2 portlet instead of liferay mvc portlet -->
<portlet-class>org.apache.struts2.portlet.dispatcher.Jsr168Dispatcher</portlet-class>
<!-- The namespace for the actions configured for edit mode -->
<init-param>
<name>editNamespace</name>
<value>/edit</value>
</init-param>
<!-- The default action to invoke in edit mode. -->
<init-param>
<name>defaultEditAction</name>
<value>index</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>edit</portlet-mode>
</supports>
<portlet-info>
<title>Struts2</title>
<short-title>Struts2</short-title>
<keywords>Struts2</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>

 
6. create a domain or model object Bookmark.java

public class Bookmark {
private String name;
private String url;
public Bookmark(String name, String url) {
this.name = name;
this.url = url;
}
public String getName() {
return name;
}
public String getUrl() {
return url;
}
}

 
7. create action classes for performing CRUD operations

import javax.portlet.PortletPreferences;
import org.apache.struts2.dispatcher.DefaultActionSupport;
import org.apache.struts2.portlet.interceptor.PortletPreferencesAware;
public class AddBookmarkAction extends DefaultActionSupport implements
PortletPreferencesAware {
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private String url;
private PortletPreferences portletPreferences;
public void setName(String name) {
this.name = name;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public void setPortletPreferences(PortletPreferences portletPreferences) {
this.portletPreferences = portletPreferences;
}
@Override
public String execute() throws Exception {
portletPreferences.setValue(name, url);
portletPreferences.store();
return SUCCESS;
}
}
[/java]
[java]
import java.util.Map;
import javax.portlet.PortletPreferences;
import org.apache.struts2.dispatcher.DefaultActionSupport;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.portlet.interceptor.PortletPreferencesAware;
import com.opensymphony.xwork2.Preparable;
public class EditBookmarkAction extends DefaultActionSupport implements
PortletPreferencesAware, Preparable, ParameterAware {
/**
*
*/
private static final long serialVersionUID = 1L;
private String oldName;
private String name;
private String url;
private PortletPreferences portletPreferences;
private Map<String, String[]> parameters;
public String getOldName() {
return oldName;
}
public void setOldName(String oldName) {
this.oldName = oldName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public void setName(String name) {
this.name = name;
}
public void setPortletPreferences(PortletPreferences portletPreferences) {
this.portletPreferences = portletPreferences;
}
public void setParameters(Map<String, String[]> parameters) {
this.parameters = parameters;
}
public void prepare() throws Exception {
// Since the prepare interceptor is run before the parameter
// interceptor,
// we have to get the parameter "manually".
this.oldName = parameters.get("oldName")[0];
this.url = portletPreferences.getValue(oldName, null);
}
public String execute() throws Exception {
// The modification is handled as remove/add
portletPreferences.reset(oldName);
portletPreferences.setValue(name, url);
portletPreferences.store();
return SUCCESS;
}
}

 

import in.sblog.domain.Bookmark;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.portlet.PortletPreferences;
import org.apache.struts2.dispatcher.DefaultActionSupport;
import org.apache.struts2.portlet.interceptor.PortletPreferencesAware;
/**
* @author admin
*
*/
public class ListBookmarksAction extends DefaultActionSupport implements
PortletPreferencesAware {
/**
*
*/
private static final long serialVersionUID = 1L;
private PortletPreferences portletPreferences;
private List<Bookmark> bookmarks = new ArrayList<Bookmark>();
public List<Bookmark> getBookmarks() {
return bookmarks;
}
public void setBookmarks(List<Bookmark> bookmarks) {
this.bookmarks = bookmarks;
}
@Override
public void setPortletPreferences(PortletPreferences portletPreferences) {
this.portletPreferences = portletPreferences;
}
@Override
public String execute() throws Exception {
Map<String, String[]> preferencesMap = portletPreferences.getMap();
for (Map.Entry<String, String[]> entry : preferencesMap.entrySet()) {
bookmarks.add(new Bookmark(entry.getKey(), entry.getValue()[0]));
}
return SUCCESS;
}
}
import javax.portlet.PortletPreferences;
import org.apache.struts2.dispatcher.DefaultActionSupport;
import org.apache.struts2.portlet.interceptor.PortletPreferencesAware;
public class DeleteBookmarkAction extends DefaultActionSupport implements
PortletPreferencesAware {
/**
*
*/
private static final long serialVersionUID = 1L;
private String bookmarkName;
private PortletPreferences portletPreferences;
public void setBookmarkName(String bookmarkName) {
this.bookmarkName = bookmarkName;
}
public void setPortletPreferences(PortletPreferences portletPreferences) {
this.portletPreferences = portletPreferences;
}
@Override
public String execute() throws Exception {
portletPreferences.reset(bookmarkName);
portletPreferences.store();
return SUCCESS;
}
}

 
8. Create nested directories html/edit
9. create two jsp files index.jsp and edit.jsp under html/edit.
index.jsp

<%@ taglib prefix="s" uri="/struts-tags"%>
<h2>Manage bookmarks</h2>
<p>
Total Bookmarks:
<s:property value="bookmarks.size()" />
</p>
<table>
<s:iterator value="bookmarks" status="bookmarkStatus">
<s:url action="editBookmark!input" id="editUrl">
<s:param name="oldName" value="name" />
</s:url>
<s:url action="deleteBookmark" portletUrlType="action" id="deleteUrl">
<s:param name="bookmarkName" value="name" />
</s:url>
<tr>
<td><s:property value="name" /></td>
<td><a href="/jcms/<s:property value="url"/>" target="_blank"><s:property
value="url" /></a></td>
<td><a href="/jcms/<s:property value="editUrl"/>">Edit</a></td>
<td><a href="/jcms/<s:property value="deleteUrl"/>">Delete</a></td>
</tr>
</s:iterator>
</table>
<p />
<s:form action="addBookmark">
<table>
<s:textfield name="name" label="Name" />
<s:textfield name="url" label="URL" />
<s:submit value="Add" />
</table>
</s:form>

 
edit.jsp

<%@ taglib prefix="s" uri="/struts-tags"%>
<h2>Edit bookmark</h2>
<s:form action="editBookmark">
<input type="hidden" name="oldName"
value="<s:property value="oldName"/>" />
<table>
<s:textfield name="name" label="Name" value="oldName" />
<s:textfield name="url" label="URL" />
<s:submit value="Update" />
</table>
</s:form>

 
10. Create struts.xml file and put under src directory

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="edit" extends="struts-portlet-default"
namespace="/edit">
<action name="index" class="in.sblog.action.ListBookmarksAction">
<result>/html/edit/index.jsp</result>
</action>
<action name="addBookmark" class="in.sblog.action.AddBookmarkAction">
<result type="redirectAction">
<param name="actionName">index</param>
</result>
</action>
<action name="deleteBookmark" class="in.sblog.action.DeleteBookmarkAction">
<result type="redirectAction">
<param name="actionName">index</param>
</result>
</action>
<action name="editBookmark" class="in.sblog.action.EditBookmarkAction">
<result type="redirectAction">
<param name="actionName">index</param>
</result>
<result name="input">/html/edit/edit.jsp</result>
</action>
</package>
</struts>

 

11. If everything was fine now deploy the application. Simply drag Struts2-portlet and drop onto the server. You can also deploy the application – do right click on the Struts2-portlet and go to Liferay->SDK->deploy.

12. Now go to http://localhost:8080 and logged in to the Liferay Portal. Go to Add->More…. Under Sample look for Struts2 portlet and add it clicking on “Add” link right to the Struts2 portlet.

struts 2 integration example with liferay

13. Now you see the Struts2 portlet appears onto the body of the Liferay Portal. Now you can manage bookmarks.

Thanks your patience. Please do not forget to leave a comment.

Leave a Reply

Your email address will not be published. Required fields are marked *