Monday, November 19, 2012

Servlet, Hibernate, jQuery and Ajax based google like chat

Hi, In this article, my aim is to create an application which uses the concept of Hibernate in Servlet with Ajax support of Jquery.
Below figure can give you the idea of final look and feel of the complete application:
Servlet, Hibernate, jQuery and Ajax based google like chat
Servlet, Hibernate, jQuery and Ajax based google like chat
DataBase:
Here I am using the MySQL Database for saving the messages entered by the users:
Copy below code to create the table in database named “test”.
1DROP TABLE IF EXISTS `test`.`chatmessage`;
2CREATE TABLE  `test`.`chatmessage` (
3`Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
4`Message` varchar(4000) NOT NULL,
5`userName` varchar(100) NOT NULL,
6`MsgTime` varchar(45) NOT NULL,
7`colorSelected` varchar(45) NOT NULL,
8PRIMARY KEY (`Id`)
9) ENGINE=InnoDB AUTO_INCREMENT=400 DEFAULT CHARSET=latin1;
Hibernate:
Now, start with the hibernate part of the code.
Create the POJO (Plain Old Java Object), which mapps the table “chatmessage” to the object in our application.
1package com.G2.pojo;
2
3import java.text.DateFormat;
4import java.text.SimpleDateFormat;
5import java.util.Date;
6
7public class ChatMessage {
8    private String Message;
9    private String userName;
10    private String MsgTime;
11    private Long Id;
12    private String colorSelected;
13
14    public String getColorSelected() {
15        return colorSelected;
16    }
17
18    public void setColorSelected(String colorSelected) {
19        this.colorSelected = colorSelected;
20    }
21
22    public String getMessage() {
23        return Message;
24    }
25
26    public void setMessage(String message) {
27        Message = message;
28    }
29
30    public String getUserName() {
31        return userName;
32    }
33
34    public void setUserName(String userName) {
35        this.userName = userName;
36    }
37
38    public Long getId() {
39        return Id;
40    }
41
42    public void setId(Long id) {
43        Id = id;
44    }
45
46    public String getMsgTime() {
47        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
48        Date date = new Date();
49        return dateFormat.format(date);
50    }
51
52    public void setMsgTime(String msgTime) {
53        MsgTime = msgTime;
54    }
55}
After creating the POJO class, create the hibernate configuration file, from which the application will come to know that how to map the table’s column from database to the class members, database name and so on. The hibernate configuration file name must be “hibernate.cfg.xml” and it should reside at the root of source code.
Code of hibernate.cfg.xml:
1<?xml version='1.0' encoding='utf-8'?>
2<!DOCTYPE hibernate-configuration PUBLIC
3"-//Hibernate/Hibernate Configuration DTD//EN"
5
6<hibernate-configuration>
7<session-factory name="java:hibernate/SessionFactory">
8      <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver</property>
9      <property name="hibernate.connection.url"> jdbc:mysql://localhost/test</property>
10      <property name="hibernate.connection.username"> username</property>
11      <property name="hibernate.connection.password"> pwd</property>
12      <property name="hibernate.connection.pool_size"> 10</property>
13      <property name="show_sql"> true</property>
14      <property name="dialect"> org.hibernate.dialect.MySQLDialect</property>
15      <property name="hibernate.hbm2ddl.auto"> update</property>
16      <!-- Mapping files -->
17      <mapping resource="ChatMessage.hbm.xml"/>
18</session-factory>
19</hibernate-configuration>
To keep the code simple, normally I add different configurations for different classes in hibernate.
What is the need of dialect in hibernate:
Databases implement subtle differences in the SQL they use. Things such as data types for example vary across databases Or database specific functionality – selecting the top n rows is different depending on the database. The dialect abstracts this so you don’t have to worry about it. In short the dialect property internally creates the highly optimized query for underlying database.
Here also, as you can see, I have included file ChatMessage.hbm.xml file.
Code of ChatMessage.hbm.xml:
1<?xml version="1.0"?>
2<!DOCTYPE hibernate-mapping PUBLIC
3"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
5
6<hibernate-mapping default-lazy="false">
7    <class name="com.G2.pojo.ChatMessage" table="chatmessage">
8        <id name="id" type="long" column="Id">
9            <generator class="identity" />
10        </id>
11        <property name="Message">
12            <column name="Message" />
13        </property>
14        <property name="userName">
15            <column name="userName" />
16        </property>
17        <property name="MsgTime">
18            <column name="MsgTime" />
19        </property>
20        <property name="colorSelected">
21            <column name="colorSelected" />
22        </property>
23    </class>
24</hibernate-mapping>
UI Part of the application:
For the UI, I have written lots of css classes, this is not possible to write complete code here. Please check the code from download link provided at the bottom of the article.
UI of the chat window is created to give the feel of the Gmail chat application as shown in below image:
Gmail like chat window with emoticons
Gmail like chat window with emoticons
Here, find the javascript code, which is responsible to send the AJAX request to the servlet, and getting back the response code:
1<script type="text/javascript">
2    var uEnteredName = prompt("Please Enter Your Name");
3    $("#chat_Header").html(uEnteredName);
4    $("#msg").focus();
5
6    function openEmot()
7    {
8        var $ele = $("#emoticons");
9        var visibility = $ele.css('display');
10
11        if(visibility == 'none')
12        {
13            $ele.show();
14        }
15        else{
16            $ele.hide();
17        }
18    }
19
20    function smileyCode(iconCode)
21    {
22        var $msgEle = $("#msg");
23        $msgEle.val($msgEle.val() + iconCode);
24        var $ele = $("#emoticons");
25        $ele.hide();
26
27        $msgEle.focus();
28    }
29
30    function saveChats() {
31        var uName = $("#chat_Header").html();
32        if (uName == '') {
33            alert('Please enter your name ');
34            return false;
35        }
36        var msg = $("#msg").val();
37        //var oldMsg = $("#chat-area").html();
38        var colorCode = $('input[name=nameColor]:checked', '#send-message-area')
39                .val();
40
41        $.ajax( {
42                    type : "POST",
43                    data : "uName=" + uName + "&msg=" + msg + "&colorCode="
44                            + colorCode,
45                    url : "Chatprocess.do",
46                    error : function(xhr, ajaxOptions, thrownError) {
47                        alert(xhr.status);
48                        alert(thrownError);
49                    },
50                    success : function(data) {
51                        $("#chat-area").html(data);
52                        $("#ChatAtBigScreen").html(data);
53                        document .getElementById('chat-area').scrollTop = document .getElementById('chat-area').scrollHeight;
54                        document .getElementById('ChatAtBigScreen').scrollTop = document .getElementById('ChatAtBigScreen').scrollHeight;
55                    }
56                });
57        return false;
58    }
59    $('#msg').keyup(function(e) {
60
61        if (e.keyCode == 13) {
62            saveChats();
63            $("#msg").val('');
64        }
65    });
66</script>
Utility class, responsible to save the chat in the database using hibernate:
1package com.G2.Model;
2
3import java.util.ArrayList;
4import java.util.Iterator;
5import java.util.List;
6
7import org.hibernate.Query;
8import org.hibernate.Session;
9import org.hibernate.SessionFactory;
10import org.hibernate.Transaction;
11import org.hibernate.cfg.Configuration;
12
13import com.G2.pojo.ChatMessage;
14
15public class DBManager {
16      // Read Hibernate.cfg.xml
17    static Configuration cf = new Configuration().configure();
18    static SessionFactory factory = cf.buildSessionFactory();
19
20    public static void saveChat(ChatMessage chat) {
21
22        Session session = null;
23        try {
24
25            session = factory.openSession();
26            Transaction tx = session.beginTransaction();
27
28            session.save(chat);
29            tx.commit();
30
31        } catch (Exception e) {
32            e.printStackTrace();
33        } finally {
34            if (session != null) {
35                // I faced problem here, if below line is not written then data automatically gets deleted after insertion
36                session.flush();
37                session.close();
38            }
39        }
40    }
41
42    public static List<ChatMessage> getMessages() {
43        List<ChatMessage> MessageList = new ArrayList<ChatMessage>();
44        Session session = null;
45        try {
46            session = factory.openSession();
47            String SQL_QUERY = "from ChatMessage c";
48            Query query = session.createQuery(SQL_QUERY);
49            Iterator<ChatMessage> it = query.iterate();
50            while (it.hasNext()) {
51                ChatMessage c = it.next();
52                MessageList.add(c);
53            }
54
55        } catch (Exception e) {
56            e.printStackTrace();
57        } finally {
58            session.flush();
59            session.close();
60        }
61
62        return MessageList;
63    }
64}
As shown in above code, to work with hibernate, our application will need to read the configuration file of hibernate by below line of code:
1static Configuration cf = new Configuration().configure();
Now, we will need to create the session object from the SessionFactory class:
1static SessionFactory factory = cf.buildSessionFactory();
2Session session = factory.openSession();
Create the object of transaction :
1Transaction tx = session.beginTransaction();
To save the object in the database use save() method of the transaction.
To get the list of chat messages from the database :
1String SQL_QUERY = "from ChatMessage c";
2Query query = session.createQuery(SQL_QUERY);
3Iterator<ChatMessage> it = query.iterate();
Here object of org.hibernate.Query is created and using method iterate(), it gives all the records from the database as a object. (That is what ORM – Object Relation Mapping)
Servlet Code:
1package com.G2.servlets;
2
3import java.io.IOException;
4import java.io.PrintWriter;
5import java.util.HashMap;
6import java.util.List;
7
8import javax.servlet.ServletException;
9import javax.servlet.http.HttpServlet;
10import javax.servlet.http.HttpServletRequest;
11import javax.servlet.http.HttpServletResponse;
12
13import com.G2.Model.DBManager;
14import com.G2.pojo.ChatMessage;
15
16public class ChatProcess extends HttpServlet {
17
18    @Override
19    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
20            throws ServletException, IOException {
21
22        String uName = req.getParameter("uName");
23        String msg = req.getParameter("msg");
24        String colorCode = req.getParameter("colorCode");
25
26        ChatMessage chat = new ChatMessage();
27        chat.setMessage(msg);
28        chat.setUserName(uName);
29        chat.setColorSelected(colorCode);
30
31        DBManager.saveChat(chat);
32        PrintWriter out = resp.getWriter();
33        List<ChatMessage> msgList = DBManager.getMessages();
34
35        StringBuilder sb = new StringBuilder();
36
37        for (ChatMessage chatMsg : msgList) {
38            sb.append("<span style='background:#"
39                    + chatMsg.getColorSelected() + "'>" + chatMsg.getUserName()
40                    + "</span>" + chatMsg.getMessage() + "<br/><br/>");
41        }
42
43        out.print(replaceEmoticons(sb.toString()));
44    }
45
46    private String replaceEmoticons(String msg) {
47        String imgTag = "<img src=\"../images/smiley/{PH}.gif\">";
48        String placeHolder = "{PH}";
49
50        SmileyCodes smileyCode = new SmileyCodes();
51        HashMap<String, String> codeMap = smileyCode.getSmileyMap();
52
53        for (Object key: codeMap.keySet()) {
54            String val = codeMap.get(key);
55            if(msg.contains(key.toString()))
56            {
57                msg = msg.replace(key.toString(), imgTag.replace(placeHolder,val));
58            }
59        }
60
61        return msg;
62    }
63
64}
This servlet class is called by the ajax code, and from here the message is saved using DBManager class.
Servlet mapping in web.config
1<servlet>
2    <servlet-name>Chatprocess</servlet-name>
3    <servlet-class>com.G2.servlets.ChatProcess</servlet-class>
4</servlet>
5
6<servlet-mapping>
7    <servlet-name>Chatprocess</servlet-name>
8    <url-pattern>/Pages/Chatprocess.do</url-pattern>
9</servlet-mapping>
Emoticon /Smiley part – XML Module:
As you can see in the servlet code,
1SmileyCodes smileyCode = new SmileyCodes();
SmileyCodes class is responsible to render the symbol as a smiley. For the performance purpose, the smiley code is saved in xml file with corresponding image file name. Below class reads the xml and creates the HashMap (Only once).
1package com.G2.servlets;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.util.HashMap;
6
7import javax.xml.parsers.DocumentBuilder;
8import javax.xml.parsers.DocumentBuilderFactory;
9import javax.xml.parsers.ParserConfigurationException;
10
11import org.w3c.dom.Document;
12import org.w3c.dom.Element;
13import org.w3c.dom.Node;
14import org.w3c.dom.NodeList;
15import org.xml.sax.SAXException;
16
17public class SmileyCodes {
18
19    private static HashMap<String, String> smileyCodes = null;
20
21    public static void main(String args[]) {
22        new SmileyCodes().replaceCodeBySmiley();
23    }
24
25    public HashMap<String, String> getSmileyMap() {
26        if (smileyCodes == null) {
27            replaceCodeBySmiley();
28        }
29        return smileyCodes;
30
31    }
32
33    private void replaceCodeBySmiley() {
34
35        try {
36
37            if (smileyCodes == null) {
38                SmileyCodes testMain = new SmileyCodes();
39                InputStream st = testMain.getClass().getResourceAsStream("/SmileyCode.xml");
40                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
41                DocumentBuilder builder;
42
43                smileyCodes = new HashMap<String, String>();
44                builder = factory.newDocumentBuilder();
45                Document doc = builder.parse(st);
46
47                // Get Root Node and its child
48                Node root = doc.getDocumentElement();
49                NodeList childNodes = root.getChildNodes();
50
51                for (int i = 0; i < childNodes.getLength(); i++) {
52                    replaceCodeBySmiley(childNodes.item(i));
53                }
54            }
55
56        } catch (ParserConfigurationException e) {
57            e.printStackTrace();
58        } catch (SAXException e) {
59            e.printStackTrace();
60        } catch (IOException e) {
61            e.printStackTrace();
62        }
63
64    }
65
66    private void replaceCodeBySmiley(Node node) {
67
68        if (node.getNodeType() == Node.ELEMENT_NODE) {
69            Element e = (Element) node;
70            String[] keyVal = e.getTextContent().trim().split("#");
71            smileyCodes.put(keyVal[0].trim(), keyVal[1].trim());
72        }
73    }
74
75    private String nodeType(short type) {
76        switch (type) {
77        case Node.ELEMENT_NODE:
78            return "Element";
79        case Node.DOCUMENT_TYPE_NODE:
80            return "Document type";
81        case Node.ENTITY_NODE:
82            return "Entity";
83        case Node.ENTITY_REFERENCE_NODE:
84            return "Entity reference";
85        case Node.NOTATION_NODE:
86            return "Notation";
87        case Node.TEXT_NODE:
88            return "Text";
89        case Node.COMMENT_NODE:
90            return "Comment";
91        case Node.CDATA_SECTION_NODE:
92            return "CDATA Section";
93        case Node.ATTRIBUTE_NODE:
94            return "Attribute";
95        case Node.PROCESSING_INSTRUCTION_NODE:
96            return "Attribute";
97        }
98        return "Unidentified";
99    }
100
101}








                                  Download Code


0 comments:

Post a Comment