Portlet Introduction / Portlet Technology Introduction

Technical Blogs December 4, 2014 By Meera Prince

Portlet is small fragment of dynamic content in the web page. And this dynamic content may be text,HTML,xml or some other MIME format. Portlet technology implemented by JSR 168 and JSR 286 standards.
 
Generally in web application we are very familiar with servlet technology and portlet technology is similar to servlet technology but it consist its own features. servlet technology based on client and server architecture in the web world here the client is browser.
 
Portlets life cycle is managed by portlet containers these are in application servers. portlet life cycle consist different stages like instantiation,serving and destroying. Portlet containers are similar to servlet containers to manage entire life cycle of portlet.

Generally in the portlet technology each page consist one or more portlets and each portlet render dynamic content to make complete web page.
 
In technical understand portlet technology implemented in Java in the package javax.portlet.
 
This portlet API consist many interfaces and implementation classes to developed portlet based application in the web world.
 
How does portlets are differed from servlet
 
Generally in servlet web application each servlet will be referred by URL to invoke or access and each web page content will be served by one servlet but in portlets each page will be served by different portlet and each portlet will have its own lifecycle and own URL pattern to execute.
 
Servlet will generate dynamic content which send to browser and it’s in single web page but portlet will server fragment of dynamic content and portal page is responsible to aggregate content from different portlet to generate whole page.
 
There are many people implemented the portlet technology.
 
Liferay
JetSpeed
Pluto
uPortal
WebLogic
Websphere
Entando
 
Understanding the Portlet Technology
 

Basically we need to following things to run portlet based application


 
JRE
Portlet Container+Application Server
Portlets

 
Portlet Container
 
Portlet containers is responsible for run the portlet and it provides the required run time environment. Portlet containers manage the life cycle of portlets. When ever portal server send the request then portlet containers receive the requests and its invoke the respective portlet to process request means its instantiated the portlet and execute appropriate life cycle methods to prepare response. Portlet container send portlet response back to portal server like that portal server receive responses of different portlets and aggregate all response to complete client request.
 
Application Server
 
Application servers are responsible to process client request and send response back to client. Application server provided different services to manage and run web applications. The services like JMS, JNDI, JTS, JAAS, JDO,Connection Pooling and all these services required by the applications.
 
Application servers integrated with different containers to provide different run time environments like servlet containers to provides run time environment to execute servlets, portlet containers is to provides the run time environment to execute portlet, EJB containers to provided environment to execute Enterprise Java Beans applications.
 
Apart from this application severs have more capabilities to provide different services to run different technology based applications.
 
Portlets
 
As we already know each portlet has it own life cycle and which will be managed by portlet container. According to the JSR 168 standard portlet have three life cycle stages.
 
Basic portlet consist following life cycle stages
 
Portlet life cycle
 
 
init:
 
Initialize the portlet and put the portlet into service
 
Handle requests:
 
Process different kinds of action- and render-requests
 
Destroy:
 
Put portlet out of service
 
Theoretically we have 3 life cycle stages in portlets and these will be implemented via portlet interface. Portlet interface is implemented in javax.portlet package by Sun Microsystems.
 
Every portlet that should implements the portlet interface or it should extend the class that already implemented the portlet interface.
 
As we know portlet have three life cycle staged and the following are interface methods which handle portlet life cycle in portlet implementation.
 
init(PortletConfig config):
 
This method is initialize the portlet and this will be called only once when portlet is instantiated, we can say when we drag and drop portlet in page.
 
If any necessary functionality required at initial time of portlet we will use this method and write code here. It is similar to servlet init method. This method can be used to create expensive objects/resources used by the portlet.
 
processAction(ActionRequest request, ActionResponse response):
 
When user is requested to server then portlet will execute process action method.
This method will notify the portlet that used has triggered an action this portlet. , a portlet can issue a redirect, change its portlet mode or window state, modify its persistent state, or set render parameters.
 
render(RenderRequest request, RenderResponse response):
 
Render method will generate content and that will be send to web client.
In the portal page we have many portlet we have triggered action in one portlet then all portlet will be executed render method to aggregate dynamic content. The portlet can produce markup that may depend on the portlet mode or window state, render parameters, request attributes, persistent state, session data, or backend data.
 
destroy ():
 
Indicate to the portlet the life cycle's end. This method allows the portlet to free up resources and update any persistent data that belongs to this portlet.
 
Note:
 
In the portlet life cycle for each action or request the final method is render method. Render method will be called for every time to aggregate content or produce content.
 
Generally portlet have different URL to call these methods like Action URL and Render URL. 
 
Action URL will execute portlet porcessAction(----) method and then it will be execute the render(----) method.
 
Render URL will execute the portlet render (---) method only. 
 
Portlet Lyfecycle Execution Process 
 
 
 
Portlet Characteristics
 
Portlet have addition Characteristics when we compare with servlet.
 
Portlet Widow States:
 
Portlet has different window states. Window state specifies how portlet will look in the page .Window state decides how much space will be accommodated in portlet page.
 
The following are important window states as for JSR 168 Standards.
 
Maximized:
 
When portlet state is decided as Maximized then entire page only one portlet is visible.
Generally we will use this state after perform some action then we will make widow state is Maximized.
 
Normal:
 
Specified that is portlet may share the page with other portlets. This is the default window state.
 
Minimized:
 
Portlet should only render minimal output or no output at all.
 
Portlet Modes:
 
Portlet mode specifies that the function will be performed by portlet.
Generally following are the portlet modes that each portlet should support as for JSR 168&286 standards.
 
View:
 
This view mode is when portlet is access or render then portlet is in view mode and this is default mode for portlet.
 
Edit:
 
Edit mode will be used to edit some portlet functionality and generally we wil use this mode for administrator to modify or edit something.
 
Help:
 
This will used to provide content to end user about portlet i.e how to use and access portlet like help information. 
 
 
Persistent storage for preferences:
 
Portlets provide a Portlet Preferences object for storing user preferences. These preferences are stored in a persistent data store, so they will be available across server restarts. As a developer, you don't have to worry about the actual implementation of how it is stored.
 
Portlet Sessions:
 
Like Http Session in the portlet technology also have different scopes of session to share data among the portlet or with in the portlet. Portlet also can use Http Session.
 
Portlet Session by default scope is portlet level what ever the data stored in Portlet Session can be available with in portlet. If we want share data among the portlets then we have to use application level scope so that data can be shares across the portlets.
 
Portlet technology have concept called publics render parameters to exchange data among portlets this is we can all it as Inter Portlet Communication.
 
We can use portlet sessions or public render parameters to establish communication among portlets which are in same page.
 
Portal context 
 
 
Portal context provides information such as the portal vendor, the portal version, and specific portal properties. The information allows the portlet to use specific vendor extensions when being called by a portal that supports these extensions and, when being called by other portals, to return to some simpler default behavior.
 
Properties 
 
 
Properties communicate vendor-specific settings between the portlet and portlet container, and between the portlet and the portal. 
 
 
These properties show up in several places in JSR 168. The portlet can read String properties with getProperty() from: 
 
 
ActionRequest, to receive properties that are action-request specific
 
RenderRequest, to receive properties that are render-request specific
 
PortalContext, to receive properties that are portal specific and do not change for different requests 
 
 
The portlet can write String properties with setProperty() to: 
 
 
ActionResponse, to set properties in response to an action request
 
RenderResponse, to set properties in response to a render request
 
Packaging and deployment
 
Portlet are packages as web archive file(WAR) this archive file consist of portlet deployment descriptors, resources and other java libraries which are required by portlets.
 
In the portlet application we have two deployment descriptors that is web.xml and portlet.xml
 
web.xml specifies the things related to web application deployment properties
 
portlet.xml specifies the portlet application related deployment properties and it always describes only one specific portlet application.
 
portlet application deployment is a two-step deployment that deploys the Web application into the application server and the portlets into the portal server.
 
Author

Liferay Requires Name Spaced Parameters

Technical Blogs November 20, 2014 By Meera Prince

When we work with liferay 6.2 portlet development some time we may get null or empty values when we access request parameters or form input values in the portlet action class.
 
The reason is from Liferay 6.2 Portlet Action class only consider the request parameters which should append with portlet name space value. This is default behavior of Liferay 6.2 Portlet Action Class.
 
Example:
 
ParamUtil.getString(uploadPortletRequest, "paramName") ===> empty value
actionRequest.getParameter("paramName") ===> null
 
Same behavior you can see for renderRequst, resourceRequest objects too while accessing request parameters or form inputs in the portlet action class respective methods.
 
What is Portlet Name Space?
 
Portlet Name Space will give unique name to the elements in the page and these elements are associated to respective portlet. This will avoid name conflicts in the page.
We may use many portlets within one page and there may be chance to get name collision among elements in the page. portlet name space will avoid those name conflicts in the page.
 
Each portlet have its own portlet name space value so that we need to append these portlet name space value to each element in the portlet like HTML tag names or ids and we can use this for request parameters.
 
How can i get Portlet Namespace Value?
 
We can use following two ways
 
  1. Using <portlet:namespace/> Tag.
  2. Using renderResponse Object
 
 
Using <portlet:namespace/> Tag.
 
We can use <portlet:namespace/> Tag so that we can append portlet name space value for element names,ids and request parameters.
 
Note :
we need to import respective tag library in the jsp page to use above tag.
 
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
 
Example Code Snippets:
 
<input type="text" name="<portlet:namespace/>employeeName" id="<portlet:namespace/>employeeName"/>
 
<div id="<portlet:namespace/>testDiv">this is div</div>
 
Using renderResponse Object
 
We can also use renderResponse object to get portet Name space value. renderResponse is liferay implicit object and  these Objects will be available in JSP page.

We need to use following tag to get portlet implicit objects and it will be available to JSP page.
 
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<portlet:defineObjects />
 
Example Code Snippets:
 
<input type="text" name="<%=renderResponse.getNamespace()%>employeeName" id="<%=renderResponse.getNamespace()%>employeeName"/>
 
<div id="<%=renderResponse.getNamespace()%>testDiv">this is div</div>
 
 
To avoid name conflicts among portlets element names and ids its recommended portlet name space for each element.
 
 
Liferay Requires Namespaced Parameters
 
Liferay 6.2 we have to append portlet Name space for every name of input element i.e. form input elements or request parameters names otherwise portlet action class ignore the parameters which does not have portlet name space to names. Due to this we will get NULL/Empty values in the portlet action class when we get parameters values from request objects.
 
Solutions
 
We must Use Portlet Name Space Value for Every form Inputs/Request parameters
 
Use <requires-namespaced-parameters> tag value “false” in liferay-portlet.xml
 
 
We must Use Portlet Name Space Value for Every form Inputs/Request parameters
 
When use forms in development we must use portlet name space for each form inputs. We need append portlet name space value to form input name attribute.
 
Example Code Snippets:
 
<input type="text" name="<portlet:namespace/>employeeName" id="<portlet:namespace/>employeeName"/>
 
OR
 
<input type="text" name="<%=renderResponse.getNamespace()%>employeeName" id="<%=renderResponse.getNamespace()%>employeeName"/>
 
OR
 
<aui:input name="employeeName" id="employeeName" label="Emplyee Name"/>
 
Note:
 
When we use aui form tags then portlet name space will be appended automatically and we need not required to append explicitly.
 
Use Request Parameters in Ajax
 
When we want to send request data using Ajax then we have to append portlet name space value to each request parameter then only portlet action class consider those request parameters and we can access request parameter values.
 
Liferay AUI Ajax Call
 
AUI().use('aui-base','aui-io-request', function(A){
//aui ajax call to get updated content
A.io.request('<%=updaContentURL%>',{
dataType: 'json',
method: 'GET',
data: {
<portlet:namespace/>employeeName:employeeName,
<%=renderResponse.getNamespace()%>employeeId:employeeId
},
on: {
success: function() {
// response data will be received here
}
}
});
});
 
jQuery Ajax Call
 
$(document).on('ready',function(){
//jquey aja methos to call server side content
$.ajax({
url: '<%=updaContentURL%>',
dataType: "json",
data:{
<portlet:namespace/>employeeName:employeeName,
<%=renderResponse.getNamespace()%>employeeId:employeeId
 
},
type: "get",
success: function(data){
//here response data will come and we need to update in the page.
},
beforeSend: function(){
// it will execute before Ajax call start
},
complete: function(){
// this method will execute after success method is completed.
},
error: function(){
}
});
 
});
 
 
Use '<requires-namespaced-parameters>' tag value “false” in liferay-portlet.xml
 
Instead of adding portlet name space value to each request parameters we can make false value to <requires-namespaced-parameters> in liferay-portlet.xml then portlet action class consider request parameters even it don't have portlet name space.
 

The following configuration we need to do in liferay-portlet.xml file
 
<requires-namespaced-parameters>false</requires-namespaced-parameters>
 
 
Finally you can access form inputs or request parameters in portlet action class so that we can get values
 
ParamUtil.getString(actionRequest, "paramName") ===>Some Value
actionRequest.getParameter("paramName") ===> Some Value
 
ParamUtil.getString(renderRequest, "paramName") ===>Some Value
renderRequest.getParameter("paramName") ===> Some Value
 
ParamUtil.getString(resourceRequest, "paramName") ===>Some Value
resourceRequest.getParameter("paramName") ===> Some Value
 
Author

Working with Liferay User Roles

Technical Blogs October 18, 2014 By Meera Prince

Liferay  have different types of roles for user. So whenever we develop portlet application we may get need to fetch user roles.
 
The following article will give you more about Liferay Roles
 
 
Generally we have following roles in Liferay
  1. Regular Roles/Portal Roles
  2. Organization Roles
  3. Site Roles
  4. Inherited Roles
Portal Role/Regular Roles
 
Liferay is providing Portal Role/Regular Role for portal level. It’s not specific to anything like Organization, Site or User Group. 
 
This role can be assigned to any user who belongs to any one of Organization, Community/Site or User Group.
 
Generally when we associate Portal Role/Regular Role s to any user then the association can be stored in Users_Roles Mapping Table.
 
To fetch Portal Role/Regular Role we can use RoleLocalServiceUtil.java class and these classes have many service methods which can fetch roles with respect to selected user.
 
We can use following ways to fetch user Portal Role/Regular Roles
 
Use RoleLocalSercviceUtil
 
 
List<Role> userRoles=RoleLocalServiceUtil.getUserRoles(themeDisplay.getUserId());
 
 
Use User Object 
 
 
List<Role> userRoles1=themeDisplay.getUser().getRoles();
 
 
Site Roles 
 
Site Role is one of the types in liferay which is only associated to Site users. This role only we can associate to site users. When we create site role we can use this site role to any used who belongs to any site liferay.
 
When we associate any site roles to user then association will be stored in UserGroupRole table.When ever we want get site roles then we have to use respective service class to access those roles like we need use UserGroupRoleLocalService.java class there we can find many service methods.
 
 
List<UserGroupRole> userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(themeDisplay.getUserId());
List<UserGroupRole> siteRoles = new ArrayList<UserGroupRole>();
for (UserGroupRole userGroupRole : userGroupRoles) {
int roleType = userGroupRole.getRole().getType();
if (roleType == RoleConstants.TYPE_SITE) {
siteRoles.add(userGroupRole);
}
}
 
 
Organization Roles
 
Similar to site role organization role is used for organization users. This role can be associated to any user who belongs to any organization in portal.
 
When we associate any Organization roles to user then association will be stored in UserGroupRole table.When ever we want get Organization roles then we have to use respective service class to access those roles like we need use UserGroupRoleLocalService.java class there we can find many service methods.
 
 
List<UserGroupRole> userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(themeDisplay.getUserId());
List<UserGroupRole> organizationRoles = new ArrayList<UserGroupRole>();
for (UserGroupRole userGroupRole : userGroupRoles) {
int roleType = userGroupRole.getRole().getType();
if (roleType == RoleConstants.TYPE_ORGANIZATION) {
organizationRoles.add(userGroupRole);
}
}
 
 

Inherited Roles
 
Inherited roles really not existed in the liferay but we can see these roles in the user my account page roles section .these roles specially appear when the user can be member of user group which is assigned a role.
 
We can say if any roles which associates with User Group and the user is member of respective user group then role can be visible as part of inherited roles section.
 
Simply we can say that user directly not associated with role instead of that User Group will be associated with role and the user will be member of User Group then the roles are become as inherited role to users who are belong to User Group.
 
Understanding inherited roles
  • Create User Group (Photography) and assign Users to Photography User Group
  • Create role called Photography Group Member
  • Assign User Group to Role( associate role to User Group)
 
Now all users who are belongs to User Group will be get Photography Group Member role as inherited role when we observe here Photography Group Member role is not directly associated with user but role is associated with Photography user group because of this Photography Group Member become as inherited role.
 
When we want fetch inherited roles first we need to find all User Groups of respective user so that we can fetch all inherited roles.
 
 
<%
User selUser=themeDisplay.getUser();
List<Group> allGroups = new ArrayList<Group>();
List<UserGroup> userGroups = selUser.getUserGroups();
List<Group> groups = selUser.getGroups();
List<Organization> organizations = selUser.getOrganizations();
allGroups.addAll(groups);
allGroups.addAll(GroupLocalServiceUtil.
getOrganizationsGroups(organizations));
allGroups.addAll(GroupLocalServiceUtil.
getOrganizationsRelatedGroups(organizations));
allGroups.addAll
(GroupLocalServiceUtil.getUserGroupsGroups(userGroups));
allGroups.addAll(GroupLocalServiceUtil.
getUserGroupsRelatedGroups(userGroups));
for(int i=0;i<allGroups.size();i++){
com.liferay.portal.model.Group group=allGroups.get(i);
List<Role> groupRoles = RoleLocalServiceUtil.getGroupRoles(group.getGroupId());
if (!groupRoles.isEmpty()) {
Role groupRole = groupRoles.get(0);
out.println(ListUtil.toString(groupRoles,
 Role.NAME_ACCESSOR));
}
}
%>
 
 
Note:
 
When we work with above code respective Java classes should be import.
 
