Thursday, April 17, 2014

Liferay Spring Data MongoDB Plugin Portlet

Introduction:

MongoDB is NoSQL database and its document database. We have many relational databases and those are very popular already in the market along with those now a day’s NoSQL database are become popular in the market and it’s have more features and more strengths.

MongoDB is one of the NoSQL database and its document based database unlike RDBMS.
We already know java application needs database depended drivers to connect to RDBMS databases and these drivers are implemented based on Java JDBC specifications.

Similarly MongoDB also have different drivers to different platform applications which allow applications communicate with MongoDB.

MongoDB also provided Mongo Java Driver which allows java applications connects to the MongoDB.

Mongo Java Driver is set of classes and interferes used to connect to MongoDB database to store and retrieve the data. This is pure java implementation driver we can use in any java application to communicate with MongoDB database.

We already know spring is very popular frame work in the market and spring also implemented java library to connect with MongoDB using Spring Framework based applications.

Spring Implemented Spring Data MongoDB java library consist set of classes and interfaces to communicate with MongoDB. Spring Data MongoDB used Mongo Java Driver in their implementation.

We already familiar with Spring JDBC template to communicate with RDBMS databases similarly Spring Data MongoDB have MongoDB template to communicate with MongoDB database.

MongoDB template has set of methods which will used to perform CRUD operation over MongoDB database.

Liferay Spring Data MongoDB

In the Liferay we will use Spring Data MongoDB library to communicate with MongoDB in liferay portlet.

We will use Liferay MVC portlet and we load the spring beans in spring context with help of Spring XML configuration.

We will use spring context, spring core and Spring Beans features in Liferay Portlet MVC.

We need Spring Data MongoDB java library, Mongo Java Driver  library and other spring frame work libraries.

Portal 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 Mongo DB Portlet from following location

You can find source and war file


Portlet Screen-1:


Procedure for deploy portlet ans its 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 sample category name as Liferay Mongo DB.

Note:

Before use this portlet please Read entire Article and Use it

Implementation:

  1. Install MongoDB server and Start MongoDB  
  2. Create Spring Configuration file and place in classes’ directory
  3. Configure Mongo Factory Bean  in Spring Configuration file.
  4. Configure Mongo Template  bean in Spring Configuration file.
  5. Create Spring Context and get Mongo Template Object
  6. Perform CRUD operation using Mongo Template
Install MongoDB server and Start MongoDB

Before use MongoDB in liferay we need install MongoDB database server and need to start data base.

The following is article to Install and Start MongoDB database server


Create Spring Configuration file and place in classes’ directory

Now we need spring configuration file to configure beans and it will used to load beans in context when spring context is initialized.

This file needs to be in application class path i.e WEB-INF/classes directory then spring context can use this file.

Create SpringConfig.xml in portlet src directory, after compile it will be places in classes’ directory automatically.

Example:

LiferayMongoDB-portlet/docroot/WEB-INF/src/SpringConfig.xml



The following is XML file with required XSD and its locations

SpringConfig.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.2.xsd">
   
</beans>


Configure Mongo Factory Bean in Spring Configuration file

We need configure Mongo Factory Bean and its need information MongoDB host and its port if required. This will give database connection objects to connect database.

The following is Mongo Factory Bean configuration.


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    <!-- Factory bean that creates the Mongo instance -->
    <bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
        <property name="host" value="localhost" />
    </bean>
   </beans>


Configure Mongo Template bean in Spring Configuration file

Mongo Template is used to perform CRUD operation on database. We will configure bean in spring configuration and it requires Mongo Factory Bean and database name.

We need to refer Mongo Factory Bean in Mongo Template so at the time at time of spring context initialization it will be injected its one of the features of spring i.e. spring dependency injection

The following is Mongo Template configuration


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    <!-- Factory bean that creates the Mongo instance -->
    <bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
        <property name="host" value="localhost" />
    </bean>
    <!-- MongoTemplate for connecting and quering the documents in the database -->
 <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongo" ref="mongo" />
        <constructor-arg name="databaseName" value="test" />
    </bean>
</beans>


Note:

In MongoDB we can give any name for Data base name and if data base exist it will use if not exist it will create automatically. So we need not bother about database name.

Create Spring Context and get Mongo Template Object

Now we have done all bean configuration spring xml file now we will create Spring Context and load all beans in the context using xml file.

When spring context is read then we will get Mongo Template object with help of that we can perform CRUD operation over Mongo DB.

The following is code snippet create spring context and get Mongo Template


ApplicationContext ctx = new GenericXmlApplicationContext("SpringConfig.xml");
MongoTemplate mongoTemplate = (MongoTemplate)ctx.getBean("mongoTemplate");


Note:

We configured all beans in SpringConfig.xml and spring application context will use configuration file to create all beans and it should be available in class path.

Perform CRUD operation using Mongo Template

Once we get Mongo Template then we can perform CRUD operations

The following are CRUD operation available in Mongo Template


public static final String COLLECTION_NAME = "person";
               
mongoTemplate.insert(personObject, COLLECTION_NAME);
         
mongoTemplate.findAll(Person.class, COLLECTION_NAME);
   
mongoTemplate.remove(personObject, COLLECTION_NAME);
   
mongoTemplate.insert(personObject, COLLECTION_NAME);     
   


Note:

We will us Collection Name in MongoDB it refers the Table Name. MongoDB will create the table if not exist automatically it won’t throw any error.

Liferay Spring MongoDB Data Plugin Portlet

Now we have used all above thing in Liferay MVC portlet to communicate with MongoDB server.

The following are important jar file we uses in portlet development


The following is SpringConfig.xml configuration file


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    <!-- Factory bean that creates the Mongo instance -->
    <bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
        <property name="host" value="localhost" />
    </bean>
    <!-- MongoTemplate for connecting and quering the documents in the database -->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongo" ref="mongo" />
        <constructor-arg name="databaseName" value="test" />
    </bean>
</beans>


The following is Liferay Portlet class


import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import org.springframework.data.mongodb.core.MongoTemplate;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
import com.meera.spring.mongodb.mode.Person;
import com.meera.spring.mongodb.service.PersonServiceUtil;
import com.meera.spring.mongodb.util.MongoTemplateUtil;
public class LiferayMongoDBAction extends MVCPortlet {
       public void savePerson(
                     ActionRequest actionRequest, ActionResponse actionResponse)
              throws IOException, PortletException {
              MongoTemplate mongoTemplate=MongoTemplateUtil.getMongoTemplate();
              Person person=new Person();
              person.setName(ParamUtil.getString(actionRequest,"name"));
              PersonServiceUtil.addPerson(person, mongoTemplate);
       }
       public void deletePerson(
                     ActionRequest actionRequest, ActionResponse actionResponse)
              throws IOException, PortletException {
              MongoTemplate mongoTemplate=MongoTemplateUtil.getMongoTemplate();
              Person person=new Person();
              person.setId(ParamUtil.getString(actionRequest,"id"));
              PersonServiceUtil.deletePerson(person, mongoTemplate);
       }

}

 Liferay portlet have used MongoTemplateUtil class it will create Application context and it will give Mongo Template Object and its Singleton pattern class

The following is MongoTemplateUtil.java


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.data.mongodb.core.MongoTemplate;
public class MongoTemplateUtil {
    private static MongoTemplate mongoTemplate;
    private MongoTemplateUtil() {
    }
    public static MongoTemplate getMongoTemplate() {
        if (null == mongoTemplate) {
              ApplicationContext ctx = new GenericXmlApplicationContext("SpringConfig.xml");
              System.out.println("ctx"+ctx);
              mongoTemplate = (MongoTemplate)ctx.getBean("mongoTemplate");
        }
        return mongoTemplate;
    }
}


Liferay portlet have used PersonServiceUtil class which perform CRUB operations on database and Collection/Table is person

The following is PersonServiceUtil.java


import java.util.List;
import java.util.UUID;
import org.springframework.data.mongodb.core.MongoTemplate;
import com.meera.spring.mongodb.mode.Person;
public class PersonServiceUtil{
    public static final String COLLECTION_NAME = "person";
    public static void addPerson(Person person,MongoTemplate mongoTemplate) {
        if (!mongoTemplate.collectionExists(Person.class)) {
            mongoTemplate.createCollection(Person.class);
        }      
        person.setId(UUID.randomUUID().toString());
        mongoTemplate.insert(person, COLLECTION_NAME);
    }
    
    public static List<Person> listPerson(MongoTemplate mongoTemplate) {
        return mongoTemplate.findAll(Person.class, COLLECTION_NAME);
    }
    
    public static void deletePerson(Person person,MongoTemplate mongoTemplate) {
        mongoTemplate.remove(person, COLLECTION_NAME);
    }
    
    public static void updatePerson(Person person,MongoTemplate mongoTemplate) {
        mongoTemplate.insert(person, COLLECTION_NAME);     
    }
}


The following is portlet view.jsp page

<%@page import="com.meera.spring.mongodb.mode.Person"%>
<%@page import="java.util.List"%>
<%@page import="com.meera.spring.mongodb.util.MongoTemplateUtil"%>
<%@page import="org.springframework.data.mongodb.core.MongoTemplate"%>
<%@page import="com.meera.spring.mongodb.service.PersonServiceUtil"%>
<%@ 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 />
<portlet:actionURL  var="savePerson" name="savePerson">
</portlet:actionURL>
<portlet:actionURL  var="updatePerson" name="updatePerson">
</portlet:actionURL>
<portlet:actionURL  var="litsPersons" name="litsPersons">
</portlet:actionURL>

 <form action="<%=savePerson.toString()%>" method="post">
            <label for="name">Person Name</label>
           <input type="text" id="<portlet:namespace/>name" name="<portlet:namespace/>name"/>
            <input type="submit" value="Submit"/>
        </form>
 <%
 MongoTemplate mongoTemplate=MongoTemplateUtil.getMongoTemplate();
 List<Person> persons=PersonServiceUtil.listPerson(mongoTemplate);
 %>
    <table border="1">
    <%for(Person person:persons){
    %>
    <portlet:actionURL  var="deletePerson" name="deletePerson">
    <portlet:param name="id" value="<%=person.getId()%>"/>
   </portlet:actionURL>
  
            <tr>
                 <td style="width:300px;"><%=person.getName() %></td>
                <td><input type="button" value="delete" onclick="window.location='<%=deletePerson.toString()%>'"/></td>
            </tr>
        <%} %>
    </table> 


Author

Popular Posts

Recent Posts

Recent Posts Widget