Tuesday 19 July 2011

Login-Logout Application in JSP/Servlet/Hibernate with Session Handling

I have put together a sample application implementing login/logout functionality using technologies like JSP, Servlets, Hibernate with database as MySQL and development environment as Eclipse Helios.

The database contains a table called logininfo which has the following structure


CREATE TABLE `logininfo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `loginid` varchar(20) NOT NULL,
  `password` varchar(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `loginid_UNIQUE` (`loginid`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1$$


There is a Login data access object that is a bean corresponding to the table in the database. The Login dao is as shown below :-

public class Login {
private long id;
private String loginId;
private String password;

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getLoginId() {
return loginId;
}
public void setLoginId(String loginId) {
this.loginId = loginId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}


The hibernate mapping file Login.hbm.xml for the above class is as shown below


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping auto-import="true" default-lazy="false">
<class name="soft.sms.dao.hibernate.Login" table="logininfo">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment"></generator>
</id>
<property name="loginId" column="loginid" type="java.lang.String"
not-null="true" unique="true" length="20"></property>
<property name="password" column="password" type="java.lang.String"
not-null="true" length="20"></property>
</class>
</hibernate-mapping>


The hibernate configuration file i.e. hibernate.cfg.xml is as follows


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/<name-of-the-database></property>
<property name="connection.username">root</property>
<property name="connection.password">****</property>
<property name="connection.pool_size">10</property>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hbm2ddl.auto">update</property>

<mapping resource="soft/sms/dao/hibernate/Login.hbm.xml"/>
</session-factory>
</hibernate-configuration>


The user login page is login.jsp as shown below. When the user enters username/password it is verified against the database table and subsequently a message is returned from the servlet stating whether the access is granted or denied.



If the user is denied access the message is shown on the same screen as shown below

If the user is granted access he is taken to a home screen where the name of the user is displayed with the current date. First, the username and password are checked and then the user information is stored in the implicit HTTP session object of JSP. This business logic is implemented at the server side in AuthenticationServlet.java as shown below


public class AuthenticationServlet extends HttpServlet {

@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

String username = request.getParameter("username");
String password = request.getParameter("password");
HttpSession httpSession = request.getSession();
SessionFactory factory = new Configuration().configure().buildSessionFactory();
Session session = factory.openSession();
String query = "from Login login where loginId=? and password=?";
Query queryObj = session.createQuery(query);
queryObj.setString(0, username);
queryObj.setString(1, password);
List<Login> records = queryObj.list();
if(records.size()>0){
request.setAttribute("loginstatus", "Login Successful.");
httpSession.setAttribute("username", username);
getServletContext().getRequestDispatcher("/application/home.jsp").forward(request, response);
}else{
request.setAttribute("loginstatus", "Username/Password do not match.");
getServletContext().getRequestDispatcher("/authentication/login.jsp").forward(request, response);
}
}


The home screen as shown below





Logout functionality is there where the session is invalidated and the user is directed to the logout page which is as shown



The entire application code is shared at the following location :
Login Application

Monday 27 June 2011

Internal Working Of HashSet and HashMap

These are the most basic hash based collections that are used in every day programming, so here I will visit both HashSet and HashMap and explain their internal working.  First I will start with HashMap and then continue with HashSet.

HashMap 

HashMap stores its elements in the form of key value pairs but no order is maintained inside the map. Each key value pair in a map corresponds to an Entry object which is static inner class inside a HashMap class. Moreover HashMap is not a thread safe implementation of a Map interface like the Hashtable, also HashMap can store one null key and multiple null values unlike the Hashtable.


How the objects are stored inside the HashMap?


HashMap is made up of two collection implementations i.e. Array and LinkedList. 

It stores its key value pairs in the buckets where each bucket corresponds to an index in the array. The array index is calculated by taking into account key's hashcode value and the size of the array. Each hashcode value can fall into the same bucket so these key-value pairs are stored in a LinkedList structure, this is known as collision in hash based collections. To get a value from a hashmap first the hashcode value of the key is computed and then the index position in the array is calculated which is also called bucket and if the bucket contains multiple values, all the values are iterated to find the correct value using the object(key) equals() method. So, proper implementation of hashcode() and equals() is necessary to ensure correct working of hash based collections.


Immutability

Immutable objects act as great building blocks for other objects whether mutable or immutable. So, immutable object make good map keys and set elements as their values will not change once they are in a map or set.





Initial Capacity and Load Factor

Initial Capacity and load factor plays an important part in deciding the performance of the hash based collections. The capacity is the number of buckets and the initial capacity is the capacity that is defined while creating a hashmap. The load factor decides how full the hashmap can get before its capacity is increased. The default capacity and load factor of hashmap are 16 and 0.75 respectively this means initially hashmap will contain 16 buckets and the capacity of the hashmap is doubled when it is 75% filled.

Higher values of load factor will decrease the space overhead but it will eventually increase the look up cost. While lower values of load factor will increase the rehashing operations thereby decreasing the performance. So, a good tradeoff between initial capacity and load factor is necessary to improve the performance of the hashmap by reducing the rehashing operations. Rehashing means to create a new array and map the old elements into the new array by applying the hashing function.


HashSet


HashSet is backed by HashMap instance and it stores unique elements but order in which the elements are stored is not defined, it also allows null element.


The value that is added to the HashSet acts as a key to the backing HashMap with a dummy object as the value to that key which is a static constant so that multiple add operations does not result in multiple instances of object. For example if we add a value to the hashset like
Set<String> collections= new HashSet<String>();
collections.add("HashSet");
then internally it is stored in a map as hashmap.put("HashSet",dummy) where dummy is 
private static final Object dummy = new Object();


When iterating over a HashSet a keyset iterator is returned not the values. Since the elements stored in the HashSet are stored as keys into the HashMap.