The following is sample code snippets which is in JSP page
 
 
<%@page import="com.liferay.portal.kernel.util.ListUtil"%>
<%@page import="com.liferay.portal.service.GroupLocalServiceUtil"%>
<%@page import="com.liferay.portal.model.Organization"%>
<%@page import="com.liferay.portal.model.User"%>
<%@page import="com.liferay.portal.model.UserGroup"%>
<%@page import="com.liferay.portal.model.Group"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.liferay.portal.model.RoleConstants"%>
<%@page import="com.liferay.portal.service.UserGroupRoleLocalServiceUtil"%>
<%@page import="com.liferay.portal.model.UserGroupRole"%>
<%@page import="com.liferay.portal.model.Role"%>
<%@page import="java.util.List"%>
<%@page import="com.liferay.portal.service.RoleLocalServiceUtil"%>
<%@page import="com.liferay.portal.service.UserLocalServiceUtil"%>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<liferay-theme:defineObjects />
<%
List<Role> userRoles=RoleLocalServiceUtil.getUserRoles(themeDisplay.getUserId());
List<Role> userRoles1=themeDisplay.getUser().getRoles();
for (Role role : userRoles) {
out.println(role.getName());
}
%>
<%
List<UserGroupRole> userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(themeDisplay.getUserId());
List<UserGroupRole> organizationRoles = new ArrayList<UserGroupRole>();
for (UserGroupRole userGroupRole : userGroupRoles) {
int roleType = userGroupRole.getRole().getType();
if (roleType == RoleConstants.TYPE_ORGANIZATION) {
organizationRoles.add(userGroupRole);
out.println(userGroupRole.getRole().getName());
}
}
%>
<%
List<UserGroupRole> userGroupRoles1 = UserGroupRoleLocalServiceUtil.getUserGroupRoles(themeDisplay.getUserId());
List<UserGroupRole> siteRoles = new ArrayList<UserGroupRole>();
for (UserGroupRole userGroupRole : userGroupRoles1) {
int roleType = userGroupRole.getRole().getType();
if (roleType == RoleConstants.TYPE_SITE) {
siteRoles.add(userGroupRole);
out.println(userGroupRole.getRole().getName());
}
}
%>
<%
User selUser=themeDisplay.getUser();
List<Group> allGroups = new ArrayList<Group>();
List<UserGroup> userGroups = selUser.getUserGroups();
List<Group> groups = selUser.getGroups();
List<Organization> organizations = selUser.getOrganizations();
allGroups.addAll(groups);
allGroups.addAll(GroupLocalServiceUtil.
getOrganizationsGroups(organizations));
allGroups.addAll(GroupLocalServiceUtil.
getOrganizationsRelatedGroups(organizations));
allGroups.addAll(GroupLocalServiceUtil.
getUserGroupsGroups(userGroups));
allGroups.addAll(GroupLocalServiceUtil.
getUserGroupsRelatedGroups(userGroups));
for(int i=0;i<allGroups.size();i++){
com.liferay.portal.model.Group group=allGroups.get(i);
List<Role> groupRoles = RoleLocalServiceUtil.getGroupRoles(group.getGroupId());
if (!groupRoles.isEmpty()) {
Role groupRole = groupRoles.get(0);
out.println(ListUtil.toString(groupRoles,
 Role.NAME_ACCESSOR));
}
}
%>
Author

Liferay 6.2 Web Content AUI Carousel Structure and Template / Image Slide Show

Technical Blogs June 26, 2014 By Meera Prince

Introduction:
 
Liferay have very good content management system we can design and publish content in the web page very easy.
 
Along with that it’s also have structures and templates feature so that we can design common designs as structures and templates then we can reuse it many places with different data.
 
Same design if we want uses many places with different data then we will use structures and templates.
 
Liferay 6.2 structure templates have very user-friendly design to create structures and templates rather than liferay 6.1
 
But conceptually basic idea is same for liferay 6.2 and Liferay 6.1 but way of using they make simpler in Liferay 6.2 with very good User Interface.
 
Liferay 6.1 we have used velocity for coding in templates but in liferay 6.2 they have used free marker templates in addition velocity while designing templates and they have given very good UI and Template editor so that we can see all variables with respect to Structure which we have used for template.
 
 
Follow above tutorial then you can understand more about Structures and Templates in liferay web content. Same thing but way of usage is different in Liferay 6.2.
 
 
Objective:
 
We are going to create Carousel Image Slide show in website.
 
We will use AUI Carousel to design image slide show in liferay and we will use Web content 
Structures and templates feature to implement Image Slide Show
 
 
Assumptions:
 
  • In the image slide show we have many images so we able to upload or use many images
  • We need Slide show width and Height it should be configurable.
  • We need to specify time interval to change images so it should be configurable.
  • Each slide image have hyperlink when we click it should go to respective page and links should be configurable.

 

To consider all able now we will design structure and template to design web content.
 
Steps
 
  1. Create Structure
  2. Create Template and associate with Respective Structure
  3. Create web content by using Template
  4. Using Web content

 

Before start this we need to login as Admin
 
Liferay have default super admin so we need to login into liferay portal by following credentials
 
 
User Name:  test@liferay.com
Password:     test
 
 
Following is login screen
 
 
 
 
Once login as Admin go to Admin >> Site Administration
 
 
Once you go to Site Administration select Content Panel there you can click on web content
 
 
 
Create Structure
 
In the web content top navigation Manu you can see manage option menu there you can select 
structure link as follows
 
 
 
 
Once click on Structures then window pop up will be launch there you can enter your structure name and description
 
 
The following is Structure Creation Screen
 
 
In the bottom of pop up window you can see User Interface Design to Design Structure as follows
 
 
 
We have many controls so we can use all elements and we can design. Now we already have code for Image Slide show Structure so you simply click on source and in editor use following source code.
 
 
<root available-locales="en_US" default-locale="en_US">
<dynamic-element dataType="image" fieldNamespace="wcm" indexType="keyword" name="images" readOnly="false" repeatable="true" required="false" showLabel="true" type="wcm-image" width="">
<dynamic-element dataType="link-to-page" fieldNamespace="ddm" indexType="keyword" name="imagelink" readOnly="false" repeatable="false" required="false" showLabel="true" type="ddm-link-to-page" width="small">
<meta-data locale="en_US">
<entry name="label">
<![CDATA[Link to Page]]>
</entry>
<entry name="predefinedValue">
<![CDATA[]]>
</entry>
<entry name="tip">
<![CDATA[]]>
</entry>
</meta-data>
</dynamic-element>
<meta-data locale="en_US">
<entry name="label">
<![CDATA[Image]]>
</entry>
<entry name="predefinedValue">
<![CDATA[]]>
</entry>
<entry name="tip">
<![CDATA[]]>
</entry>
</meta-data>
</dynamic-element>
<dynamic-element dataType="number" fieldNamespace="ddm" indexType="keyword" name="containerwidth" readOnly="false" repeatable="false" required="false" showLabel="true" type="ddm-number" width="small">
<meta-data locale="en_US">
<entry name="label">
<![CDATA[Container Width]]>
</entry>
<entry name="predefinedValue">
<![CDATA[]]>
</entry>
<entry name="tip">
<![CDATA[]]>
</entry>
</meta-data>
</dynamic-element>
<dynamic-element dataType="number" fieldNamespace="ddm" indexType="keyword" name="containerhight" readOnly="false" repeatable="false" required="false" showLabel="true" type="ddm-number" width="small">
<meta-data locale="en_US">
<entry name="label">
<![CDATA[Container Hight]]>
</entry>
<entry name="predefinedValue">
<![CDATA[]]>
</entry>
<entry name="tip">
<![CDATA[]]>
</entry>
</meta-data>
</dynamic-element>
<dynamic-element dataType="number" fieldNamespace="ddm" indexType="keyword" name="intervaltime" readOnly="false" repeatable="false" required="false" showLabel="true" type="ddm-number" width="small">
<meta-data locale="en_US">
<entry name="label">
<![CDATA[Interval Time]]>
</entry>
<entry name="predefinedValue">
<![CDATA[]]>
</entry>
<entry name="tip">
<![CDATA[]]>
</entry>
</meta-data>
</dynamic-element>
</root>
 
The following screen after use source in editor
 
 
 
The following is Graphical view of Structure
 
 
 
Finally click on save button then your structure will be created
 
 
Finally close pop up window and go back to Web content Manage Screen
 
Create Template and associate with Respective Structure
 
Now we need create template and it will use above created structure. In the web content screen top navigation goes manage option menu there you can findTemplates Link
 
 
 
 
Once we click on template then pop window will be open there we can see +Add to create new template.
 
Now we need to fill the name and description along with that we need select respective structure. In our case we already create structure i.e. Image Slide Show Structure we need to select that.
 
We already know we are using free market template so we need to select Language as Free Marker (ftl) and its default language, apart from that we can use velocity and XSLT
 
 
 
In the bottom of pop up you can see Template editor and its respective Structure variables /fields and other available variables was shown in left side.
 
In the structure we have used some fields all fields you can see left side as follows
 
 
 
We already have Free Marker Template code for Image Slide Show please use following code in Editor and save then template will be created.
 
 
<script>
AUI({ filter: 'raw' }).use('aui-carousel', function(A) {
new A.Carousel({
intervalTime:${intervaltime.getData()},
contentBox: '#myCarousel',
activeIndex:0,
height:${containerhight.getData()},
width:${containerwidth.getData()}
}).render();
 
});
</script>
<#if images.getSiblings()?has_content>
<div id="myCarousel">
<#list images.getSiblings() as cur_images>
 
<#if cur_images_index==0>
<a href="${cur_images.imagelink.getData()}">
<div class="carousel-item" style="background: url(${cur_images.getData()})width:${containerwidth.getData()}px; height:${containerhight.getData()}px;" class="carousel-item carousel-item-active";">
</div>
</a>
</#if>
<a href="${cur_images.imagelink.getData()}"> <div class="carousel-item" style="background: url(${cur_images.getData()});width:${containerwidth.getData()}px; height:${containerhight.getData()}px;" class="carousel-item""></div></a>
</#list>
 
</div>
</#if>
 
 

In the Template Design we use html and AUI Script to design template. And we will use stricture variable or fields to fill with dynamic content. These all design was made using Free Market Templates (FTL)
 
However use above template code in editor and finally save it then template will be create and it will be associated with one structure that is we created previously.
 
Note:
 
When we click in fields and variables in left side those will be added in the editor automatically where your cursor point in the editor. Templates editor is every flexible to code or design free marker templates in editor.
 
Each template should be associated with one structure and based in structure we need to code free market template to use structure variables and based on template design we will get input elements to design web content with dynamic data.
 
The following free marker template code in editor

 
 
Now finally save then your template will be created and it will be in the templates list as follows.
 
 
 
Now close pop up window and go back to web content screen.
 
Create web content by using Template
 
Well we are ready with Template and Structure and we will create web content using above template.
 
In the web content screen you can see +Add button option menu in the top navigation there you can see newly created template name that is Image Slide Show Template
 
 
Now you will get web content creation screen with selected template. We need to fill name for web content.
 
Based on template we need to fill the content and in our scenario we are using images element as repeatable so we can add more images by click + icon apposite to images file input element.
 
And we are using Height, Width and Interval we need to fill those values and it should be numbers and we can also select hyper link for each image
 
 
Once we fill the content in the web content template finally click on publish button then content will be available to use and it will be shown in web content list.
 
 
Using Web Content
 
We have done all steps now the content will be available to use. We will use web content display portlet to display web content in the pages.
 
Navigate to desirable page where you simply drag and drop web content display portlet in the page.
 
In the admin mode you can see left side + Icon click on the you can get the toggle there in the applications tab you can select Web content Display Portlet simply click on Add Link then blank web content display portlet will be added to page.
 
 
In the blank web content display portlet you can see toggle control in the bottom.
 
 
You can click on Select Web content there you can see list of web content articles.
 
 
 
You can select and click on respective web content and finally save it then web content will be displayed in portlet.
 
 
For better look and feel remove border for portlet then you can see image slide show as follows.
 
 
When we login as admin bottom of web content display portlet you can see edit controls to edit content and template. We can add more images, change height, width of slide show and we change slide interval time.
 
 
Download Image Slide Show Structure and Template Source 
 
 
Environment:
 
Liferay IDE 2.x+Eclipse (Kepler) +Liferay Plugins SDK 6.2+Tomcat 7.x Liferay Portal Bundle
 
Deployment and its Working.
 
You can source code in the template and Structure as said above in your portal.
 
I also given web content export file as lar. You simply drag and drop web content display portlet in the portlet configuration you can see export/import option and import downloaded lar file using file browses then web content will be created in your portal.
 
When we import lar file respective used template and structure will be created automatically.
 
Related Links
 
 
 
Author

Liferay Service Builder Custom Service Methods

Technical Blogs June 2, 2014 By Meera Prince

Introduction:
 
Liferay Service Builder is a tool to generate service layer to liferay portlets. It will create all necessary CRUD operation related classes and respective methods.
 
We will use Util classes’ methods to perform CRUD operations in portlet development.
The following is the tutorial about Service Builder.
 
 
Liferay Service Builder have provided some Util classes so that we can use those classes and its methods
 
The following are the important Service Util classes we will use
 
 
XXXLocalServiceUtil
XXXServiceUtil
XXXUtil
 
XXX is your entity name in service.xml file example say Student is your entity name.
 
StudentLocalServiceUtil
StudentServiceUtil
StidentUtil
 
 
XXXLocalServiceUtil (StudentLocalServiceUtil)
 
All important CRUD operation related methods will be available. We can use this class anywhere in our code implementation i.e. when we want to interacts with database. The operations are like add, update, delete, and read.
 
When we call methods from this classes there is no security check applied or there no permission checking applicable.
 
XXXServiceUtil(StudentServiceUtil)
 
This class is similar to Local Service Util and available all CRUD operation methods but here it will use some security checks and permission checking are applied when we call the methods. If the user does not have required permissions then it will throw Principle Exception
 
Scenario:
 
Use some XXXServiceUtil method in JSP page and access the page as Guest User then you can get Principle Exception

Same page you can access after login as Admin then no exception will be thrown.
 
Generally this class will use to perform admin related task if we call this method in Guest user mode then it will throw the exception
 
 
Principle Exception
 
XXXUtil (StudenUtil)
 
This class especially for finder methods and all finder methods will be available.
 
Generally in liferay we can create finder methods with help of service.xmlfile
 
We will use following tag in service.xml file so that respective finder method will be create in XXXUtil class.
 
 
<entity name="Student" local-service="true" remote-service="true">
              <!-- PK fields -->
              <column name="studentId" type="long" primary="true" />
              <column name="firstName" type="String" />
              <column name="lastName" type="String" />
              <column name="studentAge" type="int" />
              <column name="studentGender" type="int" />
              <column name="studentAddress" type="String" />
              <!-- Finder methods -->
              <finder name="Gender" return-type="Collection">
                     <finder-column name="studentGender"/>
              </finder>
</entity>
 
 
Note:
 
When we declared Collection return type is a java.uti.List<ObjectType>
 
Method Syntax in Java Class
 
 
public returnType  findByXXX (finderColumns){
 
}
 
XXX is the name we specified in finder tag as name attribute.
 
 
 Example:
 
 
public List findByGender(int stdentGender){
 
}
 
 
When we use finder tag we need to specify the finder columns inside the finder tag.
We need specify the finder method return type i.e. Collection or Object type
 
If the methods want return more than one value or records then need to specify as Collection
If the method returns only one object or one record then we can specify as Object i.e. respective object we specified as entity.
 
Example:
 
By Gender we can get more records or values so its return type should be Collection
 
 
<finder name="byGender" return-type="Collection">
<finder-column name="studentGender"/>
</finder>
 
 
For above Configuration respective SQL query as follows
 
 
Select * from LS_Student Where studentgender=?
 
 
For Above Finder Configuration respective Java Method in XXXUtil(StudentUtil) as follows
 
 
public class StudentUtil {
 
public static java.util.List<com.meera.dbservice.model.Student> 
findBybyGender(
int studentGender)
throws com.liferay.portal.kernel.exception.SystemException {
return getPersistence().findBybyGender(studentGender);
}
}
 
If the finder returns only one value or single object, Assume by first name we have only one record is expected.
 
 
<finder name="fistName" return-type="Student">
<finder-column name="firstName"/>
</finder>
 
 
For above Configuration respective SQL query as follows
 
 
Select * from LS_Student Where firstName=?
 
 
Note:
 
In the above configuration we can expect only one value that is respective entity model object that is why return type we specified as Object i.e. Student
 
Finder on Multiple Columns
 
If we want find the records based on multiple columns
 
 
<finder name="Gender_Age" return-type="Collection">
<finder-column name="studentGender"/>
<finder-column name="studentAge"/>
</finder>
 
 
For above Configuration respective SQL query as follows
 
 
Select * from LS_Student Where studentGender=? AND StudentAge=?
 
 
For Above Finder Configuration respective Java Method in XXXUtil(StudentUtil) as follows
 
 
public class StudentUtil{
 
public static java.util.List<com.meera.dbservice.model.Student>
findByGender_Age(int studentGender, int studentAge)
throws com.liferay.portal.kernel.exception.SystemException {
return getPersistence().findByGender_Age(studentGender,
studentAge);
}
}
 
Note:
 
When we use finder on multiple columns it will apply the AND operator in SQL query.
 
When we call XXXUtil methods in JSP or Portlet action class then we will get Exception
 
Example:
 
 
java.util.List<com.meera.dbservice.model.Student>  studentsList=
StudentUtil. findByGender_Age(1,20)
 
 
When we use above code in anywhere then we will get Hibernate Exception
 
 
org.hibernate.HibernateException: No Hibernate Session bound to thread
 
 
Solution:
 
We need to use these methods in XXXLocalServiceImpl then we will call these methods using XXXLocalServiceUtil
 
Note:
 
We can call any method which is in XXXLocalServiceUtil class in JSP, Portlet Action class or other places.
 
Custom Method Implementation:
 
When we thing about above scenarios we are not able to call finder methods and some the methods in XXXServiceUtil methods. This is where we need to implement custom methods.
 
Steps:
 
  1. Implement Custom method in XXXLocalServiceImpl class
  2. Run service Builder
  3. Call Implemented method using XXXLocalServiceUtil

 

Implement Custom method in XXXLocalServiceImpl class
 
Whenever we get the requirement to write our custom methods then we need to implement in respective entity local service implementation class
 
 
XXXLocalServiceImpl
 
StudentLocalServiceImpl
 
 
Assume scenario we are not able to call finder methods form StudentUtil so we will implement custom method in StudentLocalServiceImpl.java
 
 
public  java.util.List<com.meera.dbservice.model.Student>
 findByGenderAndAge(int studentGender, int studentAge)
 
throws com.liferay.portal.kernel.exception.SystemException {
 
return StudentUtil.findByGender_Age(studentGender, studentAge);
 
}
 
 
Here we have implemented our custom method in XXXLocalServiceImpl 
(StudentLocalServiceImpl.java) and inside the custom method we have used XXXUtil methods.
Like this we can use XXXServiceUtil and XXXUtil methods in XXXLolcalServiceImpl custom method implementation.
 
Note:
 
XXXLocalServiceImpl class available in basepackage.service.impl path
 
Run service Builder
 
Once we implement the custom method in XXXServiceImpl then we need to run service builder using ant build-service target from ant view in eclipse.
 
After run service builder respective method signature will be created in XXXLocalServiceUtil class.
 
Note:
 
For every change in XXXLocalServiceImpl class we need to re run the service builder.
 
Call Implemented method using XXXLocalServiceUtil
 
Now the method is available in XXXLocalSeriviceUtil class so that we can call method anywhere.
 
Example:
 
Method in StudentUtil.java
 
 
public class StudentUtil{
 
public static java.util.List<com.meera.dbservice.model.Student>
 findByGender_Age(
int studentGender, int studentAge)
throws com.liferay.portal.kernel.exception.SystemException {
return getPersistence().findByGender_Age(studentGender,
 studentAge);
}
}
 
 
Note:
 
We can’t call above method directly
 
Implement the Custom method in StudentLocalServiceImpl.java
 
 
public class StudentLocalServiceImpl extends
StudentLocalServiceBaseImpl {
public  java.util.List<com.meera.dbservice.model.Student>
 findByGenderAndAge(
int studentGender, int studentAge)
throws com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findByGender_Age(studentGender, studentAge);
}
}
 
 
Respective method Signature in StudentLocalServieUtil.java
 
 
public static java.util.List<com.meera.dbservice.model.Student>
findByGenderAndAge(
int studentGender, int studentAge)
throws com.liferay.portal.kernel.exception.SystemException {
return getService().findByGenderAndAge(studentGender, studentAge);
}
 
 
Note:
 
Method signature available after run the service builder
 
Using custom method in JSP page or Portlet Action Class
 
 
java.util.List<Student>  studentsList=
StudentLocalServiceUtil. findByGenderAndAge(1,20)
 
 
 
Important Points
 
  • Whenever we need to implement custom method then we will use XXXLocalServiceimpl class
  • We can’t call XXXUtil and XXXServiceUtil methods directly so we need to use XXXLocalServiceImpl class to implement custom methods.
  • All finder methods will be created in XXXUtil
  • When we call XXXServiceUtil methods as Guest then we will get Principle Exception.
  • When we call XXXUtil methods directly then we will get Hibernate Exception says No Hibernate Session bound to thread
  • For every custom method implementation in XXXLocalServiceImpl then the respective method signature will be created in XXXLocalServiceUtil and this is happened after run the service builder.
  • We always use XXXLocalServiceUtil to interact with database and some time we will use XXXServiceUtil too.

 

Note:
 
We can use Dynamic Query API to meet all finder requirements. We can do same as finder methods in Liferay Dynamic Query API.
 
Complete code for Example
 
Cutome Method Implemetation(StudentLocalServiceImpl.java)
 
 
public class StudentLocalServiceImpl extends
StudentLocalServiceBaseImpl {
public  java.util.List<com.meera.dbservice.model.Student>
findByGenderAndAge(
int studentGender, int studentAge)
throws com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findByGender_Age(studentGender, studentAge);
}
}
 
 
Cstome method Signature in
 
 
public class StudentLocalServiceUtil {
public static java.util.List<com.meera.dbservice.model.Student>
 findByGenderAndAge(
int studentGender, int studentAge)
throws com.liferay.portal.kernel.exception.SystemException {
return getService().findByGenderAndAge(studentGender,
 studentAge);
}
}
 
 
Calling method in JSP page(/html/jsps/get_students_by_gender_age.jsp)
 
 
<%@page import="com.liferay.portal.kernel.util.ListUtil"%>
<%@page import="com.meera.dbservice.model.Student"%>
<%@page import="java.util.List"%>
<%@page import="com.meera.dbservice.service.StudentLocalServiceUtil"%>
 
<%@ include file="init.jsp"%>
<a href="<portlet:renderURL />">&laquo;Home</a>
<div class="separator"></div>
<liferay-portlet:renderURL varImpl="getStudentsByAgeAndGender">
<portlet:param name="mvcPath"
value="/html/jsps/get_students_by_gender_age.jsp" />
</liferay-portlet:renderURL>
<liferay-portlet:renderURL varImpl="iteratorURL">
<portlet:param name="studentAge"
value="<%= String.valueOf(studentAge) %>" />
<portlet:param name="studentGender"
value="<%= String.valueOf(studentGender) %>" />
<portlet:param name="mvcPath"
value="/html/jsps/get_students_by_gender_age.jsp" />
</liferay-portlet:renderURL>
<h2>Search Students</h2><br/>
<form action="<%=getStudentsByAgeAndGender%>"
name="studentForm"  method="POST">
<b>Age</b><br/>
<input type="text" name="<portlet:namespace/>studentAge" id="<portlet:namespace/>studentAge"
value="<%=String.valueOf(studentAge)%>"/><br/>
<b>Gender</b><br/>
<input type="radio" name="<portlet:namespace/>studentGender" value="1"<%=studentGender==1?"checked":""%>>Male<br>
<input type="radio" name="<portlet:namespace/>studentGender" value="0"<%=studentGender==0?"checked":""%>>Female<br/>
<input type="submit" name="addStudent" id="addStudent" value="Search"/>
</form>
<liferay-ui:search-container
displayTerms="<%= new DisplayTerms(renderRequest) %>"
emptyResultsMessage="there-are-no-students"
headerNames="firstName,studentAge,studentGender"
iteratorURL="<%= iteratorURL %>"
delta="5"
<liferay-ui:search-container-results>
<%
 
List<Student> studentList=
StudentLocalServiceUtil.findByGenderAndAge(studentGender, studentAge);
 
searchContainer.setTotal(studentList.size());
studentList = ListUtil.subList(studentList,searchContainer.getStart(),
searchContainer.getEnd());
searchContainer.setResults(studentList);
%>
</liferay-ui:search-container-results>
<liferay-ui:search-container-row
className="Student"
keyProperty="studentId"
modelVar="currentStudent">
<liferay-portlet:renderURL varImpl="rowURL">
<portlet:param name="backURL" value="<%= currentURL %>" />
<portlet:param name="mvcPath" value="/html/jsps/display_student.jsp" />
<portlet:param name="studentId" value="<%=String.valueOf(currentStudent.getStudentId()) %>" />
</liferay-portlet:renderURL>
<liferay-ui:search-container-column-text
href="<%= rowURL %>"
name="firstName"
property="firstName"
/>
<liferay-ui:search-container-column-text
href="<%= rowURL %>"
name="studentAge"
property="studentAge"
/>
<liferay-ui:search-container-column-text
href="<%= rowURL %>"
name="studentGender"
value='<%=currentStudent.getStudentGender()==1?"Male":"Female"%>'
/>
</liferay-ui:search-container-row>
<liferay-ui:search-iterator searchContainer="<%=searchContainer %>" />
</liferay-ui:search-container>
 
 
Download Liferay Custom Service Methods Portlet
 
 
Environment:
 
Liferay IDE 2.x+Eclipse (Kepler) +Liferay Plugins SDK 6.2+Tomcat 7.x Liferay Portal Bundle
 
Deployment and its Working.
 
Download portlet you can source or war file to deploy into liferay portal as your convenient.
 
Once portlet successfully deployed drag the portlet in any desired page. Portlet is available in sample category.
 
In the portlet page you can click on Get Student By Gender And Age link then you can see the search container with search inputs.
 
Portlet Screens:
 
Default Page
 
 
Search the students by Age and Gender
 
 
 
Reference Links
 
 
 
Author

Liferay MVC Portlet Database Interactions / Liferay MVC CRUD Operations

Technical Blogs May 26, 2014 By Meera Prince

Liferay MVC Portlet Database Interactions / Liferay MVC CRUD Operations

 
Introduction:
 
Liferay MVC is portlet frame work given by Liferay and it is specific to liferay environment.
We already well aware of Liferay MVC frame work from Liferay Savvyprevious articles.
 
 
 
 
Environment:
 
Liferay IDE 2.x+Eclipse (Kepler) +Liferay Plugins SDK 6.2+Tomcat 7.x Liferay Portal Bundle
 
Note:
 
Please go through above three articles then you will be much aware of Liferay MVC framework and its use in portlet development.
 
Now we will see how liferay portlet interact with database to store the data and fetch the data from database.
 
Database interaction is like Insert, Delete, and Read and Update the data in database.
We already know there are many technologies in Java that is java applications connect to database and do CRUD operations.
 
Mainly when we are talking about Database interaction we are very much familiar with JDBC. Similarly if go little bit advanced concept then Hibernate comes into picture.
 
Liferay also have used JDBC and Hibernate concepts to interact with database and it will perform CRUD operations.
 
But we never write any legacy JDBC java code or Hibernate code when we work with database interaction all the code already abstracted and we will use simple Util classes and its method to perform operations.
 
Liferay implemented many classes and interfaces so that we can develop database interaction portlet pretty easy.
 
We have two ways to connection data base in Liferay
 
  1. Legacy JDBC Code
  2. Liferay Service Builder

Legacy JDBC Code
 
Liferay have implemented some classes and it use simple JDBC code to interact with database.
These classes are available in Liferay Kernel level so that we can use anywhere in Plugin portlet development.
 
We have class called DataAccess so that we can use this class to get the Connection object once we get the connection reaming all are like simple JDBC code to connect to database and perform operations.
 
The following is simple code using Data Access Class
 
 
import java.io.IOException;
import java.sql.SQLException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import com.liferay.portal.kernel.dao.jdbc.DataAccess;
import com.liferay.util.bridges.mvc.MVCPortlet;
public class StudentMVCPortletAction extends MVCPortlet {
       public void getStudent(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException,
PortletException, SQLException {
java.sql.Connection con = null;
java.sql.Statement st = null;
try {
con = DataAccess.getConnection();
st = con.createStatement();
java.sql.ResultSet rs = st.executeQuery("SELECT * FROM Student");
while (rs.next()) {
String firstName = rs.getString("firstName");
String lastName = rs.getString("lastName");
System.out.println("Student FirstName:" + firstName);
System.out.println("Student Last Name:" + lastName);
}
catch (Exception e) {
finally {
st.close();
con.close();
}
}
}
 
 
Note:
 
This is very Legacy JDBC code and we won’t use in real portlet development. We will use above method in some of specific scenarios.
 
Liferay Service Builder
 
Liferay Service Builder is tool to generate database interaction layer/service layer to the portlet.
 
Service layer consist of set of classes and interfaces so that we can use these classes to interact with database and perform database operation in portlet.
 
Service Builder tool help us to generate service layer so that developer need not worry about persistence code and need to concentrate on business logic.
 
Generally in the application development we need database service layer and the operations we used in persistence layer is common i.e. CRUD operations.
 
Instead writing same CRUD operation persistence logic for multiple times we have a tool in Liferay so that it will be generated all classes and interfaces and developer need not to worry about persistence logic he/she can concentrate only on writing business logic.
 
Liferay Service Builder is simple ANT script when we run ant target then all classes and interfaces will be created.
 
When we create Liferay MVC Portlet using Plugins SDK then portlet consists of ANT build file and the build file have service builder related target by default.
 
Liferay Service Builder used Spring Hibernate DAO implementation to create the services.
 
After successfully run service builder we can see many configuration files and java implementation classes all are following spring hibernate DAO implementation mechanism.
 
More details about Liferay Service Builder follow the article
 
 
The following are the steps to Generate Service Layer in Portlet.
 
  1. Create simple Liferay MVC portlet using Liferay IDE in eclipse
  2. Create Service.xml file in Portlet WEB-INF directory
  3. Define required entities/tables in service.xml
  4. Run the Service builder
  5. Using Generated Database services In Portlet Development

Create simple Liferay MVC portlet using Liferay IDE in eclipse
 
Firs we need to create simple Liferay MVC portlet using Liferay IDE in eclipse. This is very simple to create in eclipse.
 
Go through below article to create simple Liferay MVC Portlet
 
 
Create Service.xml file in Portlet WEB-INF directory
 
Now we need to create service.xml file in portlet WEB-INF directory. This is the configuration file to service builder tool and Service Builder use configuration file to generate required services (classes, interfaces) to portlet and these services provided the database interactions from the portlet.
 
The following screen shows service.xml file in portlet WEB-INF directory
 
 
Note:
 
In eclipse with Liferay IDE we have option to create service.xml with sample entity using GUI interface.
 
We can also create manually in the above specified location or we can use Liferay IDE to create service.xml file.
 
Define required entities/tables in service.xml
 
Now we need to defined required entities in service.xml file so that service builder will generate services for defined entities/tables.
 
service.xml consist of  defined tags from which we will define the entities. Tags information is available in service builder DTD file.
 
When we define entity we need to specify primary key column, column data type, column name and other required things. All the tags information is based on its DTD.
 
The following is service builder DTD we can get more information about service builder tags for service.xml
 
 
 
Assume we have an entity/table Student
 
The following is service.xml entity configuration
 
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.2.0//EN"
"http://www.liferay.com/dtd/liferay-service-builder_6_2_0.dtd">
<service-builder package-path="com.meera.dbservice">
       <author>LiferaySavvy</author>
       <namespace>LS</namespace>
       <entity name="Student" local-service="true" remote-service="true">
              <!-- PK fields -->
              <column name="studentId" type="long" primary="true" />
              <column name="firstName" type="String" />
              <column name="lastName" type="String" />
              <column name="studentAge" type="int" />
              <column name="studentGender" type="int" />
              <column name="studentAddress" type="String" />
              <!-- Order -->
              <order by="asc">
                     <order-column name="studentId" />
              </order>
              <!-- Finder methods -->
              <finder name="byGender" return-type="Collection">
                     <finder-column name="studentGender"/>
              </finder>
       </entity>
</service-builder>
 
 
Run the Service builder
 
Once we completed the configuration now we need run service builder. We can run the service builder in eclipse from ANT view. We need to click onbuild-service target from the ANT view
In normal ant command for run service builder as follows
 
 
ant build-service
 
 
The following is ANT build-service in eclipse ant view
 
 
 
The following is screen to show build success
 
 
Once we run service builder it will generate many classes and interfaces. All interfaces will be packages as jar file and it will be available in WEB-INF/libdirectory.
 
It will also generate the required SQL script and it will be executed when we deploy the portlet so that required tables and indexes will be created in database. You can see the script in sql (docroot\WEB-INF\sql) directory of portlet.
 
The table name which is creates in database will be service buildernamespace_entity name which we have given in service.xml
 
In the above example the table the name in database is LS_Student
 
The following screen shows services after run service builder
 
 
 
Using Generated Database services in Portlet Development
 
Once we generated the services then we can use in portlet development
 
We already know we have used Student entity in service.xml so that we will get many services related to Student entity/table. We will use Util classes to interact with database.
 
It will generate many classes and interfaces but we will use only Util java classes in portlet development.
 
The following are main java Util classes
 
 
XXXServiceUtil
XXXLocalServiceUtil
XXXUtil
 
XXX is entity name which we have given in service.xml and our example its Student
 
StudetLocalServiceUtil
StudentServiceUtil
StudentUtil
 
 
Mostly we will use Util class’s related methods to perform database CRUD operations.
 
  1. Add /Create record
  2. Delete Record
  3. Update Record
  4. Show Data/Record

Add /Create record  
 
When we create or add record to the table first we need create persistence object and need to fill the data in object then finally add to the table usingXXXLocalServiceUtil.addXXX() method.When we create persistence object we need a primary key so we will use CounterLocalServiceUtil.increment()to create unique id for the record.
 
The following is code snippet to add record to the table.
 
Type: 1
 
 
//create primary key
long studentId=CounterLocalServiceUtil.increment();
//create student persistance object
Student student=null;
student=StudentLocalServiceUtil.createStudent(studentId);
//fill the data in persistance object
student.setFirstName(firstName);
student.setLastName(lastName);
student.setStudentAge(studentAge);
student.setStudentGender(studentGender);
student.setStudentAddress(address);
//Add student persistance object to database student table
student=StudentLocalServiceUtil.addStudent(student);
 
 
Note:
 
In the above code we are creating primary key using Counter Service.
 
Type: 2
 
 
Student student=null;
student=new StudentImpl();
//fill the data in persistance object
student.setFirstName(firstName);
student.setLastName(lastName);
student.setStudentAge(studentAge);
student.setStudentGender(studentGender);
student.setStudentAddress(address);
//Add student persistance object to database student table
student=StudentLocalServiceUtil.addStudent(student);
 
 
Note:
 
In the above code we are creating persistence object with new operator so primary key will be auto generated.
 
In the both cases it will return student object if the record added successfully otherwise it will return null value.
 
Update Record
 
To update record first we need to get existed record with primary and need to fill new updated information in persistence object then we will update record.
 
The following is code snippet to update record.
 
 
Student student=StudentLocalServiceUtil.getStudent(studentId);
//fill update information
student.setFirstName(firstName);
student.setLastName(lastName);
student.setStudentAge(studentAge);
student.setStudentGender(studentGender);
student.setStudentAddress(address);
student=StudentLocalServiceUtil.updateStudent(student);
 
 
Note:
 
Once data is updated it will return updated persistence object.
 
Delete Record
 
We need primary key to delete the record.
 
The following is code for delete record
 
 
long studentId = ParamUtil.getLong(actionRequest,"studentId");
 
Student student=StudentLocalServiceUtil.deleteStudent(studentId);
 
 
We can also delete record by object
 
 
Student student=StudentLocalServiceUtil.getStudent(studentId);
 
student=StudentLocalServiceUtil.deleteStudent(student);
 
 
Note:
 
Once record is deleted it will return deleted persistence object.
 
Show Data/Record
 
We have different methods to get the records we can get single record by primary key and we can fetch all records too.
 
We can also fetch the record by using columns based these methods are available in XXXUtil methods. We have many finder methods and all finder methods will be available in XXXUtil class.
 
To create any finder methods on required columns then we need to add configuration in service.xml file so that finder methods will be created to specific columns.
 
The following is simple tag which will generate finder method and it fetch the record based on given column
 
 
<entity name="Student" local-service="true" remote-service="true">
              <!-- PK field -->
              <column name="studentId" type="long" primary="true" />
              <column name="firstName" type="String" />
              <column name="lastName" type="String" />
              <column name="studentAge" type="int" />
              <column name="studentGender" type="int" />
              <column name="studentAddress" type="String" />
             
              <!-- Finder methods -->
              <finder name="byGender" return-type="Collection">
                     <finder-column name="studentGender"/>
              </finder>
       </entity>
 
Note:
 
We will see more about finder methods in future articles.
 
The following are code snippets to fetch records.
 
Get Record by Primary Key
 
 
Student student=StudentLocalServiceUtil.getStudent(studentId);
 
 
Get all records
 
 
List<Student> studentList=
StudentLocalServiceUtil.getStudents(0,
StudentLocalServiceUtil.getStudentsCount());
 
 
The following are the available methods in StudentLocalService.java interface
 
 
public com.meera.dbservice.model.Student addStudent(
              com.meera.dbservice.model.Student student)
              throwscom.liferay.portal.kernel.exception.SystemException;
      
 
public com.meera.dbservice.model.Student createStudent(long studentId);
 
 
public com.meera.dbservice.model.Student deleteStudent(
              com.meera.dbservice.model.Student student)
              throwscom.liferay.portal.kernel.exception.SystemException;
 
 
public java.util.List dynamicQuery(
              com.liferay.portal.kernel.dao.orm.DynamicQuery dynamicQuery)
              throwscom.liferay.portal.kernel.exception.SystemException;
 
 
public long dynamicQueryCount(
              com.liferay.portal.kernel.dao.orm.DynamicQuery dynamicQuery)
              throwscom.liferay.portal.kernel.exception.SystemException;
 
public java.util.List<com.meera.dbservice.model.Student> getStudents(
              int start, int end)
              throwscom.liferay.portal.kernel.exception.SystemException;
 
public int getStudentsCount()
              throwscom.liferay.portal.kernel.exception.SystemException;
 
public com.meera.dbservice.model.Student updateStudent(
              com.meera.dbservice.model.Student student)
              throwscom.liferay.portal.kernel.exception.SystemException;
 
public com.meera.dbservice.model.Student deleteStudent(long studentId)
              throwscom.liferay.portal.kernel.exception.PortalException,
                     com.liferay.portal.kernel.exception.SystemException;
 
public com.meera.dbservice.model.Student addStudent(
              com.meera.dbservice.model.Student student)
              throwscom.liferay.portal.kernel.exception.SystemException;
 
 
public com.meera.dbservice.model.Student createStudent(long studentId);
 
 
 
Important Points
 
  • Service Builder is tool to generate database interaction layer to the portlet.
  • Service Builder is simple ANT script and it has target to run the tool.
  • Service Builder ANT target is available in portlet build.xml file by default so we can run target to generate service layer for portlet.
  • Service Builder need service.xml file so that it will use those configuration to generate services.
  • Service.xml file consist of set of predefined tags and it will be available in Service Builder DTD file.
  • Service builder use the Spring Hibernate DAO implementation concept to generate services.
  • Service Builder tool generate all java interfaces, implementation classes and spring hibernate configuration files, apart from these it will also generated required SQL scripts.
  • SQL script will be run at time of portlet deployment it’s generally created table scripts and indexes scripts.
  • For each modification in service.xml file or any other changes in service layer related classes we need to re run the service builder.
  • ant build-service is target to run service builder.
  • Service Builder packages all interfaces and required Util classes as porletName-portlet.jar file.
  • Services jar file will be used in other portlet to obtain other portlet services. This is called sharing of services in other portlet.

Note:
 
There are many things behind Liferay Service Builder we will see more details in coming articles.
 
Download Portlet
 
 
Portlet Screens:
 
Default View
 
 
 
Add student
 
 
Update student
 
 
 
Delete Student
 
 
Display Student
 
 
 
Complete Code of Student Liferay MVC Service Builder Portlet
 
Portlet Action Class (StudentMVCPortletAction.java)
 
 
package com.meera.liferaymvc;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
import com.meera.dbservice.model.Student;
import com.meera.dbservice.model.impl.StudentImpl;
import com.meera.dbservice.service.StudentLocalServiceUtil;
public class StudentMVCPortletAction extends MVCPortlet {
public void addStudent(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
try {
String firstName = ParamUtil.getString(actionRequest, "firstName");
String lastName = ParamUtil.getString(actionRequest, "lastName");
int studentAge = ParamUtil.getInteger(actionRequest, "studentAge");
int studentGender = ParamUtil.getInteger(actionRequest, "sex", 1);
String address = ParamUtil.getString(actionRequest, "address");
// add student record
// create primary key
long studentId = CounterLocalServiceUtil.increment();
// create student persistance object
Student student = null;
student = new StudentImpl();
student = StudentLocalServiceUtil.createStudent(studentId);
// fill the data in persistance object
student.setFirstName(firstName);
student.setLastName(lastName);
student.setStudentAge(studentAge);
student.setStudentGender(studentGender);
student.setStudentAddress(address);
// Add student persistance object to database student table
student = StudentLocalServiceUtil.addStudent(student);
if (student != null) {
// adding success message
SessionMessages.add(actionRequest.getPortletSession(),
"student-add-success");
_log.info("Student have been added successfylly");
else {
SessionErrors.add(actionRequest.getPortletSession(),
"student-add-error");
_log.error("There is an Erron in adding Student");
}
// navigate to add student jsp page
actionResponse.setRenderParameter("mvcPath",
"/html/jsps/add_student.jsp");
catch (Exception e) {
SessionErrors.add(actionRequest.getPortletSession(),
"student-add-error");
e.printStackTrace();
}
}
 
public void deleteStudent(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
try {
long studentId = ParamUtil.getLong(actionRequest, "studentId");
Student student = StudentLocalServiceUtil.deleteStudent(studentId);
if (student != null) {
// adding success message
SessionMessages.add(actionRequest.getPortletSession(),
"student-delete-success");
_log.info("Student have been deleted successfylly");
else {
SessionErrors.add(actionRequest.getPortletSession(),
"student-delete-error");
_log.error("There is an Erron in delete Student");
}
// navigate to add student jsp page
actionResponse.setRenderParameter("mvcPath",
"/html/jsps/delete_student.jsp");
catch (Exception e) {
SessionErrors.add(actionRequest.getPortletSession(),
"student-add-error");
e.printStackTrace();
}
}
 
public void updateStudent(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
try {
long studentId = ParamUtil.getLong(actionRequest, "studentId");
String firstName = ParamUtil.getString(actionRequest, "firstName");
String lastName = ParamUtil.getString(actionRequest, "lastName");
int studentAge = ParamUtil.getInteger(actionRequest, "studentAge");
int studentGender = ParamUtil.getInteger(actionRequest, "sex", 1);
String address = ParamUtil.getString(actionRequest, "address");
Student student = StudentLocalServiceUtil.getStudent(studentId);
if (student != null) {
// fill update information
student.setFirstName(firstName);
student.setLastName(lastName);
student.setStudentAge(studentAge);
student.setStudentGender(studentGender);
student.setStudentAddress(address);
student = StudentLocalServiceUtil.updateStudent(student);
if (student != null) {
// adding success message
SessionMessages.add(actionRequest.getPortletSession(),
"student-update-success");
_log.info("Student have been updated successfylly");
else {
SessionErrors.add(actionRequest.getPortletSession(),
"student-update-error");
_log.error("There is an Erron in delete Student");
}
else {
SessionErrors.add(actionRequest.getPortletSession(),
"student-update-error");
_log.error("Could not find student.");
}
// navigate to add student jsp page
actionResponse.setRenderParameter("mvcPath",
"/html/jsps/update_student.jsp");
catch (Exception e) {
SessionErrors.add(actionRequest.getPortletSession(),
"student-update-error");
e.printStackTrace();
}
}
 
public void getStudent(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
try {
long studentId = ParamUtil.getLong(actionRequest, "studentId");
String cmd = ParamUtil.getString(actionRequest, "cmd");
Student student = StudentLocalServiceUtil.getStudent(studentId);
if (student != null) {
// adding success message
actionRequest.setAttribute("studentObject", student);
_log.info("Student have been found for specific primary key successfylly");
else {
_log.error("Stundet not found");
}
if (cmd.equals("DELETE")) {
// navigate to add student jsp page
actionResponse.setRenderParameter("mvcPath",
"/html/jsps/delete_student.jsp");
}
if (cmd.equals("UPDATE")) {
// navigate to add student jsp page
actionResponse.setRenderParameter("mvcPath",
"/html/jsps/update_student.jsp");
}
if (cmd.equals("VIEW")) {
// navigate to add student jsp page
actionResponse.setRenderParameter("mvcPath",
"/html/jsps/display_student.jsp");
}
 
catch (Exception e) {
SessionErrors.add(actionRequest.getPortletSession(),
"student-add-error");
e.printStackTrace();
}
}
 
private static Log _log = LogFactoryUtil
.getLog(StudentMVCPortletAction.class);
}
 
 
Default View JSP Page (/html/jsps/view.jsp)
 
 
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet"%>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<liferay-theme:defineObjects />
<h1>Liferay Service Builder/ Student CRUD Operations</h1>
<portlet:renderURL var="addStudent">
<portlet:param name="mvcPath" value="/html/jsps/add_student.jsp"/>
</portlet:renderURL>
<portlet:renderURL var="updateStudent">
<portlet:param name="mvcPath" value="/html/jsps/update_student.jsp"/>
</portlet:renderURL>
<portlet:renderURL var="dislayStudent">
<portlet:param name="mvcPath" value="/html/jsps/display_student.jsp"/>
</portlet:renderURL>
<portlet:renderURL var="deleteStudent">
<portlet:param name="mvcPath" value="/html/jsps/delete_student.jsp"/>
</portlet:renderURL>
<br/>
<a href="<%=addStudent.toString()%>">Add Student</a><br/>
<a href="<%=updateStudent.toString()%>">Update Student</a><br/>
<a href="<%=deleteStudent.toString()%>">Delete Student</a><br/>
<a href="<%=dislayStudent.toString()%>">Display Student</a><br/>
 
 
Add Student JSP Page (/html/jsps/add_student.jsp)
 
 
<%@page import="com.liferay.portal.kernel.servlet.SessionErrors"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionMessages"%>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet"%>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<portlet:renderURL var="homeURL"></portlet:renderURL>
<portlet:actionURL var="addStudentActionURL" windowState="normal" 
name="addStudent">
</portlet:actionURL>
<% if(SessionMessages.contains(renderRequest.
getPortletSession(),"student-add-success")){%>
<liferay-ui:success key="student-add-success" message="Student information
have been added successfully." />
<%} %>
<% if(SessionErrors.contains(renderRequest.getPortletSession(),
"student-add-error")){%>
<liferay-ui:error key="student-add-error" message="There is an 
Error occured while adding student please try again" />
<%} %>
<h2>Add Student</h2>
<a href="<%=homeURL.toString() %>">Home</a><br/><br/>
<form action="<%=addStudentActionURL%>" name="studentForm" method="POST">
<b>First Name</b><br/>
<input  type="text" name="<portlet:namespace/>firstName" id="<portlet:namespace/>firstName"/><br/>
<b>Last Name</b><br/>
<input type="text" name="<portlet:namespace/>lastName"
id="<portlet:namespace/>lastName"/><br/>
<b>Age</b><br/>
<input type="text" name="<portlet:namespace/>studentAge" id="<portlet:namespace/>studentAge"/><br/>
<b>Gender</b><br/>
<input type="radio" name="<portlet:namespace/>sex" value="1">Male<br>
<input type="radio" name="<portlet:namespace/>sex" value="0">Female<br/>
<b>Address</b><br/>
<textarea rows="4" cols="50" name="<portlet:namespace/>address">
</textarea><br/>
<input type="submit" name="addStudent" id="addStudent" value="Add Student"/>
</form>
 
 
Update Student JSP Page (/html/jsps/update_student.jsp)
 
 
<%@page import="com.liferay.portal.kernel.servlet.SessionErrors"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionMessages"%>
<%@page import="com.meera.dbservice.service.StudentLocalServiceUtil"%>
<%@page import="java.util.List"%>
<%@page import="com.meera.dbservice.model.Student"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionErrors"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionMessages"%>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet"%>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<portlet:renderURL var="homeURL"></portlet:renderURL>
<portlet:actionURL var="updateStudentActionURL" windowState="normal" 
name="updateStudent">
</portlet:actionURL>
<portlet:actionURL var="getStudentActionURL" windowState="normal"name="getStudent">
<portlet:param name="cmd" value="UPDATE"/>
</portlet:actionURL>
<h2>Update Student</h2>
<a href="<%=homeURL.toString() %>">Home</a><br/><br/>
<%if(SessionMessages.contains(renderRequest.getPortletSession(),"student-update-success")){%>
<liferay-ui:success key="student-update-success" message="Selected Student
 information have been updated successfully." />
<%} %>
<% if(SessionErrors.contains(renderRequest.getPortletSession(),
"student-update-error")){%>
<liferay-ui:error key="student-update-error" message="There is an 
Error occurred while updating student please try again" />
<%} %>
<%
List<Student> studentList=StudentLocalServiceUtil.
getStudents(0,StudentLocalServiceUtil.getStudentsCount());
Student selecteStudentObject=(Student)renderRequest.getAttribute("studentObject");
%>
<form action="<%=getStudentActionURL.toString()%>" name="studentForm" method="POST">
<b>Select Student ID</b><br>
<select name="<portlet:namespace/>studentId"onchange="submitform(this.value);">
<option value="-1">--select--</option>
<%for(Student student:studentList){%>
  <option 
value="<%=student.getStudentId()%>"<%=selecteStudentObject!=null&&selecteStudentObject.getStudentId()==
student.getStudentId()?"selected":""%>>
<%=student.getStudentId()%></option>
  <%} %>
</select><br>
<%if(selecteStudentObject!=null){%>
<b>First Name</b><br/>
<input  type="text" name="<portlet:namespace/>firstName"
id="<portlet:namespace/>firstName" 
value="<%=selecteStudentObject.getFirstName()%>"/><br/>
<b>Last Name</b><br/>
<input type="text" name="<portlet:namespace/>lastName" 
id="<portlet:namespace/>lastName" 
value="<%=selecteStudentObject.getLastName()%>"/><br/>
<b>Age</b><br/>
<input type="text" name="<portlet:namespace/>studentAge" 
id="<portlet:namespace/>studentAge" 
value="<%=selecteStudentObject.getStudentAge()%>"/><br/>
<b>Gender</b><br/>
<input type="radio" name="<portlet:namespace/>sex"
value="1"<%=selecteStudentObject.getStudentGender()==1?"checked":""%>>Male<br>
<input type="radio" name="<portlet:namespace/>sex"
value="0"<%=selecteStudentObject.getStudentGender()==0?"checked":""%>>Female<br/>
<b>Address</b><br/>
<textarea rows="4" cols="50" name="<portlet:namespace/>address">
<%=selecteStudentObject.getStudentAddress()%>
</textarea><br/>
<input type="button" name="updateStudent" id="updateStudent" 
value="Update Student" onclick="updateStudentRecord();"/>
<%}%>
</form>
<script>
function submitform(selectedValue)
{
  if(selectedValue!="-1"){
         document.studentForm.submit(); 
  }
      
}
function updateStudentRecord()
{
       document.studentForm.action="<%=updateStudentActionURL.toString()%>"
    document.studentForm.submit();
}
</script>
 
 
Delete Student JSP Page (/html/jsps/delete_student.jsp)
 
 
<%@page import="com.liferay.portal.kernel.servlet.SessionErrors"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionMessages"%>
<%@page import="com.meera.dbservice.service.StudentLocalServiceUtil"%>
<%@page import="java.util.List"%>
<%@page import="com.meera.dbservice.model.Student"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionErrors"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionMessages"%>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet"%>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<portlet:renderURL var="homeURL"></portlet:renderURL>
<portlet:actionURL var="deleteStudentActionURL" windowState="normal" 
name="deleteStudent">
</portlet:actionURL>
<portlet:actionURL var="getStudentActionURL" windowState="normal" 
name="getStudent">
<portlet:param name="cmd" value="DELETE"/>
</portlet:actionURL>
<h2>Delete Student</h2>
<a href="<%=homeURL.toString() %>">Home</a><br/><br/>
<% if(SessionMessages.contains(renderRequest.
getPortletSession(),"student-delete-success")){%>
<liferay-ui:success key="student-delete-success" message="Selected Student 
information have been deleted successfully." />
<%} %>
<% if(SessionErrors.contains(renderRequest.getPortletSession(),
"student-delete-error")){%>
<liferay-ui:error key="student-delete-error" message="There is an Error occured 
while deleting student please try again" />
<%} %>
<%
List<Student> studentList=StudentLocalServiceUtil.
getStudents(0,StudentLocalServiceUtil.getStudentsCount());
Student selecteStudentObject=(Student)renderRequest.getAttribute("studentObject");
%>
<form action="<%=getStudentActionURL.toString()%>" name="studentForm" method="POST">
<b>Select Student ID</b><br>
<select name="<portlet:namespace/>studentId"onchange="submitform(this.value);">
<option value="-1">--select--</option>
<%for(Student student:studentList){%>
<option 
value="<%=student.getStudentId()%>"<%=selecteStudentObject!=null&&selecteStudentObject.getStudentId()==
student.getStudentId()?"selected":""%>>
<%=student.getStudentId()%></option>
  <%} %>
</select><br>
<%if(selecteStudentObject!=null){%>
Student Name:
<%=selecteStudentObject.getFirstName()+"&nbsp;"+
selecteStudentObject.getLastName()%>
<br/>
Student Age: <%=selecteStudentObject.getStudentAge() %><br/>
Student Gender:<%=selecteStudentObject.getStudentGender()==1?"Male":"Famale"%>
<br/>
Address: <%=selecteStudentObject.getStudentAddress()%><br/>
<input type="button" name="deleteStudent" id="addStudent" value="Delete
 Student" onclick="deleteStudentRecord();"/>
<%}%>
</form>
<script>
function submitform(selectedValue)
{
  if(selectedValue!="-1"){
         document.studentForm.submit(); 
  }
      
}
function deleteStudentRecord()
{
       document.studentForm.action="<%=deleteStudentActionURL.toString()%>"
    document.studentForm.submit();
}
</script>
 
 
Display Student JSP Page (/html/jsps/display_student.jsp)
 
 
<%@page import="com.liferay.portal.kernel.servlet.SessionErrors"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionMessages"%>
<%@page import="com.meera.dbservice.service.StudentLocalServiceUtil"%>
<%@page import="java.util.List"%>
<%@page import="com.meera.dbservice.model.Student"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionErrors"%>
<%@page import="com.liferay.portal.kernel.servlet.SessionMessages"%>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet"%>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<portlet:renderURL var="homeURL"></portlet:renderURL>
<portlet:actionURL var="getStudentActionURL" windowState="normal"name="getStudent">
<portlet:param name="cmd" value="VIEW"/>
</portlet:actionURL>
<h2>Display Student Information</h2>
<a href="<%=homeURL.toString() %>">Home</a><br/><br/>
<%
List<Student> studentList=StudentLocalServiceUtil.
getStudents(0,StudentLocalServiceUtil.getStudentsCount());
Student selecteStudentObject=(Student)renderRequest.getAttribute("studentObject");
%>
<form action="<%=getStudentActionURL.toString()%>" name="studentForm" method="POST">
<b>Select Student ID</b><br>
<select name="<portlet:namespace/>studentId"onchange="submitform(this.value);">
<option value="-1">--select--</option>
<%for(Student student:studentList){%>
<option 
value="<%=student.getStudentId()%>"<%=selecteStudentObject!=null&&selecteStudentObject.getStudentId()==
student.getStudentId()?"selected":""%>>
<%=student.getStudentId()%></option>
  <%} %>
</select><br>
<%if(selecteStudentObject!=null){%>
<h3>The following are the selected Student Information</h3><br/>
Student Name:
<%=selecteStudentObject.getFirstName()+"&nbsp;"
+selecteStudentObject.getLastName()%><br/>
Student Age: <%=selecteStudentObject.getStudentAge() %><br/>
Student Gender:<%=selecteStudentObject.getStudentGender()==1?"Male":"Famale"%><br/>
Address: <%=selecteStudentObject.getStudentAddress()%><br/>
<%}%>
</form>
<script>
function submitform(selectedValue)
{
  if(selectedValue!="-1"){
         document.studentForm.submit(); 
  }
      
}
</script>
 
 
Related Articles
 
 
 
 
 
 
 
Author

Liferay MVC Portlet Development Introduction

Technical Blogs April 29, 2014 By Meera Prince

Introduction:
 
Liferay have come up with their portlet frame work called Liferay MVC. Liferay MVC is portlet development framework and we can develop JSR 168&286 standards portlets and deploy into Liferay Portal.
 
Liferay MVC is portlet framework specially designed for liferay and we can develop portlet and deploy into liferay portal.
 
This frame work has many features and it uses Liferay APIs to rapid portlet development and easy to use. It is very light weight frame work and it come up with liferay Plugins SDK.
 
Liferay MVC portlet is default liferay portlet development frame work and it is inbuilt in Liferay Plugins SDK. We need not to do any additional configuration or need not to add any additional jar files when we develop portlet using Liferay MVC. It’s also follows all JSR portlet standards and it inherited the Generic Portlet features.
 
Liferay IDE has support to create Liferay MVC portlet and deploy into servers.
 
Generally when we use Generic Portlet developer need to handle more code but when we use Liferay MVC it will cut down development effort when we think in prospective of code, it have very good mechanism to handle portlet lifecycle.
 
MVC portlet hierarchy
 
 
When we moving to up to down it meaning we are getting many features in the child class i.e. MVC Portlet have many features.
 
We already have experience with Generic Portlet and we already well aware of Portlet Life cycle and its JSR 168&286 features.
 
Go through following articles for more understand about portlet development and life cycle.
 
 
 
In the generic portlet development portlet class need to override doView(--) ,processAction(--)  for every use of portlet action or render.
 
But when we use Liferay MVC Portlet we need not override any of the above methods because those methods already implemented and they have designed good mechanism to render views and perform portlet action without overdoing any of the method.
 
Here we will handle page navigation or render views by simply  using some request parameters in URL and similarly we will specify portlet class action method name as request pearamter  in portlet Action URL to perform action.
 
In the portlet Action Phase we will simple specify the portlet class method name in URL parameter so that it will perform action. So here we need not override processAction(--)  method
 
Examples
 
Navigate from one jsp page to another jsp page
 
 
<portlet:renderURL  var="linkToJspPageOne">
<portlet:param name="mvcPath" value="/html/jsps/page1.jsp"/>
</portlet:renderURL>
 
OR
 
<portlet:renderURL  var="linkToJspPageTwo">
<portlet:param name="jspPage" value="/html/jsps/page2.jsp"/>
</portlet:renderURL>
 
Note:
 
We need to use jspPage or mvcPath  URL parameter and need specify the jsp page path as value then it will navigate  to jsp page or render the specified view.
 
In the portlet class we need not specify any thing means we need not override doView(--) method.
 
Perform Portlet Action Phase
 
 
Action URL
 
<portlet:actionURL var="portletActionURL" name="addEmployee">
</portlet:actionURL>
 
OR
 
<portlet:actionURL var="portletActionURL">
<portlet:param name="javax.portlet.action" value="addEmployee"/>
</portlet:actionURL>
 
OR
 
<portlet:actionURL var="portletActionURL">
<portlet:param name="<%=ActionRequest.ACTION_NAME%>"value="addEmployee"/>
</portlet:actionURL>
 
When we access above URL through hyper link or as form action then it will execute portlet call action method and the method name is addEmployee.
 
Portlet Class Action Method
 
public class EmplyeePortletAction extends MVCPortlet {
 
public void addEmployee(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
 
       //business logic here
 
       }
}
 
Note:
 
We simple create Portlet Action URL and we need to specify the portlet class action method name as URL name attribute
 
URL name attribute is same as Portlet Class action method name so that it will execute the method and perform action phase. We need  not to override processAction(--) method.
 
We can specify the portlet class action method name in URL name attribute or we can specify as URL request parameter i.e.javax.portlet.action
 
 
 
When we perform multiple actions then we simple create multiple Action URLs and use URL name attribute to specify the action method name so that it will perform action phase.
 
 It is very convenient to developer to avoid many if else blocks in processAction(--) method and we need not override process action method.
 
Access Action URL request Parameters in Render Phase or JSP page.
 
We already know when we specify URL parameters in Action URL those are not available in jsp page or render phase.
 
We have to use Set Render Parameters method in action phase or we have to use Copy Render Parameters method in action method or action phase.
 
Scenario
 
We have some request parameter in Portlet Action URL and after perform action phase through portlet class action method then we need to access Action URL parameters in Render Phase or JSP page.
 
 
Case:1
 
<portlet:renderURL  var="portletRenerURL">
<portlet:param name="employeeName" value="Meera Prince"/>
</portlet:renderURL>
 
In JSP Page
 
Emplyee Name: <%=renderRequest.getParameter("employeeName")%><br/>
 
In the Case: 1 we are using Portlet Render URL that is why we can access URL request parameters in Render Phase or JSP page.
 
 
Case:2
 
<portlet:actionURL var="portletActionURL" name="addEmployee">
<portlet:param name="<%=ActionRequest.ACTION_NAME%>"value="addEmployee"/>
<portlet:param name="employeeName" value="Meera Prince"/>
</portlet:actionURL>
 
Emplyee Name: <%=renderRequest.getParameter("employeeName")%><br/>
 
In the Case: 2 we are using Portlet Action URL and we are performing action phase, after perform action phase the parameter we passed in request URL not available in Render Phase or JSP page.
 
 
Solution:1
 
We have to use copy request parameter method in portlet class action method so that all URL parameters carried to render phase and it is available in JSP page.
 
<portlet:actionURL var="portletActionURL" name="addEmployee">
<portlet:param name="<%=ActionRequest.ACTION_NAME%>"value="addEmployee"/>
<portlet:param name="employeeName" value="Meera Prince"/>
</portlet:actionURL>
 
Portlet Class Action Method
 
public class EmplyeePortletAction extends MVCPortlet {
public void addEmplyee(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
 
PortalUtil.copyRequestParameters(actionRequest, actionResponse);
      
       }
}
 
Solution:2
 
We can use set render parameter method in portlet class action method to set URL parameters and those URL parameters are carried to render phase or jsp page.
 
<portlet:actionURL var="portletActionURL" name="addEmployee">
<portlet:param name="<%=ActionRequest.ACTION_NAME%>"value="addEmployee"/>
<portlet:param name="employeeName" value="Meera Prince"/>
</portlet:actionURL>
 
Portlet Class Action Method
 
public class EmplyeePortletAction extends MVCPortlet {
public void addEmplyee(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
 
              String employeeName=ParamUtil.getString(actionRequest,"employeeName");
              actionResponse.setRenderParameter("employeeName",employeeName);
       }
}
 
 
 
 
JSP Navigation or Render different Views from Action Phase
 
In general portlet development after performing action phase we need to navigate result page.
To Perform Action URL we already know URL parameters are not available in render phase that is what we cannot set jspPage/mvcPath in Action URL parameter.
 
We need to set this parameter value in Portlet class action method so that after perform action it will render specified jsp page that we mention asmvcPath
 
 
view.jsp
 
<portlet:actionURL var="portletActionURL" name="addEmployee">
<portlet:param name="<%=ActionRequest.ACTION_NAME%>" value="addEmployee"/>
<portlet:param name="employeeName" value="Meera Prince"/>
</portlet:actionURL>
 
Portlet Class Action Method
 
public class EmplyeePortletAction extends MVCPortlet {
public void addEmplyee(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
 
String employeeName=ParamUtil.getString(actionRequest,"employeeName");
actionResponse.setRenderParameter("employeeName",employeeName);
actionResponse.setRenderParameter("mvcPath","/html/jsps/displayEmployee.jsp");
       }
}
 
displayEmployee.jsp
 
Emplyee Name: <%=renderRequest.getParameter("employeeName")%><br/>
 
 
 
Access Form input data or URL request parameters in Portlet Class Action Method
 
In portlet development we will send data from client to server using form input elements or as URL request parameters.
 
In the server side or portlet class action method we will use get Parameteror we have liferay Util class called Param Util to access the URL or form input data.
 
When we use Param Util we have flexibility to access desired data type we need not to do explicit type casting.
 
If we use get Parameter then we needs to do type casting the value to get desired data type because request parameters always is string.
 
Example methods in Param Util class
 
 
String employeeAddress=ParamUtil.getString(actionRequest,"employeeAddress");
int age=ParamUtil.getInteger(actionRequest,"age");
float price =ParamUtil.getFloat(actionRequest,"price");
boolean valid=ParamUtil.getBoolean(actionRequest,"valid");
 
 
 
Jsp page
 
<portlet:actionURL var="addEmployeeActionURL" name="addEmployee">
<portlet:param name="<%=ActionRequest.ACTION_NAME%>"value="addEmployee"/>
<portlet:param name="requestParam" value=" requestParamValue"/>
</portlet:actionURL>
 
<form action="<%=addEmployeeActionURL%>" name="emplyeeForm" method="POST">
Employee Name<br/>
<input  type="text" name="<portlet:namespace/>employeeName" id="<portlet:namespace/>employeeName"/><br/>
Employee Address<br/>
<input type="text" name="<portlet:namespace/>employeeAddress" id="<portlet:namespace/>employeeName"/><br/>
<input type="submit" name="addEmployee" id="addEmployee" value="Add Employee"/>
</form>
 
Portlet Class Action Method
 
public class EmplyeePortletAction extends MVCPortlet {
public void addEmplyee(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
 
String employeeName=ParamUtil.getString(actionRequest,"employeeName");
String employeeAddress=ParamUtil.getString(actionRequest,"employeeAddress");
String requestParamValue=ParamUtil.getString(actionRequest,"requestParam");
 
       }
}
 
OR
 
public class EmplyeePortletAction extends MVCPortlet {
public void addEmplyee(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
 
String employeeName=actionRequest.getParameter("employeeName");
String employeeAddress=actionRequest.getParameter("employeeAddress");
String requestParamValue= actionRequest.getParameter("requestParam");
 
             
       }
}
 
 
 
Required Name Space Parameter Behavior in Liferay
 
Liferay 6.2 we have to append  portlet Name space for every name of input element i.e. form input elements or request parameters names otherwise portlet action class ignore  the parameters which does not have portlet name space to names.
 
Scenario
 
 
Jsp page
 
In the following form we are not appending portlet name space to form input element names.
 
<portlet:actionURL var="addEmployeeActionURL" name="addEmployee">
<portlet:param name="<%=ActionRequest.ACTION_NAME%>"value="addEmployee"/>
</portlet:actionURL>
 
<form action="<%=addEmployeeActionURL%>" name="emplyeeForm" method="POST">
Employee Name<br/>
<input  type="text" name="employeeName" id="employeeName"/><br/>
Employee Address<br/>
<input type="text" name="employeeAddress" id="employeeName"/><br/>
<input type="submit" name="addEmployee" id="addEmployee" value="Add Employee"/>
</form>
 
Portlet Class Action Method
 
public class EmplyeePortletAction extends MVCPortlet {
public void addEmplyee(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
 
String employeeName=ParamUtil.getString(actionRequest,"employeeName");
String employeeAddress=ParamUtil.getString(actionRequest,"employeeAddress");
 
       }
}
 In above case employeeName and employeeAddress form input data not accessible in portlet class action .The form elements name are not appended with portlet name space such scenarios portlet class ignore those request parameters or form inputs
 
 
Solution:1
 
Need to append <portlet:namespace/>  tag to every input element name.
 
Jsp page
 
<portlet:actionURL var="addEmployeeActionURL" name="addEmployee">
<portlet:param name="<%=ActionRequest.ACTION_NAME%>"value="addEmployee"/>
<portlet:param name="requestParam" value=" requestParamValue"/>
</portlet:actionURL>
 
<form action="<%=addEmployeeActionURL%>" name="emplyeeForm" method="POST">
Employee Name<br/>
<input  type="text" name="<portlet:namespace/>employeeName" id="<portlet:namespace/>employeeName"/><br/>
Employee Address<br/>
<input type="text" name="<portlet:namespace/>employeeAddress" id="<portlet:namespace/>employeeName"/><br/>
<input type="submit" name="addEmployee" id="addEmployee" value="Add Employee"/>
</form>
 
Portlet Class Action Method
 
public class EmplyeePortletAction extends MVCPortlet {
public void addEmplyee(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
 
String employeeName=ParamUtil.getString(actionRequest,"employeeName");
String employeeAddress=ParamUtil.getString(actionRequest,"employeeAddress");
String requestParamValue=ParamUtil.getString(actionRequest,"requestParam");
 
       }
}
 
Solution:2
We can make it false to following tag value in liferay-portlet.xml file
 
<requires-namespaced-parameters>false</requires-namespaced-parameters>
 
Solution:3
 
We can use alloy tag library form tags. When we use AUI tags it will append portlet name space to each input element name.
 
Jsp page
 
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
 
<aui:input type="text" name="employeeAddress" id="employeeName"/><br/>
<aui:input type="submit" name="addEmployee" id="addEmployee" value="Add Employee"/
 
 
 
 
<input type="text" name="<portlet:namespace/>employeeAddress" id="<portlet:namespace/>employeeName"/>
 
Is same As
 
<aui:input type="text" name="employeeAddress" id="employeeName"/>
 
 
 
Send the Data from Portlet Class Action method to JSP pages.
 
Generally we need requirement that need to send some data from portlet class action method to jsp pages.
 
After perform some business logic we need to send some data from portlet class action method to jsp pages
 
We have three ways to send data to JSP Pages.
 
 
  1. Set Arrtibute and Get Attribute on portlet  request object
  2. Set Render Parameter method on portlet response object
  3. Copy Render Parameters method

 

Set  Arrtibute and Get Attribute on portlet  request object
 
We will use set Attribute to set some object or value in portlet class Action method and we will use get Attribute method in jsp page to get value in jsp.
 
Example:
 
 
Portlet Class Action Method
 
public void addEmployee(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
 
String employeeName=ParamUtil.getString(actionRequest,"employeeName");
String employeeAddress=ParamUtil.getString(actionRequest,"employeeAddress");
Map<String,String> employeeMap=new HashMap<String,String>();
employeeMap.put("employeeName",employeeName);
employeeMap.put("employeeAddress",employeeAddress);
actionRequest.setAttribute("employeeMap", employeeMap);
       }
 
 
In the above portlet class action method we are passing employee data from map object, we will set map object in request.
 
Get the map object in JSP  page
 
 
Jsp page
 
<%@page import="java.util.Map"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<h1>Display Employee Derails</h1>
 
<%
Map<String,String> employeeMap=(Map<String,String>)renderRequest.getAttribute("employeeMap");
if(employeeMap!=null){
%>
Emplyee Name: <%=employeeMap.get("employeeName")%>     <br/>
Emplyee Address: <%=employeeMap.get("employeeAddress")%><b/>
<%}%>
 
 
Set Render parameter method on Portlet Response Object
 
Set Render Parameter method will set the parameter and its values in portlet query string. We can only set the string values using this method.
 
Example:
 
In the portlet class action method
 
 
Portlet Class Action Method
 
public void addEmployee(ActionRequest request,ActionResponse response)throws PortletException,java.io.IOException{
        String emplyeeName=request.getParameter("employeeName");
        String employeeAddress=request.getParameter("employeeAddress");
        response.setRenderParameter("employeeName",emplyeeName);
        response.setRenderParameter("employeeAddress",employeeAddress);  
      
    }
 
Get the Parameter Values in JSP Page that already set in Process Action
 
Emplyee Name: <%=renderRequest.getParameter("employeeName")%> <br/>
Emplyee Address: <%=renderRequest.getParameter("employeeAddress")%><br/>
 
 
 
Copy Render Parameters method
 
 
<portlet:actionURL var="addEmployeeActionURL" name="addEmployee">
<portlet:param name="mvcPath"value="/html/helloworld/displayEmployee.jsp"/>
<portlet:param name="emplyeeName" value="Meera Prince"/>
</portlet:actionURL>
 
Portlet Class Action Method
 
public void addEmployee(ActionRequest actionRequest,
                     ActionResponse actionResponse) throws IOException, PortletException {
          PortalUtil.copyRequestParameters(actionRequest, actionResponse);
       }
 
Now we can access request parameters in displayEmployee jsp page
 
Jsp page
 
Emplyee Name: <%=renderRequest.getParameter("employeeName")%> <br/>
 
 
 
Liferay Tag Libraries and its Usage in JSP page.
 
Liferay have rich built in tag libraries and they have many components in set of library.
 
The following are useful tag libraries in JSP page
 
  • AUI Tag Library
  • Liferay Portlet Tag Library
  • Liferay Theme Tag Library
  • Liferay UI Tag Library
  • Liferay Util Tag Library

 

To Use all tag Libraries in JSP page
 
Add following Tag lib URI in any of the portlet application jsp page so that we can use many tags in JSP page. For details information about tag please have look into tag lib tld file.
 
 
 
 
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet"%>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://liferay.com/tld/util" prefix="liferay-util" %>
 
 
Access Liferay Implicit Objects
 
Liferay have provided some of the important implicit variables to use in JSP pages.To access those implicit variables we need add following tags in jsp page so that we can access renderRequest, renderResponse, themeDisply, user and Layout.
 
Add following tags in JSP page
 
 
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet"%>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://liferay.com/tld/util" prefix="liferay-util" %>
 
<liferay-theme:defineObjects />
<portlet:defineObjects />
 
 
Liferay MVC Employee Portlet Example Code.


Download MVC Portlet Examples
 

 
MVC Portlet Directory Structure
 
 
Web.xml
 
 
<?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>LiferayMVCEmployee-portlet</display-name>
      
       <jsp-config>
              <taglib>
                     <taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri>
                     <taglib-location>
                           /WEB-INF/tld/liferay-portlet.tld
                     </taglib-location>
              </taglib>
              <taglib>
                     <taglib-uri>http://liferay.com/tld/aui</taglib-uri>
                     <taglib-location>/WEB-INF/tld/aui.tld</taglib-location>
              </taglib>
       </jsp-config>
</web-app>
 
 
Portlet.xml
 
 
<?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>employeeliferaymvc</portlet-name>
              <display-name>Employee MVC Portlet</display-name>
              <portlet-class>
                     com.meera.liferaymvc.EmployeePortletAction
              </portlet-class>
              <init-param>
                     <name>view-template</name>
                     <value>/html/jsps/view.jsp</value>
              </init-param>
              <expiration-cache>0</expiration-cache>
              <supports>
                     <mime-type>text/html</mime-type>
                     <portlet-mode>view</portlet-mode>
              </supports>
              <portlet-info>
                     <title>Employee MVC Portlet</title>
                     <short-title>Employee Portlet Action</short-title>
                     <keywords></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>
 
 
Liferay-portlet.xml
 
 
<?xml version="1.0"?>
<!DOCTYPE liferay-portlet-app
PUBLIC "-//Liferay//DTD Portlet Application 6.2.0//EN"
"http://www.liferay.com/dtd/liferay-portlet-app_6_2_0.dtd">
<liferay-portlet-app>
       <portlet>
              <portlet-name>employeeliferaymvc</portlet-name>
              <icon>/icon.png</icon>
              <instanceable>false</instanceable>
              <header-portlet-css>/css/main.css</header-portlet-css>
              <footer-portlet-javascript>
                     /js/main.js
              </footer-portlet-javascript>
              <css-class-wrapper>
                     employeeliferaymvc-portlet
              </css-class-wrapper>
       </portlet>
       <role-mapper>
              <role-name>administrator</role-name>
              <role-link>Administrator</role-link>
       </role-mapper>
       <role-mapper>
              <role-name>guest</role-name>
              <role-link>Guest</role-link>
       </role-mapper>
       <role-mapper>
              <role-name>power-user</role-name>
              <role-link>Power User</role-link>
       </role-mapper>
       <role-mapper>
              <role-name>user</role-name>
              <role-link>User</role-link>
       </role-mapper>
</liferay-portlet-app>
 
 
Liferay-display.xml
 
 
<?xml version="1.0"?>
<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 6.2.0//EN"
"http://www.liferay.com/dtd/liferay-display_6_2_0.dtd">
<display>
       <category name="category.sample">
              <portlet id="employeeliferaymvc"></portlet>
       </category>
</display>
 
 
Portlet Action Class
 
 
package com.meera.liferaymvc;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
public class EmployeePortletAction extends MVCPortlet {
       public void addEmployee(ActionRequest actionRequest,
                     ActionResponse actionResponse) throws IOException, PortletException {
String employeeName = ParamUtil.getString(actionRequest, "employeeName");
              String employeeAddress = ParamUtil.getString(actionRequest,
                           "employeeAddress");
              Map<String, String> employeeMap = new HashMap<String, String>();
              employeeMap.put("employeeName", employeeName);
              employeeMap.put("employeeAddress", employeeAddress);
              actionRequest.setAttribute("employeeMap", employeeMap);
              actionResponse.setRenderParameter("mvcPath","/html/jsps/displayEmployee.jsp");
       }
}
 
 
Default portlet view page (view.jsp)
 
 
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<portlet:renderURL  var="addEmployee" windowState="normal">
<portlet:param name="mvcPath" value="/html/jsps/addEmployee.jsp"/>
</portlet:renderURL>
<h1>Welcome to Liferay MVC Employee Portlet</h1>
<a href="<%=addEmployee.toString()%>">Add Employee</a><br/>
 
 
 
Add Employee JSP page (/html/jsps/addEmployee.jsp)
 
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<portlet:actionURL var="addEmployeeActionURL" windowState="normal"name="addEmployee">
</portlet:actionURL>
<h1> Add Employee</h1>
<form action="<%=addEmployeeActionURL%>" name="emplyeeForm" method="POST">
Employee Name<br/>
<input  type="text" name="<portlet:namespace/>employeeName" id="<portlet:namespace/>employeeName"/><br/>
Employee Address<br/>
<input type="text" name="<portlet:namespace/>employeeAddress" id="<portlet:namespace/>employeeName"/><br/>
<input type="submit" name="addEmployee" id="addEmployee" value="Add Employee"/>
</form>
 
 
Display Employee JSP page (/html/jsps/displayEmployee.jsp)
 
 
<%@page import="java.util.Map"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<h1>Display Employee Details</h1>
<%
Map<String,String> employeeMap=(Map<String,String>)renderRequest.getAttribute("employeeMap");
if(employeeMap!=null){
%>
Emplyee Name: <%=employeeMap.get("employeeName")%>     <br/>
Emplyee Address: <%=employeeMap.get("employeeAddress")%><b/>
<%}%>
 
 
 
Portlet out Put Screens
 
Portlet Default view page
 
 
 
Add Employee Screen
 
 
Display Employee Screen
 
 
Related Articles
 
 
 
Author

Liferay CometD Ajax Push / Liferay Reverse Ajax

Technical Blogs April 11, 2014 By Meera Prince

Introduction:
 
Ajax Push is a mechanism to push data from server. Generally in the web application when the client request for the server then we will get the dynamic data or updated data from server to web client/browser.
 
But sometimes we need a mechanism it automatically push data from server to client this is called server push mechanism. Server push is technique to push data from server to client. In this scenarios client will not send request to server but server will automatically push the data to client when it get updated.
 
To make it work server push technique we will use one protocol calledBayeux protocol.
 
Bayeux:
 
Bayeux is a protocol for transporting asynchronous messages (primarily over HTTP), with low latency between a web server and a web client. The messages are routed via named channels and can be delivered
 
We can use protocol for server to client, client to server, client to client (via the server)
The primary purpose of Bayeux is to support responsive bidirectional interactions between web clients, for example using AJAX, and the web server.
 
Here we will produce data on some channels and client will subscribe channels. When client subscribe channeled as soon as data published on channels will aquatically reached the client who are subscribed channels.
 
 
CometD
 
CometD is a scalable HTTP-based event routing bus that uses a Ajax Push technology pattern known as Comet
 
CometD is a Dojo Foundation project to provide implementations of the Bayeux protocol in JavaScript, java, Perl, python and other languages. Other organizations (eg. Sun, IBM and BEA) also have implementations of Bayeux that are not strictly part of the CometD project, but where possible they are linked to from this site.
 
 
Environment:
 
Liferay 6.2 +Tomcat 7.x+MySQL 5.1
 
Note:
 
The code will work for portal 6.2 version you can try for 6.1 too.
 
Download Liferay CometD Ajax Push Portlet from following location
You can find source and war file
 
 
Portlet Screen-1:
 
 
Procedure for deploy portlet ans Use:
 
You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.
 
Once portlet is deployed successfully you can see the portlet in samplecategory name as Liferay Commet D Reverse Ajax.
 
As soon as you place the portlet in page you can see updated stock prices for every few seconds and it will be updated automatically.
 
You can also open portlet in another browser there also you can see price changes automatically.
 
Note:
 
Before use this portlet please Read entire Article and Use it
 
Implementation:
 
We will use Bayeux java implementation for produce data on channels.
 
Once data produced on channels we will use CometD java script implementation to get the data to client automatically. We have Dojo and JQuery java script implementation for CometD.
 
 
Using ComedD Ajax Push in Liferay Portlet
 
  1. Configure CometD servlet in portlet web.xml
  2. Implement Data Producer to produce data
  3. Implement Service to publish data on Channels Using Bayeux
  4. Use CometD java script in client side to subscribe channel and show data.

 

Concept:
 
We will take an example of stock prices updates so that we will send stock price changes to client when changes in price changes in stocks.
 
We will use Java Scheduler to produce data for every few second from server side and as soon as data produced we will use CometD service to publish data on channels.
 
In the client side we will use CometD JQuery to subscribe the channels and show the stock price changes.
 
Configure CometD servlet in portlet web.xml
 
We need configure CometD servlet to initiate all the process. We have different servlets one of the servlet AnnotationCometdServlet and need to pass CometD service as init parameter.
 
The following is code snippet
 
<servlet>
        <servlet-name>cometd</servlet-name>
        <servlet-class>org.cometd.annotation.AnnotationCometdServlet</servlet-class>
        <init-param>
            <param-name>transports</param-name>
            <param-value>org.cometd.websocket.server.WebSocketTransport</param-value>
        </init-param>
        <init-param>
            <param-name>services</param-name>
            <param-value>com.meera.commetd.StockPriceService</param-value>
        </init-param>
        <init-param>
            <param-name>maxLazyTimeout</param-name>
            <param-value>2000</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>cometd</servlet-name>
        <url-pattern>/cometd/*</url-pattern>
    </servlet-mapping>
 
 
Implement Data Producer to produce data
 
We already we need some source need to generate data so we will use some java class to produce data.
 
We will randomly generate some price for stock quotes and we have used Scheduler Executer to run this task for every few seconds. We have usedStockPriceEmitter java class
 
 
Implement Service to publish data on Channels Using Bayeux
 
We need service that responsible for publish data on channels with the help of Bayeux protocol. We need create channel and then need to publish
 
The following example syntax to create channel and publish
 
Create channel
 
 
bayeuxServer.createChannelIfAbsent(channelName, newConfigurableServerChannel.Initializer()
            {
                public void configureChannel(ConfigurableServerChannel channel)
                {
                    channel.setPersistent(true);
                    channel.setLazy(true);
                }
            });
 
 
 
Publish data on channel
 
 
ServerChannel channel = bayeuxServer.getChannel(channelName);
            channel.publish(sender, data);
 
 
Use CometD java script in client side to subscribe channel and show data
 
In the client side will use CometD java script implementation to subscribe channel and show the data.
 
We need configure CometD servlet URL and need to add two leisters to make hand shake with server.
 
The following syntax
 
 
var cometURL = location.protocol + "//" + location.host + config.contextPath + "/cometd";
        cometd.configure({
            url: cometURL,
            logLevel: 'debug'
        });
 
        cometd.addListener('/meta/handshake', _metaHandshake);
        cometd.addListener('/meta/connect', _metaConnect);
        cometd.handshake();
 
 
Subscribe Channel Syntax
 
 
cometd.subscribe('/stock/*', function(message)
                    {
var data = message.data;
 
});
 
 
Note:
 
We need add CometD java script implementation source in page and we will use cometd is java script object available to call methods.
 
We have implement application related java script in application.js
 
The following are all required java script source files
 
 
<scriptsrc="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/cometd-namespace.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/cometd-json.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/AckExtension.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/TransportRegistry.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/Transport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/RequestTransport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/WebSocketTransport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath()%>/js/comet/CallbackPollingTransport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/LongPollingTransport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/Utils.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/Cometd.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/jquery.cometd.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/application.js"></script>
 
 
Complete Source code for Implementation
 
The following is web.xml file
 
 
<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>LiferayCommetDRevserseAjax-portlet</display-name>
        <servlet>
        <servlet-name>cometd</servlet-name>
        <servlet-class>org.cometd.annotation.AnnotationCometdServlet</servlet-class>
        <init-param>
            <param-name>transports</param-name>
            <param-value>org.cometd.websocket.server.WebSocketTransport</param-value>
        </init-param>
        <init-param>
            <param-name>services</param-name>
            <param-value>com.meera.commetd.StockPriceService</param-value>
        </init-param>
        <init-param>
            <param-name>maxLazyTimeout</param-name>
            <param-value>2000</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>cometd</servlet-name>
        <url-pattern>/cometd/*</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>cross-origin</filter-name>
        <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>cross-origin</filter-name>
        <url-pattern>/cometd/*</url-pattern>
    </filter-mapping>
       <jsp-config>
              <taglib>
                     <taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri>
                     <taglib-location>
                           /WEB-INF/tld/liferay-portlet.tld
                     </taglib-location>
              </taglib>
              <taglib>
                     <taglib-uri>http://liferay.com/tld/aui</taglib-uri>
                     <taglib-location>/WEB-INF/tld/aui.tld</taglib-location>
              </taglib>
       </jsp-config>
</web-app>
 
 
The following is StockPriceServiceJava Class
 
 
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.inject.Inject;
import org.cometd.annotation.Service;
import org.cometd.annotation.Session;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ConfigurableServerChannel;
import org.cometd.bayeux.server.LocalSession;
import org.cometd.bayeux.server.ServerChannel;
@Service
public class StockPriceService implements StockPriceEmitter.Listener
{
    @Inject
    private BayeuxServer bayeuxServer;
    @Session
    private LocalSession sender;
 
    public void onUpdates(List<StockPriceEmitter.Update> updates)
    {
        for (StockPriceEmitter.Update update : updates)
        {
            // Create the channel name using the stock symbol
            String channelName = "/stock/" + update.getSymbol().toLowerCase(Locale.ENGLISH);
 
            // Initialize the channel, making it persistent and lazy
            bayeuxServer.createChannelIfAbsent(channelName, newConfigurableServerChannel.Initializer()
            {
                public void configureChannel(ConfigurableServerChannel channel)
                {
                    channel.setPersistent(true);
                    channel.setLazy(true);
                }
            });
 
            // Convert the Update business object to a CometD-friendly format
            Map<String, Object> data = new HashMap<String, Object>(4);
            data.put("symbol", update.getSymbol());
            data.put("oldValue", update.getOldValue());
            data.put("newValue", update.getNewValue());
              System.out.println("===========================");
            // Publish to all subscribers
            ServerChannel channel =bayeuxServer.getChannel(channelName);
            channel.publish(sender, data);
        }
    }
}
 
 
 
The following is StockPriceEmitter java class
 
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EventListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; 
public class StockPriceEmitter implements Runnable {
       private final ScheduledExecutorService scheduler = Executors
                     .newSingleThreadScheduledExecutor();
       private final List<String> symbols = new ArrayList<String>();
       private final Map<String, Float> values = new HashMap<String, Float>();
       private final List<Listener> listeners = newCopyOnWriteArrayList<Listener>();
 
       public StockPriceEmitter() {
              symbols.addAll(Arrays.asList("ORCL", "MSFT", "GOOG","YHOO", "FB"));
              values.put("ORCL", 29.94f);
              values.put("MSFT", 27.10f);
              values.put("GOOG", 655.37f);
              values.put("YHOO", 17.82f);
              values.put("FB", 21.33f);
       }
       public List<Listener> getListeners() {
              return listeners;
       }
       public void start() {
              run();
       }
       public void stop() {
              scheduler.shutdownNow();
       }
       public void run() {
              Random random = new Random();
 
              List<Update> updates = new ArrayList<Update>();
 
              // Randomly choose how many stocks to update
              int howMany = random.nextInt(symbols.size()) + 1;
              for (int i = 0; i < howMany; ++i) {
                     // Randomly choose which one to update
                     int which = random.nextInt(symbols.size());
                     String symbol = symbols.get(which);
                     float oldValue = values.get(symbol);
 
                     // Randomly choose how much to update
                     boolean sign = random.nextBoolean();
                     float howMuch = random.nextFloat();
                     float newValue = oldValue + (sign ? howMuch : -howMuch);
 
                     // Store the new value
                     values.put(symbol, newValue);
 
                     updates.add(new Update(symbol, oldValue, newValue));
              }
 
              // Notify the listeners
              for (Listener listener : listeners) {
                     listener.onUpdates(updates);
              }
 
              // Randomly choose how long for the next update
              // We use a max delay of 1 second to simulate a high rate of updates
              long howLong = random.nextInt(1000);
              scheduler.schedule(this, howLong, TimeUnit.MILLISECONDS);
       }
 
       public static class Update {
              private final String symbol;
              private final float oldValue;
              private final float newValue;
 
              public Update(String symbol, float oldValue, floatnewValue) {
                     this.symbol = symbol;
                     this.oldValue = oldValue;
                     this.newValue = newValue;
              }
 
              public String getSymbol() {
                     return symbol;
              }
 
              public float getOldValue() {
                     return oldValue;
              }
 
              public float getNewValue() {
                     return newValue;
              }
       }
 
       public interface Listener extends EventListener {
              void onUpdates(List<Update> updates);
       }
}
 
 
The following is Liferay Portlet Class
 
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import com.liferay.util.bridges.mvc.MVCPortlet;
public class LiferayCommetDReverseAjax extends MVCPortlet {
     private StockPriceEmitter emitter;
    public void startStockUpdates(
    ActionRequest actionRequest, ActionResponse actionResponse)
                     throws IOException, PortletException {
    emitter = new StockPriceEmitter();
 StockPriceService service(StockPriceService)getPortletContext().
getAttribute(StockPriceService.class.getName());
  // Register the service as a listener of the emitter
  emitter.getListeners().add(service);
                      // Start the emitter
    emitter.start();
              }
public void stopStockUpdates(
ActionRequest actionRequest, ActionResponse actionResponse)
throws IOException, PortletException {
//emitter = new StockPriceEmitter();
emitter.stop();
              }
}
 
 
The following is application.js code
 
 
(function($)
{
    var cometd = $.cometd;
//alert(cometd);
    $(document).ready(function()
    {
        function _connectionEstablished()
        {
            $('#body').append('<div>CometD Connection Established</div>');
        }
 
        function _connectionBroken()
        {
            $('#body').append('<div>CometD Connection Broken</div>');
        }
 
        function _connectionClosed()
        {
            $('#body').append('<div>CometD Connection Closed</div>');
        }
 
        // Function that manages the connection status with the Bayeuxserver
        var _connected = false;
        function _metaConnect(message)
        {
            if (cometd.isDisconnected())
            {
                _connected = false;
                _connectionClosed();
                return;
            }
 
            var wasConnected = _connected;
            _connected = message.successful === true;
            if (!wasConnected && _connected)
            {
                _connectionEstablished();
            }
            else if (wasConnected && !_connected)
            {
                _connectionBroken();
            }
        }
 
        // Function invoked when first contacting the server and
        // when the server has lost the state of this client
        function _metaHandshake(handshake)
        {
            if (handshake.successful === true)
            {
                cometd.batch(function()
                {
                    cometd.subscribe('/stock/*', function(message)
                    {
                    
                    var data = message.data;
                        var symbol = data.symbol;
                        var value = data.newValue;
                       // alert(symbol);
                        var id = 'stock_'+ symbol;
                        var symbolDiv=document.getElementById(id);
                        if (!symbolDiv)
                        {
                        symbolDiv = document.createElement('div');
                        symbolDiv.id =id;
                        document.getElementById('stocks').appendChild(symbolDiv);
                        }
                        symbolDiv.innerHTML = '<span class="symbol">' + symbol + ': <b>' + value + '</b></span>';
                    });
                    // Publish on a service channel since the message is for the server only
                    //cometd.publish('/stock/*', { name: 'World' });
                });
            }
        }
 
        // Disconnect when the page unloads
        $(window).unload(function()
        {
            cometd.disconnect(true);
        });
 
        var cometURL = location.protocol + "//" + location.host + config.contextPath + "/cometd";
        cometd.configure({
            url: cometURL,
            logLevel: 'debug'
        });
 
        cometd.addListener('/meta/handshake', _metaHandshake);
        cometd.addListener('/meta/connect', _metaConnect);
        cometd.handshake();
    });
})(jQuery);
 
 
The following is portlet JSP page.
 
 
<%@ include file="init.jsp"%>
 <scriptsrc="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/cometd-namespace.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/cometd-json.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/AckExtension.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/TransportRegistry.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/Transport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/RequestTransport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/WebSocketTransport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath()%>/js/comet/CallbackPollingTransport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/LongPollingTransport.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/Utils.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/Cometd.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/jquery.cometd.js"></script>
           <script type="text/javascript" src="<%=renderRequest.getContextPath() %>/js/comet/application.js"></script>
<%--
    The reason to use a JSP is that it is very easy to obtain server-side configuration
    information (such as the contextPath) and pass it to the JavaScript environment on the client.
    --%>
<style>
#stocks .symbol b{
color:red;
}
#controler-table td{
padding-left:30px;
}
</style>
<script type="text/javascript">
        var config = {
            contextPath: '<%=renderRequest.getContextPath()%>'
        };
 </script>
<portlet:actionURL  var="startStockUpdates" name="startStockUpdates">
</portlet:actionURL>
<portlet:actionURL  var="stopStockUpdates" name="stopStockUpdates">
</portlet:actionURL>
<h2>Liferay CometD Ajax Push Portlet</h2>
<br/>
<table id="controler-table">
       <tr>
              <td><a href="<%=startStockUpdates.toString()%>">Start</a></td>
              <td><a href="<%=stopStockUpdates.toString()%>">Stop</a></td>
       </tr>
</table>
<br/>
<div id="stocks"></div>
 
 
Author

Liferay Auto Complete List with Ajax

Technical Blogs March 4, 2014 By Meera Prince

Introduction:
 
Liferay Have given AUI Auto complete list from which we can populate matching values to user in input fields and data will be served from server with help of Ajax call.
 
AUI Auto Complete list need source property this specify the data which populated in input filtered.
 
This is very useful component in Liferay AUI so that we can populate exact matching result to end user instead of all available values.
 
Environment:
 
Liferay 6.2 +Tomcat 7.x+MySQL 5.1
 
Note:
 
The code will work for portal 6.2 version you can try for 6.1 too.
 
Download Liferay AUI Auto Complete List with Ajax from following location
 
You can find source and war file
 
 
Portlet Screen-1:
 
 
Portlet Screen-2:
 
 
Procedure for deploy portlet:
 
You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.
 
Once portlet is deployed successfully you can see the portlet in sample category name as Liferay AUI Auto Complete List with Ajax.
 
Note:
 
Before use this portlet please Read entire Article and Use it
Go thorough following posts to get basic Understand about Liferay AUI Auto Complete List
 
 
Scenario: 1
 
Get all the data from server at one time and filter user desired values
 
In the last post I fetched the all values at one time to Input files and I am populating and when user type any string or letter It will display matching values.
 
Here only one time it requested to server through Ajax and gets all possible values to client side then AUI Auto Complete List will filter the values from all values at client side when user type something in input field.
 
Note:
 
Above scenario already covered in last post please has a look into following post.
 
 
Please read above article before start this article.
 
Scenario: 2
 
Get Matching Data from server for each user Input
 
In this scenario we will bring exact matching result from server for each time when use types something in input field.
 
Auto Complete List have capability to call back method for each user input so that we will use Ajax call to send request get the data from server.
 
I just took User table example so that when user type anything in input box I just search user based on email address that given by user.
 
Steps to implement
 
  1. Use AUI use function to load required AUI Java Script Modules.
  2. Create AUI Auto Complete List and pass required options
  3. Implement AUI IO Ajax in AUI Auto Complete List call back function
  4. Implement Server Resource Method in Portlet Action class to search data from user table.

 

Note:
 
We will use Server Resource method in portlet action class to server JSON Data and we will use Dynamic Query API to search user data from database.
 
The following is example Code in JSP page.
 
<%@page import="com.liferay.portal.kernel.util.Constants"%>
<%@ include file="init.jsp"%>
<portlet:resourceURL var="getUsers">
       <portlet:param name="<%=Constants.CMD%>" value="get_users" />
</portlet:resourceURL>
<h2>Liferay Auto Complete List with Ajax</h2><br/>
<aui:input id="myInputNode" name="myInputNode" label="User Email"
       helpMessage="Type User Email address in Input Box" />
<aui:script>
AUI().use('autocomplete-list','aui-base','aui-io-request','autocomplete-filters','autocomplete-highlighters',function (A) {
var testData;
new A.AutoCompleteList({
allowBrowserAutocomplete: 'true',
activateFirstItem: 'true',
inputNode: '#<portlet:namespace />myInputNode',
resultTextLocator:'email',
render: 'true',
resultHighlighter: 'phraseMatch',
resultFilters:['phraseMatch'],
source:function(){
var inputValue=A.one("#<portlet:namespace />myInputNode").get('value');
var myAjaxRequest=A.io.request('<%=getUsers.toString()%>',{
dataType: 'json',
method:'POST',
data:{
<portlet:namespace />userEmail:inputValue,
},
autoLoad:false,
sync:false,
on: {
success:function(){
var data=this.get('responseData');
testData=data;
}}
});
myAjaxRequest.start();
return testData;},
});
});
</aui:script>
 
Note:
 
When we use AUI IO Ajax call in Auto Complete List we need to first define AUI IO request and we need to start Ajax call with start method.
 
When we manually start Ajax call we need to make autoLoada false.
 
Go through following link more about AUI IO Request
 
 
The following sample code in Portlet Action Class
 
public class LiferayAUIAutoCompleteListWithAjaxAction extends MVCPortlet {
@Override
public void serveResource(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws IOException,
PortletException {
String cmd = ParamUtil.getString(resourceRequest, Constants.CMD);
System.out.println("Constants.CMD: " + cmd);
if (cmd.equals("get_users")) {
getUsers(resourceRequest, resourceResponse);
}}
private void getUsers(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws IOException,
PortletException {
JSONArray usersJSONArray = JSONFactoryUtil.createJSONArray();
ThemeDisplay themeDisplay = (ThemeDisplay) resourceRequest.getAttribute(WebKeys.THEME_DISPLAY);
String userEmail = ParamUtil.getString(resourceRequest, "userEmail");
System.out.println("=====00000========" + userEmail);
DynamicQuery userQuery = DynamicQueryFactoryUtil.forClass(User.class,
PortalClassLoaderUtil.getClassLoader());
Criterion criterion = RestrictionsFactoryUtil.like("emailAddress",
StringPool.PERCENT + userEmail + StringPool.PERCENT);
userQuery.add(criterion);
JSONObject userJSON = null;
System.out.println("=====1111========" + userQuery.toString());
try {
List<User> userList = UserLocalServiceUtil.dynamicQuery(userQuery);
System.out.println("=====222========" + userList.size());
for (User user : userList) {
userJSON = JSONFactoryUtil.createJSONObject();
userJSON.put("userId", user.getUserId());
userJSON.put("email", user.getEmailAddress());
userJSON.put("firstName", user.getFirstName());
usersJSONArray.put(userJSON);
}} catch (Exception e) {
}
PrintWriter out = resourceResponse.getWriter();
out.println(usersJSONArray.toString());
}
}
 
Note:
 
In the above code we used Liferay Dynamic query to search user data from table, this pretty good mechanism and this is alternative to custom sql in liferay.
 
Related Articles:
 
 
 
 
Reference Links:
 
 
 
 
 
Author

Working with Liferay Custom Fields

Technical Blogs February 14, 2014 By Meera Prince

Introduction:
 
Liferay have every good feature that is Custom Fields from this we can create additional attributes or new fields to existed entities.
 
Please go through following Tutorial for Introduction
 
 
Environment:
 
Liferay 6.2 +Tomcat 7.x+MySQL 5.1
 
Note:
 
The code will work for portal 6.2 version you can try for 6.1 too.
 
Download Liferay Custom Fields Portlet from following location
 
You can find source and war file
 
 
Portlet Screen1:
 
 
Portlet Screen2:
 
 
Portlet Screen3:
 
 
 
Procedure for deploy portlet:
 
You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.
 
Once portlet is deployed successfully you can see the portlet in sample category name as Liferay Custom Fields.
 
Note:
 
Before use this portlet please Read entire Article and Use it
 
Implementation
 
Now we will see how to use custom filed in real time development.
We are going create new custom fields to user so that we can add additional information user.Assume we are creating Custom Fields to User Entity
 
  1. Create Custom Fields
  2. Using Custom Fields in Plugin Portlet Development

 

Create Custom Fields
 
We need create required custom attributes to user entity from liferay portal admin screen.
Assume we want create two custom fields to track user education details and  I am choosing select input and text input as my requirement.
 
Login as Portal Admin and go to Admin Control Panel
 
The following screen show control panel link
 
 
As soon as we click we can go Admin control panel there we can see many admin sections
 
The following screen show Admin Control Panel and sections
 
 
 
In the configurations section we can see Custom Fields Link. We need to click on that and we will go to the custom field’s screen
 
The following is all entities witch support Custom Field Feature. Now we are going to create custom fields for User. You can click on User entity link
 
 
As soon as we click on User entity we can see following screen
 
 
 
We have button called add custom filed button when we click button it will go to add custom field screen there it will ask custom field key and its type
 
The following is create custom field screen
 
 
 
We can create many types of fields like text box, select like all form fields apart from that we can also have choice to select fields accept data type too. The above screen in type field you can see all possibilities
 
Now we need to give attribute key and type then we can save custom field.
 
Here very important is attribute key we will use this as reference to access custom field.
Once we save then you can see following screen where you can see all list of custom fields and its properties
 
 
 
We can also have edit and set permission to custom fields.
 
The following screen shows you edit and permission options
 
 
 
The following screen shows you permission screen for custom field
 
 
 
Assume we have created select Field as follows and we click on save then field will be saved.
 
 
 
 
To fill options to select box we need click on edit field then we can get more properties as follows
 
 
 
In the above screen there you can find values input field there I passed required select options with comma separate. After completion of edit you can save the field
 
The following is example for Text Field
 
 
Now we have created two custom fields for user and one is select box another one is text box
The following screen shows Available Custom Fields for User
 
 
Now we have done creation of custom fields to user
 
View User Custom Fields
 
To view custom fields for user we need to go MY Account page there you can see custom field section.
 
When you click on custom fields you call see available custom fields to user there you add or update the data.
 
The following is screen show navigate to my account page
 
 
The following screen shows custom fields for user and we can add or update data here
 
 
 
Using Custom Fields in Plugin Portlet Development
 
Before going to use custom fields we need to ready with custom fields
 
The following is code for Display Custom Fields as Editable Mode
 
<%@page import="com.liferay.portal.model.User"%>
<%@ include file="init.jsp" %>
<%
User selUser=themeDisplay.getUser();
 
%>
<portlet:actionURL  var="updateUserCustomeAttributeURL"
name="updateUserCustomeAttributes">
</portlet:actionURL>
<aui:form action="<%= updateUserCustomeAttributeURL %>" method="post"name="fm">
<aui:input name="currentUserId" value="<%=user.getUserId()%>"type="hidden"/>
                     <liferay-ui:custom-attribute-list
                     className="<%= User.class.getName() %>"
                     classPK="<%= selUser != null ? selUser.getUserId() : 0 %>"
                     editable="<%= true %>" label="true"/>
<aui:button type="submit" value="update"/>
</aui:form>  
 
Update Data for User Custom Fields
 
The following is code we need place in Portlet Action Class to Update/Add Data
 
public void updateUserCustomeAttributes(ActionRequest actionRequest, ActionResponse actionResponse)throws IOException,
 PortletException, PortalException, SystemException {
ServiceContext serviceContext = 
ServiceContextFactory.getInstance(User.class.getName(), actionRequest);
long currentUserId = ParamUtil.getLong(actionRequest,"currentUserId");
User user=UserLocalServiceUtil.getUser(currentUserId);
user.setExpandoBridgeAttributes(serviceContext);
UserLocalServiceUtil.updateUser(user);
}
 
View Custom Field Data in JSP Page
 
<%
User selUser=themeDisplay.getUser();
%>
<h2>User Education Details</h2>
<liferay-ui:custom-attribute-list
className="<%= User.class.getName() %>"
classPK="<%= selUser != null ? selUser.getUserId() : 0 %>"
editable="<%= false %>" label="true"/>
<aui:button type="submit" value="update"/>
 
Display Single Field as Editable
 
<%
User selUser=themeDisplay.getUser();
 
%>
<h2>User Education Details</h2>
<liferay-ui:custom-attribute
 className="<%= User.class.getName() %>"
 classPK="<%= selUser != null ? selUser.getUserId() : 0 %>"
editable="<%= true %>"
name="Qualification" label="true"/>
 
View Single Field Data
 
<%
User selUser=themeDisplay.getUser();
%>
<h2>User Education Details</h2>
<liferay-ui:custom-attribute
 className="<%= User.class.getName() %>"
 classPK="<%= selUser != null ? selUser.getUserId() : 0 %>"
editable="<%= false %>"
name="Qualification" label="true"/>
 
Note:
 
Validation for this is not straight forward way we need use Java Script and we need to apply manually.
Author

Liferay Plugin Portlet JSON Web Services

Technical Blogs February 11, 2014 By Meera Prince

Introduction:

Liferay have in built support for REST API so we can create REST web services for Plugin portlets means we can create web services for custom entities or portlet related entities.
 
Creating web services in Plugin portlet is very easy and we will use service builder help to generate web services.
 
Generate JSON web service in Plugin Portlet
 
  1. Create simple Liferay MVC Portlets using Liferay IDE with eclipse
  2. Define required entities in service.xml file and use remote service true for entities
  3. Run service builder
  4. Define web service java method in XXXServiceImpl and Run service Builder
  5. Deploy the portlet into server
  6. Access Plugin Portlet JSON Web Services

Steps to Produce  JSON web services in Liferay Plugin Portlet
 
The Following are the steps write custom methods to produce JSON web services:
 
Create simple Liferay MVC Portlets using Liferay IDE with eclipse
 
Create Plugin portlet in Liferay using liferay IDE and portlet is liferay MVC portlet.
 
Go through following link to setup Liferay Development Environment
 
 
Define required entities in service.xml file and use remote service true for entities
 
Create service.xml file in Portlet WEB-INF directory or we can also use liferay IDE to create service.xml file this is nothing but create service builder for Plugin portlet
 
Open service.xml file and define data base tables and put remote-service is true. When we put remote service true then it will create default JSON web services.
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.1.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd">
<service-builder package-path="com.meera.jsonwebservices.db">
            <author>E5410</author>
            <namespace>JSON</namespace>
            <entity name="Employee" local-service="true" remote-service="true">
                        <column name="emplyeeId" type="long" primary="true"/>
                        <column name="emplyeeName" type="String" />
                        <column name="employeeDesignation" type="String" />
                        <order by="asc">
                                    <order-column name="emplyeeId" />
                        </order>
            </entity>
</service-builder>
 
Run service builder
 
Run service builder using ant build-service or in eclipse you can run this from ant view.
 
Define web service java method in XXXServiceImpl and Run service Builder
 
We need to write java method there we will implement according to our requirement.
We need to decide for which entity we have to provide JSON Web Services and find appropriate entity and write required java methodXXXServiceImpl.java and the XXXServiceImpl class is under package
 
 your-base-package.service.impl package of your source.
 
Here XXX is entity name which is specified in service.xml
 
In our example I have implemented in EmployeeServiceImpl.java here I am getting employee object by employeeId. This method return employee object. In liferay any object automatically sterilizes and produces as JSON data.
 
The following is example for code
 
 
public class EmployeeServiceImpl extends EmployeeServiceBaseImpl {   
            public  com.meera.db.model.Employee getEmployee(
                                    long emplyeeId)
                                    throwscom.liferay.portal.kernel.exception.PortalException,
                                                com.liferay.portal.kernel.exception.SystemException {
                                    returnEmployeeLocalServiceUtil.getEmployee(emplyeeId);
                        }
}
 
 
Once we completed writing custom method in XXXServiceImpl.java
Then we need to run service builder using ant build-service command or from eclipse ant view you can run same command
 
Deploy the portlet into server
 
Now finally deploy the portlet into server by using ant deploy command or from ant view you can use same command. Now we are ready with Plugin Portlet JSON web services
 
Note:
 
For each modification in XXXServiceImpl.java or in service layer we have to run ant build-service command  later we have to deploy the portlet usingant deploy then only change will be applied to the services.
 
Access Plugin Portlet JSON Web Services
 
Create JSON web service is pretty easy we already know. Now we need to access plugin portlet web services.
 
We can accedes Plugin portlet JOSN Web Services in two ways
 
UsingPortal Context (Liferay Plugin Portlet JSON Web Services Part-II)
 
UsingPlugin Portlet Context (Liferay Plugin Portlet JSON Web Services Part-III)
 
Note:
 
Click the above hyper links to continue the tutorial.
 
Download LiferayJSONWebservices portlet from following location
 
You can find source and war file
 
 
Note:
 
Portlet developed in Liferay 6.2CE version
 
Procedure for deploy portlet:
 
You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.
 
Once portlet is deployed successfully insert data in the following table as shown in screens
webservices_employee
 
 
 
 
Now test web service URLs
 
The following is screen show access web service URL in browser
 
 
 
 
Author

Liferay Portal SSL Configuration

Technical Blogs February 6, 2014 By Meera Prince

Objective:
 
Configure SSL (Secure Socket Layer) for Liferay portal.
 
What is SSL?
 
SSL is secured socket layer which secure our application data in the network  means it will protect application data while are exchanging data from web browsers to web servers.SSL is mechanism to protect application data when it travel in the network.SSL use the https protocol in the network
 
We have two protocols
 
 
HTTP, HTTPS
 
HTTP is simple protocol we use in web applications to communicate client and server.
 
HTTPS is same like http but this protocol will work in the secure socket layer so that application data can be protected while data travel in the network.
 
When we send any request using https protocol it need SSL help to protect data.
 
 
How SSL is working?
 
SSL use the https protocol to communicate client with server with secured layer and to make it work we need SSL certificates
.
What is SSL certificate?
 
SSL certificate is like information which contain the public key, private key and data Encryption algorithm information.
 
This information will used by server to encrypt data and decrypt data when the client and server communication is occurred. Similarly Clint also uses same information to encrypt and decrypt the request and response data.
 
This public and private key information shared by Client and Server when Server and Clint are in the communication.
 
SSL Working Mechanism
 
  • We already know SSL uses the Https protocol in the client server communication.
  • When it is https protocol communication then application data will travel in secure layer in the network.
  • When client send the request to server before request travel in network then request data will be encrypted by using SSL certificate information. This certificate provides the encryption algorithm and public key and private to encrypt the data.
  • Once data is encrypted then application data will be travel in secure layer because its https request.
  • As soon as request reached by server then server will take the request and it will decrypt the data by using same encryption algorithm, public and private key.
  • This information will be available in SSL certificate so that server can get this information and able to decrypt. We already know client and server will use same certificate information and the certificate will be shared by the server and client.
  • Once request is decrypted then server processes the request and it will prepare the response. Now server is responsible to encrypt response by using SSL certificate information.
  • Once the data is encrypted it will send to client and it will use secure layer while travel in the network.
  • As soon as response reached by client then it can decrypt the data by using SSL certificate information.
  • This process will apply to each and every request and response while in the communication.

 

Note:
 
Here we need to communicate server and client using HTTPS protocol then only server and client can understand the communication secure type andhttps protocol use 443 port by default.
 
How to get the certificates?
 
 We need get SSL certificates from SSL certificate vendors in the market. We need to purchase certificate and we need to use for our application. In production environment we have to use trusted certificates from reputed vendors. Verisign is one of SSL certificate vendor.
 
How can I implement SSL in local environment?
 
We will use self signed certificate in local development environment.
 
How to create Self-Signed SSL Certificates in Local Development Environment?
 
We will use Java Key Tool or Open SSL tool to create certificates in Local environment.
Java Key Tool by default will come with JDK so that we need install JAVA in our machine to create Self-Signed Certificates.
 
How to Configure SSL in Server?
 
We need to add SSL certificate to server JRE so that server can use these certificates. After add the certificate to server JRE we need to configure certificate information in server configuration files and we need to enable https protocol to server.
 
Note:
 
SSL configuration is varying from server to server based on server vendor.  And server will always look for certificate information JRE/lib/securityfolder this is default location for certificates. Server will search certificates information from cacerts file this file available in jre\lib\security of any JDK.
 
SSL configuration for Liferay Portal
 
The following are the steps to configure SSL in Liferay Portal.
 
  1. Create SSL certificate using Java Key Tool
  2. Configure SSL in Liferay Portal Server

 

Create SSL certificate using Java Key Tool
 
The following are the steps to create certificate using Java Key Tool
 
  • Generate Key
  • Export Key Information into Certificate
  • Import certificate into Server JRE

Java Key Tool is default tool which comes with JAVA. Before use these we need to install java. Once install java then we can use Java Key Tool. WE use Java Key Tool from Command Prompt to create certificate.
 
Open command prompt and go to java installation bin path because there java key tool available.
 
The following screen shows the example java bin path
 
 
Note:
 
If you set java path in your system then you can access java key tool from any directory. Otherwise we need to point to java bin path from command prompt.
 
Generate Key
 
For generating key we need use following command and we need to pass some input values
The following are input options:
 
 
-alias:    this is just reference name to key
 
-keyalg:  which specify the encryption algorithm and the algorithm will use when data will encrypt like RSA.
 
-keypass:  password for key and default we will use changeit
 
 
Enter following command in command prompt
 
 
keytool -genkey -alias tomcatserver -keypass changeit -keyalg RSA
 
 
Once enter this command it will ask some information please provide accordingly and please make sure first name and last name should be name of your host (localhost) or domain name. We should not provide IP Address.
 
The following is information will ask by tool once we enter above command
 
 
Enter keystore password: changeit
What is your first and last name?
  [Unknown]:  localhost
What is the name of your organizational unit?
  [Unknown]:  ASW
What is the name of your organization?
  [Unknown]:  ASW
What is the name of your City or Locality?
  [Unknown]:  HK
What is the name of your State or Province?
  [Unknown]:  HK
What is the two-letter country code for this unit?
  [Unknown]:  HK
Is CN=localhost, OU=ASW, O=ASW, L=HK, ST=HK, C=HK correct?
  [no]:  yes
 
 
Now key was generated and it was Stored in the default key store file that is called .keystore file
 
The default keystore (.keystore) file available in C:\Users\<username>directory of your computer
 
The following is example to .keystore in my computer
 
 
 
Note:
 
If we want store generated key in our own keystore file then use following command
 
 
keytool -genkey -keystore c:\users\localhost.keystore -alias tomcatmeera -keyalg RSA
 
Provide –keystore value this is path to our keystore file
 
 
 
Export Key Information into Certificate
 
We already generated key and that key information stored in .keystore file. Now we need export this key into some certificate and name of certificate is our choice and the extension should be .cert
 
Example for name of certificate myserver.cert
 
Enter following command that will export key into given certificate file
 
 
keytool -export -alias tomcatserver -keypass changeit -file myserver.cert
 
 
Note:
 
The above command will search the key information in .keystore file in default location i.e. C:\Users\<username>
 
We need to give exact alias name that is we previously used when we generate key in previous step
 
If the key stored in our own keystore file then we need to provide keystorefile path with following command
 
 
keytool -export -alias tomcatmeera -keypass changeit -file
myserver.cert  –keystore c:/users/localhost.keystore
 

 
 
Import certificate into Server JRE
 
Now we need to import certificate into server JRE Because Server will always search certificate information in JRE which used by server.
 
Generally all certificates available in jdk1.6.0_43\jre\lib\security location and server will always search the certificates from this location.
 
We will import all certificates in cacerts file this default file to server. Now we need to import our created certificate into cacerts (jdk1.6.0_43\jre\lib\security\cacerts)
 
Use following command to import certificate into cacerts
 
 
keytool -import -alias tomcatserver -file
"C:\Users\E5410\myserver.cert" -keypass changeit -keystore "C:\Program Files\Jav
a\jdk1.6.0_43\jre\lib\security\cacerts"
 
 
As soon as you enter above command it will ask password and enter password then it will show certificate information then you need enter yesthen certificate will be imported into JRE default certificate file location (jre\lib\security\cacerts).
 
The following is information after enter above command
 
 
Enter keystore password:changeit
Owner: CN=meera, OU=meera, O=meera, L=meera, ST=meera, C=meera
Issuer: CN=meera, OU=meera, O=meera, L=meera, ST=meera, C=meera
Serial number: 52e7aad6
Valid from: Tue Jan 28 21:04:22 CST 2014 until: Mon Apr 28 21:04:22 CST 2014
Certificate fingerprints:
         MD5:  02:FC:FA:21:68:D1:26:57:07:3B:DB:B0:A2:1C:9A:5E
         SHA1: D8:52:61:D6:A3:33:97:1E:F9:2F:8C:56:38:26:0D:6C:59:CC:5E:AC
         Signature algorithm name: SHA1withRSA
         Version: 3
Trust this certificate? [no]:  yes
Certificate was added to keystore
 
 
Note:
 
We need to give full qualified path information of JRE default certificate location and our created certificate path and paths are enclosed in quote so that we never see any errors.
 
Alias name we used in all steps because it is reference name to identify the certificate.
 
The following is complete screen to create Self Signed Certificate and which use the Default Keystore file (C:\Users\<username\.keystore)
 
 
 
Note:
 
Key pass every where changeit
 
Please concentrate on red colored rectangle areas in above screen.
 
The following is complete screen to create Self Signed Certificate and which use the Our Own Keystore file
 
 
 
Note:
 
Key pass everywhere is changeit
 
Please concentrate on red colored rectangle areas in above screen.
 
Configure SSL in Liferay Portal Server
 
Now we ready with certificate and we need to configure SSL in server. We already know SSL configuration will change server to server.
 
Now we need to configure SSL to Liferay Portal Server. We are very familiar with following Liferay Portal Servers
 
  1. Liferay Portal Tomcat Server
  2. Liferay Portal JBoss Server

 

Liferay Portal Tomcat Server
 
To configure SSL in tomcat server we will use server.xml file and we wil add connector tag with some SSL related attributes.
 
Go to Liferay Portal Tomcat Server configuration directory and openserver.xml file in any editor.
 
The following is server.xml location in server
 
 
tomcat-7.0.40/conf/ server.xml
 
 
Add following connector xml tag in server.xml
 
The following configuration will always look for certificate information from JRE default certificate location or .keystore in default system user location
 
<!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
 maxThreads="200" scheme="https" secure="true"
  clientAuth="false" sslProtocol="TLS" />
 
 
The following configuration explicitly specify the keystore file location
 
<Connector protocol="HTTP/1.1"
 port="7443" maxThreads="200"
 scheme="https" secure="true" SSLEnabled="true"
 keystoreFile="C:/Users/localhost.keystore" keystorePass="changeit"
clientAuth="false" sslProtocol="TLS"/>
 
 
Note:
 
keystorePass this is password we provided at the time of certificate creation.
 
Connector tag has more additional attributes which will give some addition support and in the configuration we just use some basic required attributes to connector.
 
SSL configuration Connector tag already defined in server.xml file but it’s in comment mode. We just uncomment that SSL configured connector tag and modify accordingly instead of adding new connector tag.
 
Generally in development environment we will configure server to eclipse. When we configure server to eclipse it will create separate sever instance and server instance have its own configuration files.
 
Whenever we did SSL configuration in the original server.xml (tomcat7.0.40/conf/server.xml) file. These configurations not update in the existed eclipse local server configuration files.
So we should remove old server in eclipse again add new local server to eclipse so that new server instance have SSL configuration.
 
The following is screen shows local server in eclipse
 
 
 
Go through following link to get more information about SSL configuration
 
 
Liferay Portal Jboss Server
 
In Jboss also we will use server configuration file to configure SSL. Jboss will use standalone.xml file to configure SSL.
 
The following is location of standalone.xml file
 
 
jboss-7.1.1\standalone\configuration\ standalone.xml
 
 
Now open standalone.xml file and look for following tag this is for http connector tag
.
 
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
 
 
Add following SSL configuration below the above tag as follows and this is for https connector tag.
 
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
   <ssl/>
 </connector>
 
When configure above configuration then server enables with https protocol and it will use SSL.
 
<Connector/> tag has many additional attributes so that it will give more support to SSL. We just use basic configuration.
 
Same like tomcat server Jboss also look for certificates information in JRE default certificate location i.e. jre\lib\security\cacerts
 
The following is more information about SSL configuration Jboss server
 
 
Note:
 
Very important thing is we need to add certificates to server using JRE.
 
Same like tomcat when we use jboss in eclipse please update eclipse server once we completed SSL configuration in original server configuration files i.e. standalone.xml (jboss-7.1.1\standalone\configuration\standalone.xml)
 
When we update server in eclipse then it will get SSL support for eclipse server instance
 
Access Application in Secure Layer
 
To access application in secured network we need to use https and application will use default 443 port when it uses the https protocol.
 
The following is URL to access Liferay Portal Application with https in secured way.
 
 
Note:
 
When we use self signed certificates to access our application in browsers then browser will prompt some message like certificate in not trusted. Simple accept and follow further steps which showed by browser.
 
The following is the screen to show Liferay Portal in Chrome when we use Self-signed certificates.
 
Simple click on Proceed button so that you can view Liferay Portal in browser.
 
 
The following is screen to show Accessing Liferay Portal using SSL
 
 
Important Pints
 
  • SSL use the https protocol to provide secure layer for application data while in the network.
  • We need to add trusted certificates information in server JRE so that data will be encrypted or decrypted when the client server communication is occurred.
  • In the real environment or production environment we need to get SSL certificate from SSL vendors.
  • In the development environment we will use Self Signed Certificates and which can be created by using Java Key Tool
  • We need to add self signed SSL certificates to Server JRE default SSL certificates location i.e jre\lib\security\cacerts
  • To configure SSL information in server we will use server configuration files these file name varying from server to server.
  • To enable SSL is we need to enable HTTPS connector and there we need pass SSL certificate information as attributes values.

 

Author

Liferay Client Side Inter Portlet Communication Using Ajax

Technical Blogs January 20, 2014 By Meera Prince

Liferay Client Side Inter Portlet Communication Using Ajax

 
Objective:
 
Achieve inter portlet communication from client side using Ajax and Liferay Java Script.
 
Introduction:
 
Inter portlet communication is way of exchange the data between portlets in the page or portlets which reside in the other pages.
 
In liferay we have different ways we can achieve this one of the way is client side inter portlet communication.
 
Environment:
 
Liferay 6.2 +Tomcat 7.x+MySQL 5.1
 
Note:
 
The code will work for portal 6.2 version you can try for 6.1 too.
 
Download Client Side IPC portlet from following location
 
You can find source and war file
 
 
Portlet Screen:
 
 
 
Procedure for deploy portlet:
 
You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.
 
Once portlet is deployed successfully you can see the portlet in sample category names as Sender Portlet and Receiver Portlet.
 
Usage Of Portlets:
 
Drag and Drop two portlet in same page and enter email address in sender portlet then click on send button as soon as you click you can see user details in receiver portlet.
 
Client Side Inter Portlet Communication (IPC):
 
Client Side Inter Portlet Communication is one of the ways in IPC   this can apply the portlet which reside in same page. Because Client side IPC will uses java script to communicate that’s why all portlet which participated in IPC need to be in same page.
 
Liferay already have some java script library to implement client side IPC in portlet 
development.
 
The following diagram show you the IPC among Portlets
 
 
Here we have two types of portlets
 
Sender Portlet
Receiver Portlet
 
Go through following link for full source of tutorial
 

http://www.liferaysavvy.com/2014/01/liferay-client-side-inter-portlet.html

All About Liferay Technology

General Blogs January 13, 2014 By Meera Prince

Liferay Savvy By Meera Prince

Hi I am Meera Prince i am very passion about explore in liferay portal and java technolgies.The followings is content of my website its all about liferay technology. i am very happy to share my knowldge to all people who are interested in liferay portal.

 

# Title Author
1 Introduction to Liferay Portal Meera Prince
2 Liferay Service Builder Many to Many Relation in Plugin Portlet Part-III Meera Prince
3 Liferay Service Builder Many to Many Relation in Plugin Portlet Part-II Meera Prince
4 Liferay Service Builder Many to Many Relation in Plugin Portlet Part-I Meera Prince
5 Content Auto Update in Liferay Plugin Portlet Meera Prince
6 Content Auto Update Using AUI Ajax in Liferay Plugin Portlet Meera Prince
7 Content Auto Update Using jQuery Ajax in Liferay Plugin Portlet Meera Prince
8 Store and Retrieve Images Using BLOB Data Type in Plgin Portlet Meera Prince
9 Form Validation in Liferay Meera Prince
10 AUI Form Validator in Liferay Plugin Portlet Meera Prince
11 Liferay Form Validator Meera Prince
12 Liferay Android SDK for Mobile Application Development Meera Prince
13 Simple Way to Use Forms in Liferay Web Content Meera Prince
14 Using BLOB Data Type in Liferay Service Builder Meera Prince
15 Liferay AUI Validator Meera Prince
16 Liferay Captcha Plugin Portlet Meera Prince
17 Liferay Spring Portlet Meera Prince
18 Liferay CAS Integration Part-1 Meera Prince
19 Liferay Environment Challenges and Solutions with Eclipse Meera Prince
20 Liferay Portal Development Introduction Meera Prince
21 Liferay 6.2 Portal Development Setup Meera Prince
22 Liferay 6.2 Portal Installation Meera Prince
23 Sharing Liferay Service Layer between two plugin portlet contexts Meera Prince
24 Access Liferay Database Services in Themes/Velocity Templates Meera Prince
25 Liferay Tables Meta Data Meera Prince
26 Open Liferay Portlet in AUI Dialog/PopUp Meera Prince
27 Liferay Document Viewer Plugin Portlet Meera Prince
28 Export Journal Content as PDF in Liferay Meera Prince
29 Liferay Document Conversion Portlet Meera Prince
30 Send Mails in Liferay Plugin Portlet Meera Prince
31 Lifeay Message Bus Portlet/Handling bulk operations in Liferay Meera Prince
32 Liferay Custom JSON Web Services on Multiple Tables. Meera Prince
33 Google Embedded Document Viewer in Liferay Portlet... Meera Prince
34 Working with Liferay URLs Meera Prince
35 Working with Liferay Alloy UI Dialogs Meera Prince
36 Using Yahoo Query Language in Liferay(YQL) Meera Prince
37 Liferay Portlet Displaying AUI Date Time Meera Prince
38 Liferay PDF generation from HTML using flying saucer Meera Prince
39 Liferay DWR JSON Web services portlet Meera Prince
40 Liferay DWR portlet Meera Prince
41 Liferay Plugin portlet connecting to multiple data... Meera Prince
42 Liferay search container with curd operations. Meera Prince
43 Connection pooling in multithreaded applications Meera Prince
44 Liferay Important Code Snippets Meera Prince
45 Struts2+Liferay Service Builder +JqGrid Liferay ... Meera Prince
46 Spring3+Struts2+Hibernate4+Liferay portlet Meera Prince
47 Best way to add data to life ray tables. Meera Prince
48 Liferay Permission System Detailed Concept Meera Prince
49 Liferay LDAP integration Meera Prince
50 Getting Data from Multiple tables in Liferay Meera Prince
51 How to clone/copy permission system of role to an... Meera Prince
52 Liferay Jersey Restful web services Meera Prince
53 Liferay Android Application Meera Prince
54 Java Client to Consuming Liferay JSON web Services... Meera Prince
55 Expose Liferay Custom JSON web Services in Plug-in... Meera Prince
56 Liferay Jasper Reports Example Meera Prince
57 Liferay6.1GA2 Build Failed Solution Meera Prince
58 Setting Environment variables and System propertie... Meera Prince
59 Liferay CAS Issues and Solutions Meera Prince
60 Plugin portlet Custom JSON Services Meera Prince
61 Dynamic JqGrid with JSON Data Meera Prince

 

Introduction to Liferay Portal

Technical Blogs January 13, 2014 By Meera Prince

Introduction to Liferay Portal

 
Liferay is Portlet technology which follows the JSR 168 and JSR 286 complains.
 
Liferay is very good open source for portlet technology have very good working group and community.
 
Portlet technology is similar to servlet technology but portlet is small part of dynamic content in web page.
 
In normal web application when we send request then server serve the response to the client or browser. Here entire page will be served by one response.
 
Coming to portlet technology in one web page there may be many portlets and each portlet have its own request and response.
 
Each portlet can send request and get the response from server then the response belongs to only the portlet which send the request.
 
We can say portlet is small fragment of dynamic content in the page. Page is aggregation of multiple fragments of dynamic content and each dynamic fragment is managed by one portlet in the web page.
 
In one page we can accommodate multiple portlet and each portlet is responsible for generate dynamic content for page. Multiple portlet together generate the dynamic content and all the portlet dynamic content aggregation will be generated as one web page.
 
 
 

Read More.....

 

Liferay Service Builder Many to Many Relation in Plugin Portlet

Technical Blogs January 11, 2014 By Meera Prince

Objective:
 
Implement Many to Many Relation in liferay development using service builder tool.
 
 
 
 
Environment:
 
Liferay 6.2 +Tomcat 7.x+MySQL 5.1
 
Note:
 
The code will work for portal 6.2 version you can try for 6.1 too.
 
Download Liferay Many To Many Portlet from following location
 
You can find source and war file 
 
 
Portlet Screen:
 
 
Procedure for deploy portlet:
 
You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.
 
Once portlet is deployed successfully you can see the portlet in sample category name as Many To Many.
 
How To use Portlet?
 
One portlet successfully deployed then portlet available in sample category.
 
Login as Liferay Admin and add portlet to any page.
 
Add some students in the database using Add Student Screen
 
 
Add some courses in database using Add course screen
 
 
 Map Courses to Student from following screen
 
 
Map Students to course from following screen
 
 
Display students and his/her courses
 

 


Author
Meera Prince

Form Validation in Liferay

Technical Blogs January 7, 2014 By Meera Prince

Objective:
 
Perform form validation in liferay development.
 
Approaches to achieve
 
Liferay form validation we can do in different approaches.
 
The following are the ways
 
  1.  Liferay AUI Validator Tag
  2.  Liferay Form Validator
  3. AUI Form Validator

 

Liferay Validator Tag:
 
Liferay have come with AUI validator JSP tag we can use this JSP tag and we can perform the form validations.
 
The following is complete tutorial about Liferay AUI Validator Tag
 
 
Liferay Form Validator:
 
This is simple AUI java script validator which is written by liferay people to do form validations. This script inherit the base properties from pure AUI form Validator
 
This java script implemented in liferay-form.js file in lifeay
 
The following is complete tutorial about Liferay Form Validator
 
 
AUI Form Validator
 
AUI Form Validator is come from AUI library. This is pure AUI form validator.
Liferay Form Validator extends by AUI Form Validator.
 
The following is tutorial about AUI Form Validator
 
 
Author
Meera Prince
 

Sharing Liferay Service Layer between two plugin portlet contexts

General Blogs December 15, 2013 By Meera Prince

Sharing Liferay Service Layer between two plugin portlet contexts

 
 
Objective:
 
Using one plug-in portlet services in other plug-in portlet.
 
In liferay we develop portlets in plug-in portlet environment. Here some time we may develop group of portlets in single plug-in context or sometimes we develop in multiple plug-in contexts.
 
When we get requirement like we want use one plug-in context liferay services in other plug-in context, we need to follow the some sequence of steps when we share service layer between two different liferay plug-in portlet contexts.
 
Download Sharing service layer Example  portlets from following location
 
You can find source and war file
 
 
Note: 
 
This portlet developed in Liferay6.1GA2 EE you can change source based on your liferay version, please go through my previous articles to know more information about this.
 
Procedure for deploy portlet:
 
You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.
 
First deploy the Child-portlet make sure deployment should be successful.
 
Second deploy Parent-portlet.
 
Drag and Drop Parent portlet which in sample category then you can see the child table row data.
 
Note:
 
Before use this portlet read entire article and then test the portlet
 
 
Frits we need to identify required dependent plug-in context
 
We need to specify the required plug-in context name in liferay-plugin-package.properties file as follows 


 
required-deploymentcontexts=
PluginPortletContextName1,PluginPortletContextName2
 
Example:
 
required-deployment-contexts=Child-portlet
 
 
 
Note: if multiple contexts then speared by comma
 
First deploy the liferay plug-in portlet context which we mention in liferay-plugin-package.properties as a property required-deployment-contexts.
 
Next deploy the second portlet
 
Example:
 
Assume we have two plug-in contexts Parent-portlet and Child-portlet
 
In Parent-portlet I have one entity called Parent and in Child-portlet I have entity called Child.
 
Now I create service builder for both plug-in portlets and run the service builder. Here both are two different plug-in contexts
 
Now we will get two service jar files in each plug-in portlet WEB-INF/lib directory (Parent-portlet.war/WEB-INF/lib/Parent-portlet-service.jar andChildt-portlet.war/WEB-INF/lib/Child-portlet-service.jar).
 
Now we want use Child-portlet services in Parent-portlet for this need to specify the Child-portlet context information in Parent-portlet. This information we need provided by liferay-plugin-package.properties ofParent-portlet as follows
 
 
required-deployment-contexts=Child-portlet
 
 
Once we mention above property then Child-portlet services will be available in Paretn-portlet means we can use ChildLocalServieUtil, ChildSeriveceUtil and ChildUtil classes in Parent-portlet(As we know our entity in child portlet is child)
 
Now simple get child information in parent portlet JSP page as follows
 
 
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@page import="com.meer.db.service.ChildLocalServiceUtil"%>
<portlet:defineObjects />
<h1>This is parent portlet</h1>
<%=ChildLocalServiceUtil.getChild(1)%>
 
 
Now deploy the Child-portlet first
 
Next and finally we have to deploy the Parent-portlet.
 
Note:
 
In the development in Liferay IDE/Eclipse when we use child services it will show compile time errors but don’t worry you can deploy the portlet.
 
If you really don’t want see such compile time errors you can add services jar file in portlet build path.
 
In above example you can add Child-portlet-service.jar file in Parent-portlet build path. Simple right click on Parent-portlet in eclipse and select build path option add Child-portlet-service.jar before do this you need to run service builder for Child-portlet then only Child-portlet-service.jar file available.
 
Observations:
 
When we want share service layer between two plug-in contexts the services jar file should be available in other portlet plug-in context class path i.e.WEB-INF/lib.
 
In above example we are sharing Child-portlet services in Parent-portlet so we need to make available Child-portlet-service.jar file in Parent-portlet/WEB-INF/lib so that we can use Child-portlet service classes.
 
To do above task we need to mention the child context information in parent portlet as I mention above property.
 
After deployment of two portlet if you see the Parent-portlet/WEB-INF/lib(in server deployment directory) you can find the Child-portlet-service.jarfile. Because of this only we able access the child portlet services.
 
The following is Parent-portlet lib after deployment in the server
 
 
 
 
Screens:
 
Child-portlet with service.xml file
 
 
 
 
Parent-portlet and we mentioned child deployment context.
 
 
 
 
The following is Parent-portlet which is accessing Child-portlet services.
 
 
 
 
Author
Meera Prince
www.liferaysavvy.com
Showing 18 results.
Items 20
of 1