Wednesday, 26 February 2014

Externalizable in java

Before understanding Externalizable interface, you need to have idea about Serialization.You can read more about Serialization at Serialization in java.

Java provides mechanism called serialization to persists java objects in a form of ordered or sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object.

Externalizable:

As name suggest it is externalilizing your serialization.If you want to customize your serialization mechanism then you can use it.It uses custom written mechanism to perform marshalling and unmarshalling of objects.Externalizable interface extends Serializable interface. If you implement this interface then you need to override following methods.
    @Override
    public void readExternal(ObjectInput arg0) throws IOException,

            ClassNotFoundException {

    }

    @Override
    public void writeExternal(ObjectOutput arg0) throws IOException {

    }

Now lets see how serialization happens:

At sender side:
JVM checks if class implements externalizable or not.If it does then serialize object using writeExternal() method.If it does not implement externalizable but implements serializable , object is serialized using ObjectOutputStream.

At receiver side:
When object is reconstructed and it is externalizable , an instance is created using no args constructor and readExternal is called.If it is not externalizable but serializable , object is reconstructed using ObjectInputStream.

Lets start with example same as we have used in Serialization in java.
Create Employee.java in src->org.arpit.javapostsforlearning

Employee.java:
package org.arpit.javapostsforlearning;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class Employee implements Externalizable{ 

 int employeeId;
 String employeeName;
 String department;
 String nationality;

 public Employee()
 {

 }
 public int getEmployeeId() {
  return employeeId;
 }
 public void setEmployeeId(int employeeId) {
  this.employeeId = employeeId;
 }
 public String getEmployeeName() {
  return employeeName;
 }
 public void setEmployeeName(String employeeName) {
  this.employeeName = employeeName;
 }
 public String getDepartment() {
  return department;
 }
 public void setDepartment(String department) {
  this.department = department;
 }


 public String getNationality() {
  return nationality;
 }
 public void setNationality(String nationality) {
  this.nationality = nationality;
 }
 @Override
 public void readExternal(ObjectInput in) throws IOException,
 ClassNotFoundException {
  employeeId=in.readInt();
  employeeName=(String) in.readObject();
  
 }
 @Override
 public void writeExternal(ObjectOutput out) throws IOException {

  out.writeInt(employeeId);
  out.writeObject(employeeName);
 }
}
you must have no args contructor if you implement externalizable.
Create ExternalizableMain.java in org.arpit.javapostsforlearning
ExternalizableMain.java:
package org.arpit.javapostsforlearning;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ExternalizableMain {
 /**
  * @author Arpit Mandliya
  */
 public static void main(String[] args) {

  Employee emp = new Employee();
  emp.setEmployeeId(101);
  emp.setEmployeeName("Arpit");
  emp.setDepartment("CS");
  
  //Serialize
  try
  {
   FileOutputStream fileOut = new FileOutputStream("employee.ser");
   ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
   outStream.writeObject(emp);
   outStream.close();
   fileOut.close();
  }catch(IOException i)
  {
   i.printStackTrace();
  }

  //Deserialize
  emp = null;
  try
  {
   FileInputStream fileIn =new FileInputStream("employee.ser");
   ObjectInputStream in = new ObjectInputStream(fileIn);
   emp = (Employee) in.readObject();
   in.close();
   fileIn.close();
  }catch(IOException i)
  {
   i.printStackTrace();
   return;
  }catch(ClassNotFoundException c)
  {
   System.out.println("Employee class not found");
   c.printStackTrace();
   return;
  }
  System.out.println("Deserialized Employee...");
  System.out.println("Emp id: " + emp.getEmployeeId());
  System.out.println("Name: " + emp.getEmployeeName());
 
 }
}

Run it :
When you run ExternalizableMain.java.You will get following output
Deserialized Employee...
Emp id: 101
Name: Arpit

If you already have serializable,why you need externalizable at all!!:

  • When you serialize any object using serializable, apart from fields, all objects that belong to object map and that can be reached using instance variable will also be serialized .for example :
    • If you have Employee class and its superclass is person then it will serialize all superclass objects (such as person) until it reaches "Object" class.
    • Similarly if Employee has instance variable of address class then it will serialize whole object map of address also .
           Do you really want this much overhead when all you want to serialize is employeeId and  employeeName
  • JVM uses reflection when you use serializable which is quite slow.
  • While serializing,information about class description which incluses description of its superclass and instance variable associated with that class also get stored in stream.Again this is also a performance issue

Inheritance in Externalization:

Now we will see how inheritance affects externalization.So there can be muliple cases whether super class is externalizable or not.If not then how will you handle that and how it works.Lets see by example.
We will create Person.java which will be superclass of Employee.

Case 1: What if super class does not implement Externalizable:

If superclass does not implements externalizable , you need to serialize superclass 's fields in subclass that implements Externalizable.

Person.java
package org.arpit.javapostsforlearning;
public class Person {
 
 String name="default";
 String nationality;
 
 public Person()
 {
  System.out.println("Person:Constructor");
 }

 public Person(String name, String nationality) {
  super();
  this.name = name;
  this.nationality = nationality;
 }
 
 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getNationality() {
  return nationality;
 }

 public void setNationality(String nationality) {
  this.nationality = nationality;
 }

}

Create Employee.java in org.arpit.javapostsforlearning
Employee.java:
package org.arpit.javapostsforlearning;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
;

public class Employee extends Person implements Externalizable{ 

 int employeeId;
 String department;
 
 public Employee()
 {
  
 }
 public Employee(int employeeId,String name,String department,String nationality)
 {
  super(name,nationality);
  this.employeeId=employeeId;
  this.department=department;
  System.out.println("Employee:Constructor");
 }
 
 public int getEmployeeId() {
  return employeeId;
 }
 public void setEmployeeId(int employeeId) {
  this.employeeId = employeeId;
 }
 
 public String getDepartment() {
  return department;
 }
 public void setDepartment(String department) {
  this.department = department;
 }



@Override
public void writeExternal(ObjectOutput out) throws IOException {
 
 /*since superclass does not implement externalizable, you need to serialize super class field in this class itself*/
 //superclass fields
 out.writeObject(name);
 out.writeObject(nationality);
 
 // its own fields
 out.writeInt(employeeId);
 out.writeObject(department);
}

@Override
public void readExternal(ObjectInput in) throws IOException,
  ClassNotFoundException {
 /*since superclass does not implement externalizable, you need to deserialize super class field in this class itself*/
 //superclass fields
 name=(String) in.readObject();
 nationality=(String) in.readObject();
 
 // its own fields
 employeeId=in.readInt();
 department=(String) in.readObject();

}
}
Create ExternalizableMain.java in org.arpit.javapostsforlearning
ExternalizableMain.java:
package org.arpit.javapostsforlearning;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ExternalizableMain {

 /**
  * @author Arpit Mandliya
  */
 public static void main(String[] args) {

  //Serialize
  Employee emp = new Employee(101,"Arpit","CS","Indian");
  System.out.println("Before serializing");
  System.out.println("Emp id: " + emp.getEmployeeId());
  System.out.println("Name: " + emp.getName());
  System.out.println("Department: " + emp.getDepartment());
  System.out.println("Nationality: " + emp.getNationality());
  System.out.println("************");
  System.out.println("Serializing");
  try
  {
   FileOutputStream fileOut = new FileOutputStream("employee.ser");
   ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
   outStream.writeObject(emp);
   outStream.close();
   fileOut.close();
  }catch(IOException i)
  {
   i.printStackTrace();
  }

  //Deserialize
  System.out.println("************");
  System.out.println("Deserializing");
  emp = null;
  try
  {
   FileInputStream fileIn =new FileInputStream("employee.ser");
   ObjectInputStream in = new ObjectInputStream(fileIn);
   emp = (Employee) in.readObject();
   in.close();
   fileIn.close();
  }catch(IOException i)
  {
   i.printStackTrace();
   return;
  }catch(ClassNotFoundException c)
  {
   System.out.println("Employee class not found");
   c.printStackTrace();
   return;
  }
  System.out.println("After serializing");
  System.out.println("Emp id: " + emp.getEmployeeId());
  System.out.println("Name: " + emp.getName());
  System.out.println("Department: " + emp.getDepartment());
  System.out.println("Nationality: " + emp.getNationality());
 }
} 
Run it :
When you run ExternalizableMain.java.You will get following output:
Employee:Constructor
Before serializing
Emp id: 101
Name: Arpit
Department: CS
Nationality: Indian
************
Serializing
************
Deserializing
Person:Constructor
After serializing
Emp id: 101
Name: Arpit
Department: CS
Nationality: Indian

Case 2: What if super class implements Externalizable:

If superclass implements externalizable ,then it will also have readExternal() and writeExternal() method so it will serialize its own fields in these methods

Person.java
package org.arpit.javapostsforlearning;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class Person implements Externalizable{

 String name="default";
 String nationality;

 public Person()
 {
  System.out.println("Person:Constructor");
 }

 public Person(String name, String nationality) {
  super();
  this.name = name;
  this.nationality = nationality;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getNationality() {
  return nationality;
 }

 public void setNationality(String nationality) {
  this.nationality = nationality;
 }


 @Override
 public void writeExternal(ObjectOutput out) throws IOException {

  out.writeObject(name);
  out.writeObject(nationality);
 }

 @Override
 public void readExternal(ObjectInput in) throws IOException,
 ClassNotFoundException {
  name=(String) in.readObject();
  nationality=(String) in.readObject();

 }

}

Create Employee.java in org.arpit.javapostsforlearning
Employee.java:
package org.arpit.javapostsforlearning;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
;

public class Employee extends Person implements Externalizable{ 

 int employeeId;
 String department;

 public Employee()
 {

 }
 public Employee(int employeeId,String name,String department,String nationality)
 {
  super(name,nationality);
  this.employeeId=employeeId;
  this.department=department;
  System.out.println("Employee:Constructor");
 }

 public int getEmployeeId() {
  return employeeId;
 }
 public void setEmployeeId(int employeeId) {
  this.employeeId = employeeId;
 }

 public String getDepartment() {
  return department;
 }
 public void setDepartment(String department) {
  this.department = department;
 }



 @Override
 public void writeExternal(ObjectOutput out) throws IOException {

  super.writeExternal(out);
  out.writeInt(employeeId);
  out.writeObject(department);
 }

 @Override
 public void readExternal(ObjectInput in) throws IOException,
 ClassNotFoundException {

  super.readExternal(in);
  employeeId=in.readInt();
  department=(String) in.readObject();

 }
}
Create ExternalizableMain.java in org.arpit.javapostsforlearning
ExternalizableMain.java:
package org.arpit.javapostsforlearning;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ExternalizableMain {

 /**
  * @author Arpit Mandliya
  */
 public static void main(String[] args) {

  //Serialize
  Employee emp = new Employee(101,"Arpit","CS","Indian");
  System.out.println("Before serializing");
  System.out.println("Emp id: " + emp.getEmployeeId());
  System.out.println("Name: " + emp.getName());
  System.out.println("Department: " + emp.getDepartment());
  System.out.println("Nationality: " + emp.getNationality());
  System.out.println("************");
  System.out.println("Serializing");
  try
  {
   FileOutputStream fileOut = new FileOutputStream("employee.ser");
   ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
   outStream.writeObject(emp);
   outStream.close();
   fileOut.close();
  }catch(IOException i)
  {
   i.printStackTrace();
  }

  //Deserialize
  System.out.println("************");
  System.out.println("Deserializing");
  emp = null;
  try
  {
   FileInputStream fileIn =new FileInputStream("employee.ser");
   ObjectInputStream in = new ObjectInputStream(fileIn);
   emp = (Employee) in.readObject();
   in.close();
   fileIn.close();
  }catch(IOException i)
  {
   i.printStackTrace();
   return;
  }catch(ClassNotFoundException c)
  {
   System.out.println("Employee class not found");
   c.printStackTrace();
   return;
  }
  System.out.println("After serializing");
  System.out.println("Emp id: " + emp.getEmployeeId());
  System.out.println("Name: " + emp.getName());
  System.out.println("Department: " + emp.getDepartment());
  System.out.println("Nationality: " + emp.getNationality());
 }
} 

Run it :
When you run ExternalizableMain.java.You will get following output:
Employee:Constructor
Before serializing
Emp id: 101
Name: Arpit
Department: CS
Nationality: Indian
************
Serializing
************
Deserializing
Person:Constructor
After serializing
Emp id: 101
Name: Arpit
Department: CS
Nationality: Indian

In this example, since the Person class stores and restores its fields in its own writeExternal and readExternal methods, you dont need to save/restore the superclass fields in sub class but if you observe closely the writeExternal and readExternal methods of Employee class, you will find that you still need to first call the super.xxxx() methods that confirms the statement the externalizable object must also coordinate with its supertype to save and restore its state.

DownSides of Externalizable:

  • If you make any change to your class definition, you need to maintain writeExternal() and readExternal accordingly.
  • As we have seen in example,Sub class object has to coordinate with its superclass to save and store its state(by call super.xxxx() method from subclass)

Tuesday, 25 February 2014

hash and indexFor method in HashMap

Target Audience

This post is for the people who already have good understanding of how HashMap works in java and want to understand more about hash and indexFor method.

In this post, we will see how hash and indexFor method works internally in hashmap. hash and indexFor methods belong to HashMap class. Why JDK developers need to have another hash function when  key object's have there own hashcode method.
Lets see code for hash and indexFor
/**
 * Applies a supplemental hash function to a given hashCode, which
 * defends against poor quality hash functions.  This is critical
 * because HashMap uses power-of-two length hash tables, that
 * otherwise encounter collisions for hashCodes that do not differ
 * in lower bits. Note: Null keys always map to hash 0, thus index 0.
 */
static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}
 
/**
 * Returns index for hash code h.
 */
static int indexFor(int h, int length) {
    return h & (length-1);
}
As java doc says about hash:
 Applies a supplemental hash function to a given hashCode, which defends against poor quality hash functions. This is critical because HashMap uses power-of-two length hash tables, that otherwise encounter collisions for hashCodes that do not differ in lower bits. Note: Null keys always map to hash 0, thus index 0.

Lets understand this with the help of example: Lets say key object's hashcode() returns only 3 values 31,63 and 95. 31,63 and 95 are integers, so all are 32 bits.
 31=00000000000000000000000000011111
 63=00000000000000000000000000111111
 95=00000000000000000000000001011111
 Now lets say our hashmap's lenth is 16(2^4, Hashmap's length will be always in power of two)

What if we do not use hash function: 

Now if we do not use hash function then 
indexFor will return :
 31=00000000000000000000000000011111 => 1111=15
 63=00000000000000000000000000111111  => 1111=15
 95=00000000000000000000000001011111 => 1111=15

Why so?
because when we call indexFor function.It will do AND between 31&15 , 63&15 and 95&15.
For ex. 95&15
00000000000000000000000001011111 &00000000000000000000000000001111
so (2^n-1) will always have sequence of 1's in it.so what matters here it last n bits as 0&1 is always 0.
In above example, all have 1111 in end that is why they are returning same index.
so although we have different hashcode,each Entry object will be stored at 15 index only.

What if we  use hash function:

If we use hash function then :
On each hashcode, first hash will  be applied.
 31=00000000000000000000000000011111 => 00000000000000000000000000011110
 63=00000000000000000000000000111111  => 00000000000000000000000000111100
 95=00000000000000000000000001011111 => 00000000000000000000000001011010

 now after passing new hash to indexFor.It will return :
00000000000000000000000000011110 =>1110=14
00000000000000000000000000111100 =>1100=12
00000000000000000000000001011010 =>1010=10

After applying hash function, above hashcodes are returning different index so hash function is redistributing elements in hashmap thus less collisions and better performance.
The main purpose of hash operation is to make the hashcode differences visible in the least significant bits so that the hashmap elements can be distributed evenly across the buckets

Note:

  • If two key objects have same hashcode, then they will always go to same index in table array
  • If two key objects do not have same hashcode then they may or may not go to same index in table array.

How HashMap works in java

Most common interview questions are "How HashMap works in java", "How get and put method of HashMap work internally". Here I am trying to explain internal functionality with an easy example. Rather than going through theory, we will start with example first, so that you will get better understanding and then we will see how get and put function work in java.

Lets take a very simple example. I have a Country class, we are going to use Country class object as key and its capital name(string) as value. Below example will help you to understand, how these key value pair will be stored in hashmap.

1. Country.java 
package org.arpit.javapostsforlearning;
public class Country {

 String name;
 long population;
 
 public Country(String name, long population) {
  super();
  this.name = name;
  this.population = population;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public long getPopulation() {
  return population;
 }
 public void setPopulation(long population) {
  this.population = population;
 }
 
 // If length of name in country object is even then return 31(any random number) and if odd then return 95(any random number).
 // This is not a good practice to generate hashcode as below method but I am doing so to give better and easy understanding of hashmap.
 @Override
 public int hashCode() {
  if(this.name.length()%2==0)
   return 31;
  else 
   return 95;
 }
 @Override
 public boolean equals(Object obj) {
  
  Country other = (Country) obj;
   if (name.equalsIgnoreCase((other.name)))
   return true;
  return false;
 }
  
}

If you want to understand more about hashcode and equals method of object, you may refer hashcode() and equals() method in java

2. HashMapStructure.java(main class)

import java.util.HashMap;
import java.util.Iterator;
  
public class HashMapStructure {
  
    /**
     * @author Arpit Mandliya
     */
    public static void main(String[] args) {
          
        Country india=new Country("India",1000);
        Country japan=new Country("Japan",10000);
          
        Country france=new Country("France",2000);
        Country russia=new Country("Russia",20000);
          
        HashMap countryCapitalMap=new HashMap();
        countryCapitalMap.put(india,"Delhi");
        countryCapitalMap.put(japan,"Tokyo");
        countryCapitalMap.put(france,"Paris");
        countryCapitalMap.put(russia,"Moscow");
          
        Iterator countryCapitalIter=countryCapitalMap.keySet().iterator();//put debug point at this line
        while(countryCapitalIter.hasNext())
        {
            Country countryObj=countryCapitalIter.next();
            String capital=countryCapitalMap.get(countryObj);
            System.out.println(countryObj.getName()+"----"+capital);
            }
        }
  
  
} 
Now put debug point at line 23 and right click on project->debug as-> java application. Program will stop execution at line 23 then right click on countryCapitalMap then select watch.You will be able to see structure as below.


Now From above diagram, you can observe following points
  1. There is an Entry[] array called table which has size 16.
  2. This table stores Entry class's object. HashMap class has a inner class called Entry.This Entry have key value as instance variable. Lets see structure of entry class Entry Structure.
  3. static class Entry implements Map.Entry
    {
            final K key;
            V value;
            Entry next;
            final int hash;
            ...//More code goes here
    } 
  4. Whenever we try to put any key value pair in hashmap, Entry class object is instantiated for key value and that object will be stored in above mentioned Entry[](table). Now you must be wondering, where will above created Enrty object get stored(exact position in table). The answer  is, hash code is calculated for a key by calling Hascode() method. This hashcode is used to calculate index for above Entry[] table.
  5. Now, If you see at array index 10 in above diagram, It has an Entry object named HashMap$Entry.
  6. We have put 4 key-values in hashmap but it seems to have only 2!!!!This is because if two objects have same hashcode, they will be stored at same index. Now question arises how? It stores objects in a form of LinkedList(logically).
So how hashcode of above country key-value pairs are calculated. 
Hashcode for Japan = 95 as its length is odd.
Hashcode for India =95 as its length is odd
HashCode for Russia=31 as its length is even.
HashCode for France=31 as its length is even.

Below diagram will explain LinkedList concept clearly.


 So now if you have good understanding of hashmap structure,Lets go through put and get method.

Put :

Lets see implementation of put method:
/**
  * Associates the specified value with the specified key in this map. If the
  * map previously contained a mapping for the key, the old value is
  * replaced.
  *
  * @param key
  *            key with which the specified value is to be associated
  * @param value
  *            value to be associated with the specified key
  * @return the previous value associated with <tt>key</tt>, or <tt>null</tt>
  *         if there was no mapping for <tt>key</tt>. (A <tt>null</tt> return
  *         can also indicate that the map previously associated
  *         <tt>null</tt> with <tt>key</tt>.)
  */
 public V put(K key, V value) {
  if (key == null)
   return putForNullKey(value);
  int hash = hash(key.hashCode());
  int i = indexFor(hash, table.length);
  for (Entry<k , V> e = table[i]; e != null; e = e.next) {
   Object k;
   if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
    V oldValue = e.value;
    e.value = value;
    e.recordAccess(this);
    return oldValue;
   }
  }

  modCount++;
  addEntry(hash, key, value, i);
  return null;
 } 
now lets understand above code step by step
  1. Key object is checked for null. If key is null then it will be stored at table[0] because hashcode for null is always 0.
  2. Key object's hashcode() method is called and hash code is calculated. This hashcode is used to find index of array for storing Entry object. It may happen sometimes that, this hashcode function is poorly written so JDK designer has put another function called hash() which takes above calculated hash value as argument.If you want to learn more about hash() function, you can refer hash and indexFor method in hashmap.
  3. indexFor(hash,table.length)  is used to calculate exact index in table array for storing the Entry object.
  4. As we have seen in our example, if two key objects have same hashcode(which is known as collision) then it will be stored in form of linkedlist.So here, we will iterate through our linkedlist.
  • If there is no element present at that index which we have just calculated then it will directly put our Entry object at that index.
  • If There is element present at that index then it will iterate until it gets Entry->next as null.Then current Entry object become next node in that linkedlist
  • What if we are putting same key again, logically it should replace old value. Yes,it will do that.While iterating it will check key equality by calling equals() method(key.equals(k)), if this method returns true then it replaces value object with current Entry's value object.

 Get:

 Lets see implementation of get now:
/**
  * Returns the value to which the specified key is mapped, or {@code null}
  * if this map contains no mapping for the key.
  *
  * <p>
  * More formally, if this map contains a mapping from a key {@code k} to a
  * value {@code v} such that {@code (key==null ? k==null :
  * key.equals(k))}, then this method returns {@code v}; otherwise it returns
  * {@code null}. (There can be at most one such mapping.)
  *
  * </p><p>
  * A return value of {@code null} does not <i>necessarily</i> indicate that
  * the map contains no mapping for the key; it's also possible that the map
  * explicitly maps the key to {@code null}. The {@link #containsKey
  * containsKey} operation may be used to distinguish these two cases.
  *
  * @see #put(Object, Object)
  */
 public V get(Object key) {
  if (key == null)
   return getForNullKey();
  int hash = hash(key.hashCode());
  for (Entry<k , V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
   Object k;
   if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
    return e.value;
  }
  return null;
 } 
As you got the understanding on put functionality of hashmap. So to understand get functionality is quite simple. If you pass any key to get value object from hashmap.
  1. Key object is checked for null. If key is null then value of Object resides at table[0] will be returned.
  2. Key object's hashcode() method is called and hash code is calculated.
  3. indexFor(hash,table.length)  is used to calculate exact index in table array using generated hashcode for getting the Entry object.
  4. After getting index in table array, it will iterate through linkedlist and check for key equality by calling equals() method and if it returns true then it returns the value of Entry object else returns null.

Key points to Remeber:

  • HashMap has a inner class called Entry which stores key-value pairs.
  • Above Entry object is stored in Entry[ ](Array) called table
  • An index of table is logically known as bucket and it stores first element of linkedlist
  • Key object's hashcode() is used to find bucket of that Entry object.
  • If two key object 's have same hashcode , they will go in same bucket of table array.
  • Key object 's equals() method is used to ensure uniqueness of key object.
  • Value object  's equals() and hashcode() method is not used at all

Monday, 24 February 2014

hashcode() and equals() method in java

In this post ,we will try to understand hashcode() and equals() method in java.
These methods can be found in the Object class and hence available to all java classes.Using these two methods, an object can be stored or retrieved from a Hashtable, HashMap or HashSet.
  • hashcode()
  • equals()

Usage of hashcode() and equals()

hashcode():
This method is used to get unique integer for given object. This integer is used to find bucket when storing in hashmap or hashset.By default, This method returns integer represention of memory address where object is stored.

equals():
This method is used to simply check the equality between two objects. By default, it checks where two reference refer to same object or not(==).

Lets override default implemenation of hashcode() and equals():

If you don't override these method, everything will work fine but sometimes there is a need to override these method e.g. you want to define equality between two employee object as true if Both have same employee id.

Lets see with the help of example.We have a class called Country
1. Country.java
package org.arpit.javapostsforlearning;

public class Country {

    String name;
    long population;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public long getPopulation() {
        return population;
    }
    public void setPopulation(long population) {
        this.population = population;
    }
    
}

This country class have two basic attributes- name and population.
Now create a class called "EqualityCheckMain.java"

package org.arpit.javapostsforlearning;

public class EqualityCheckMain {

    /**
     * @author arpit mandliya
     */
    public static void main(String[] args) {
        
        Country india1=new Country();
        india1.setName("India");
        Country india2=new Country();
        india2.setName("India");
        System.out.println("Is india1 is equal to india2:" +india1.equals(india2));
    }

}
When you run above program, you will get following output
Is india1 is equal to india2:false
In above program, we have created two different objects and set their name attribute to "india".
Because both references india1 and india2 are pointing to different object, as default implementation of equals check for ==,equals method is returning false. In real life, it should have return true because no two countries can have same name.

Now lets override equals and return true if two country's name are same.

Add this method to above country class:

@Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Country other = (Country) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

and now run EqualityCheckMain.java again
You will get following output:
Is india1 is equal to india2:true

Now this is because overriden equals method return true if two country have same name.
One thing to remember here, signature of equals method should be same as above.

Lets put this Country objects in hashmap:

Here we are going to use Country class object as key and its capital name(string) as value in HashMap.

package org.arpit.javapostsforlearning;

import java.util.HashMap;
import java.util.Iterator;

public class HashMapEqualityCheckMain {

    /**
     * @author Arpit Mandliya
     */
    public static void main(String[] args) {
        HashMap<Country,String> countryCapitalMap=new HashMap<Country,String>(); 
        Country india1=new Country();
        india1.setName("India");
        Country india2=new Country();
        india2.setName("India");

        countryCapitalMap.put(india1, "Delhi");
        countryCapitalMap.put(india2, "Delhi");

        Iterator<Country> countryCapitalIter=countryCapitalMap.keySet().iterator();
        while(countryCapitalIter.hasNext())
        {
            Country countryObj=countryCapitalIter.next();
            String capital=countryCapitalMap.get(countryObj);
            System.out.println("Capital of "+ countryObj.getName()+"----"+capital);

        }
    } 
}

When you run above program, you will see following output:
Capital of India----Delhi
Capital of India----Delhi

Now you must be wondering even through two objects are equal why HashMap contains two key value pair instead of one.This is because First HashMap uses hashcode to find bucket for that key object, if hashcodes are same then only it checks for equals method and because hashcode for above two country objects uses default hashcode method,Both will have different memory address hence different hashcode.

Now lets override hashcode method.Add following method to Country class

@Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

Now run HashMapEqualityCheckMain.java again
You will see following output:
Capital of India----Delhi

So now hashcode for above two objects india1 and india2 are same, so Both will be point to same bucket,now equals method will be used to compare them which  will return true.
This is the reason java doc says "if you override equals() method then you must override hashCode() method"

hashcode() and equals() contracts: 

equals():

The equals method implements an equivalence relation on non-null object references:
  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

hashcode():

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

Key points to remember:

  1. If you are overriding equals method then you should override hashcode() also.
  2. If two objects are equal then they must have same hashcode.
  3. If two objects have same hashcode then they may or may not be equal
  4. Always use same attributes to generate equals and hashcode as in our case we have used name.

Sunday, 8 December 2013

static keyword in java with examples

In this post, we will see about static keyword in java.So static keyword can be associated with:
  • Variable
  • Method
  • Block
  • Nested class
Lets go through each one by one.

Static variable:

If any instance variable is declared as static.It is known as static variable.
static int countryCounter;
Some points about static variables are:
  • Static variable belongs to a class not to a object.
  • Static variable are initialized only once in class area at the time of class loading
  • All objects share single copy of static variable
  • You don't need to create object to access static variable.You can directly access it using class name.
  • Static variable can be accessed by instance java methods also.

If you create a class with two variables, one static, one non static.Non static variable of that class (objects created from that class) gets its own version of that variable. But with the static variable, it belongs to the class, and there is only one. Although any object from that class can reference it.

Example:
Lets take a very simple example.You want to track how many objects you have created.For that you have a static variable in your class.Lets say your class is:
Country.java
package org.arpit.javapostsforlearning;
/*
 * @author:Arpit Mandliya
 */
public class Country {

    //static variable
   static int countryCounter;
  
    // instance variable
    String name;
    int dummyCounter;
    Country(String name)
    {
        this.name=name;
        countryCounter++;
        
        dummyCounter++;
    }
  
    public static void main(String[] args)
    {
        System.out.println("****************************************");

        Country india=new Country("India");
        System.out.println("Country Name: "+india.getName());
        System.out.println("Number of country object created: "+Country.countryCounter);
        System.out.println("Dummy counter not a static variable: "+india.dummyCounter);
        System.out.println("****************************************");
        Country france=new Country("France");
        System.out.println("Country Name: "+france.getName());
        System.out.println("Number of country object created: "+france.countryCounter);
        System.out.println("Dummy counter not a static variable: "+france.dummyCounter);

        System.out.println("****************************************");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


}
Output:
When you run above program,you will get following results:
****************************************
Country Name: India
Number of country object created: 1
Dummy counter not a static variable 1
****************************************
Country Name: France
Number of country object created: 2
Dummy counter not a static variable 1
****************************************

Diagram:

In above example,we have one static variable named "countryCounter" so whenever we are creating one new object,its value will be incremented by 1 as counterCounter variable is being shared by all country objects and we have instance variable named "dummyCounter" so whenever any new object is created,its value is initialized to 0 again.

Static Method:

If any method is declared as static.It is known as static method.
 public static void printCountryCounter()
    {
        System.out.println("Number of country object created: "+countryCounter);
    }
Some points about static methods are:
  •  Static method belongs to a class not to object.
  •  Static method can be invoked directly using a className.Although It can be invoked using      objectName also
  • Generally static method are used for getting static fields.
  • You can access static methods through java instance methods.
  • You can not access non static method or instance variable in static methods.
  • A static method can not refer to this or super keyword.
Example:
We will create above example and will use one static method printCountryCounter for printing countryCounter variable.
Country.java
package org.arpit.javapostsforlearning;
/*
 * @author:Arpit Mandliya
 */
public class Country {

    String name;
    static int countryCounter;
    int dummyCounter;
    Country(String name)
    {
        this.name=name;
        countryCounter++;
       
        dummyCounter++;
    }
    

    public static void main(String[] args)
    {
        Country india=new Country("India");
       
        System.out.println("****************************************");
        System.out.println("Country Name: "+india.getName());
        printCountryCounter();
        System.out.println("Dummy counter not a static variable: "+india.dummyCounter);
        System.out.println("****************************************");
        Country france=new Country("France");
        System.out.println("Country Name: "+france.getName());
        printCountryCounter();
        System.out.println("Dummy counter not a static variable: "+france.dummyCounter);
        System.out.println("****************************************");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public static void printCountryCounter()
    {
        System.out.println("Number of country object created: "+countryCounter);
    }
}

Output:
When you run above program,you will get following results: 

****************************************
Country Name: India
Number of country object created: 1
Dummy counter not a static variable 1
****************************************
Country Name: France
Number of country object created: 2
Dummy counter not a static variable 1
****************************************

Why can't you access non static member from static method:

When you call non static method from static method,you will get compilation error.
For example:In above printCountryCounter(),Lets say you call getName()
You will compilation error.
public static void printCountryCounter()

 {

        getName();  //Compilation error

        System.out.println("Number of country object created: "+countryCounter);

 }
 Imagine a situation, when you are allowed to call getName() from printCountryCounter() .You can call printCountryCounter() just using class name so when you call printCountryCounter() ,what value getName() should return because value may be different for each new object and which value will it refer.So that is why,you are not allowed call non static member from static method.

Static block:

The static block, is a block of statement inside a Java class that will be executed when a class is first loaded in to the JVM
Some points about static blocks are:
  • Static blocks are used to initialize static data members.
  • Static blocks get executed before main method get executed.
package org.arpit.javapostsforlearning;
public class StaticBlockExample {

    /**

     * @Author:Arpit Mandliya

     */

    static{
        System.out.println("This block will get call before main method");
    }

    public static void main(String[] args) {
        
        System.out.println("In main method");
    }
}

Output:
When you run above program,you will get following results: 
This block will get call before main method
In main method 

Static class:

In java,you can define a class within another class. Such a class is called a nested class. The class which enclosed nested class is known as Outer class. In java, we can’t make outer class static.
Only nested class can be declared as static
Some points about nested static class are:
  • Nested static class does not need reference of outer class.
  • A static class cannot access non-static members of the Outer class. It can access only static members of Outer class including private.
Example:
package org.arpit.javapostsforlearning;
/*
 * @author:Arpit Mandliya
 */
public class OuterClass {


    static class InnerStaticClass{
       
        public void printInnerClass()
        {
            System.out.println("In inner class");
        }
    }
       
    public static void main(String[] args)
    {
       
       
        System.out.println("****************************************");
        OuterClass.InnerStaticClass inc=new OuterClass.InnerStaticClass();
        inc.printInnerClass();
        System.out.println("****************************************");
    }

    public static void printOuterClass()
    {
        System.out.println("In outer class");
    }
    
} 

Output:
When you run above program,you will get following results: 
****************************************
In inner class
****************************************

Sunday, 17 November 2013

GSON example – Read and write JSON

In this post,we will see how can we read and write JSON using GSON.

Java JSON Tutorial Content:

Part-1:JSON Introduction
Part-2:JSON.simple example-read and write JSON 
Part-3:GSON example-read and write JSON 
After  reading and writing JSON using json-simple.We will use another way(i.e. GSON) of reading JSON.
Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.
There are various goals or advantages of using GSON(taken from GSON offcial page)
  • Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice-versa
  • Allow pre-existing unmodifiable objects to be converted to and from JSON
  • Extensive support of Java Generics
  • Allow custom representations for objects
  • Support arbitrarily complex objects (with deep inheritance hierarchies and extensive use of generic types)
Reading and writing JSON using GSON is very easy.You can use these two methods:
toJSON() : It will convert simple pojo object to JSON string.
FromJSON() : It will convert JSON string to pojo object.

In this post,we will read and write JSON using GSON.
Download gson-2.2.4 jar from here.

Create a java project named "GSONExample"
Create a folder jars and paste downloaded jar gson-2.2.4.jar.
right click on project->Property->java build path->Add jars and then go to src->jars->gson-2.2.4.jar.


Click on ok.
Then you will see json-simple-1.1 jar added to your libraries and then click on ok


First create a pojo named "Country.java"
package org.arpit.javapostsforlearning.pojo;

import java.util.ArrayList;
import java.util.List;

public class Country {

    String name;
    int population;
    private List<String> listOfStates;

    //getter and setter methods

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPopulation() {
        return population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

    public List<String> getListOfStates() {
        return listOfStates;
    }

    public void setListOfStates(List<String> listOfStates) {
        this.listOfStates = listOfStates;
    }

}

Write JSON to file:

Create a new class named "GSONWritingToFileExample.java" in src->org.arpit.javapostsforlearning
package org.arpit.javapostsforlearning;

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.arpit.javapostsforlearning.pojo.Country;
import com.google.gson.Gson;

/*
 * @Author : Arpit Mandliya
 */
public class GSONWritingToFileExample {

 public static void main(String[] args) {

  Country countryObj=new Country();
  countryObj.setName("India");
  countryObj.setPopulation(1000000);
  List<String> listOfStates=new ArrayList<String>();
  listOfStates.add("Madhya Pradesh");
  listOfStates.add("Maharastra");
  listOfStates.add("Rajasthan");
  
  countryObj.setListOfStates(listOfStates);
  Gson gson = new Gson();
  
  // convert java object to JSON format,
  // and returned as JSON formatted string
  String json = gson.toJson(countryObj);
  
  try {
   //write converted json data to a file named "CountryGSON.json"
   FileWriter writer = new FileWriter("E:\\CountryGSON.json");
   writer.write(json);
   writer.close();
  
  } catch (IOException e) {
   e.printStackTrace();
  }
  
  System.out.println(json);
  
     }
}

Run above program and you will get following output:
Writing JSON object to file
----------------------------
{"name":"India","population":1000000,"listOfStates":["Madhya Pradesh","Maharastra","Rajasthan"]}

Read JSON to file:

Here we will read above created JSON file.
Create a new class named "JSONSimpleReadingFromFileExample.java" in src->org.arpit.javapostsforlearning
package org.arpit.javapostsforlearning;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import org.arpit.javapostsforlearning.pojo.Country;
import com.google.gson.Gson;

/*
 * @Author : Arpit Mandliya
 */
public class GSONReadingFromFileExample {

 public static void main(String[] args) {

  Gson gson = new Gson();
   
  try {
  
   System.out.println("Reading JSON from a file");
   System.out.println("----------------------------");
   
   BufferedReader br = new BufferedReader(
     new FileReader("E:\\file.json"));
   
    //convert the json string back to object
   Country countryObj = gson.fromJson(br, Country.class);
   
   System.out.println("Name Of Country: "+countryObj.getName());

   
   System.out.println("Population: "+countryObj.getPopulation());

   System.out.println("States are :");
   
   List<String> listOfStates = countryObj.getListOfStates();
   for (int i = 0; i < listOfStates.size(); i++) {
    System.out.println(listOfStates.get(i));
   }
  
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
Run above program and you will get following output:
Reading JSON from a file
----------------------------
Name Of Country: India
Population: 1000000
States are :
Madhya Pradesh
Maharastra
Rajasthan 

Project Structure: 

 

JSON.simple example – Read and write JSON

In this post,we will see how can we read and write JSON using json.simple.

Java JSON Tutorial Content:

Part-1:JSON Introduction
Part-2:JSON.simple example-read and write JSON 
Part-3:GSON example-read and write JSON 

JSON.simple, is a simple Java library for JSON processing, read and write JSON data and full compliance with JSON specification (RFC4627).

In this post,we will read and write JSON using JSON.simple.
Download JSON.simple jar from here.

Create a java project named "JSONSimpleExample"
Create a folder jars and paste downloaded jar json-simple-1.1.1.jar.
right click on project->Property->java build path->Add jars and then go to src->jars->json-simple-1.1.1.jar.


Click on ok.
Then you will see json-simple-1.1 jar added to your libraries and then click on ok


Write JSON to file:

Create a new class named "JSONSimpleWritingToFileExample.java" in src->org.arpit.javapostsforlearning
package org.arpit.javapostsforlearning;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

/*
 * @Author : Arpit Mandliya
 */
public class JSONSimpleWritingToFileExample {

    public static void main(String[] args) {

        JSONObject countryObj = new JSONObject();
        countryObj.put("Name", "India");
        countryObj.put("Population", new Integer(1000000));

        JSONArray listOfStates = new JSONArray();
        listOfStates.add("Madhya Pradesh");
        listOfStates.add("Maharastra");
        listOfStates.add("Rajasthan");

        countryObj.put("States", listOfStates);

        try {
            
            // Writing to a file
            File file=new File("E:\\CountryJSONFile.json");
            file.createNewFile();
            FileWriter fileWriter = new FileWriter(file);
            System.out.println("Writing JSON object to file");
            System.out.println("-----------------------");
            System.out.print(countryObj);

            fileWriter.write(countryObj.toJSONString());
            fileWriter.flush();
            fileWriter.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

Run above program and you will get following output:
Writing JSON object to file
----------------------------
{"Name":"India","Population":1000000,"States":["Madhya Pradesh","Maharastra","Rajasthan"]}

Read JSON to file:

Here we will read above created JSON file.
Create a new class named "JSONSimpleReadingFromFileExample.java" in src->org.arpit.javapostsforlearning
package org.arpit.javapostsforlearning;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
/*
 * @Author : Arpit Mandliya
 */
public class JSONSimpleReadingFromFileExample {

 public static void main(String[] args) {

  JSONParser parser = new JSONParser();

  try {

   Object obj = parser.parse(new FileReader("E:\\CountryJSONFile.json"));

   JSONObject jsonObject = (JSONObject) obj;

   String nameOfCountry = (String) jsonObject.get("Name");
   System.out.println("Name Of Country: "+nameOfCountry);

   long population = (long) jsonObject.get("Population");
   System.out.println("Population: "+population);

   System.out.println("States are :");
   JSONArray listOfStates = (JSONArray) jsonObject.get("States");
   Iterator<String> iterator = listOfStates.iterator();
   while (iterator.hasNext()) {
    System.out.println(iterator.next());
   }

  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (ParseException e) {
   e.printStackTrace();
  }

 }
}
Run above program and you will get following output:
Reading JSON from a file
----------------------------
Name Of Country: India
Population: 1000000
States are :
Madhya Pradesh
Maharastra
Rajasthan 

Project Structure: 

 

Java JSON tutorial

In this post,We will see introduction to JSON

Java JSON Tutorial Content:

Part-1:JSON Introduction
Part-2:JSON.simple example-read and write JSON 
Part-3:GSON example-read and write JSON 

What is JSON?

JSON stands for JavaScript Object Notation.It  is a simple and easy to read and write data exchange format just like XML.JSON is smaller than XML, and faster and easier to parse.

It is entirely language independent and can be used with most of the modern programming languages.

Internet media type of JSON is "application/json".

JSON sample:
    {
    "Countries": [
    { "Name": "India",
    "Capital": "Delhi"
    },
    {
    "Name": "France",
    "Major": "Paris"
    },
    ]
    } 
The above sample store informatipn about two countries.Basically
  1. Squiggly brackets({ }) act as containers
  2. Square brackets([ ]) represents arrays.
  3. Names and values are separated by a colon(:).
  4. Array elements are separated by commas

Comparison with XML:

As JSON and XML both are data exchange format.There is always comparison between them.

Similarity:
  • Both are human readable.
  • Both are hierarchical. (i.e. You can have values within values.)
  • Both are used by most of programming languages.
Differences:
  • JSON is less verbose so it's definitely quicker for humans to write, and probably quicker for us to read.
  • JSON stores data in form of Key-value pair which is universal in nature.
  • JSON is faster than XML.
  • JSON can be parsed trivially using the eval() procedure in JavaScript

Thursday, 4 April 2013

RESTful web service tutorial

In this post,we will see RESTful web service introduction.

Part-1:Introduction to web services
Part-2:SOAP web service introduction 
Part-3:RESTful web service introduction 
Part-4:SOAP web service example in java using eclipse
Part-5:JAX-WS web service eclipse tutorial
Part-6:JAX-WS web service deployment on tomcat 
Part-7:Create RESTful web service in java(JAX-RS) using jersey

REST is an architectural style which was brought in by Roy Fielding in 2000 in his doctoral thesis.

In the web services terms, REpresentational State Transfer (REST) is  a stateless client-server architecture in which the web services are viewed as resources and can be identified by their URIs. Web service clients that want to use these resources access via globally defined set of remote methods that describe the action to be performed on the resource.

It consists of two components REST server which provides access to the resources and a REST client which accesses and modify the REST resources.

In the REST architecture style, clients and servers exchange representations of resources by using a standardized interface and protocol.REST isn't protocol specific, but when people talk about REST they usually mean REST over HTTP.

The response from server is considered as the representation of the resources. This representation can be generated from one resource or more number of resources.


REST allows that resources have different representations, e.g.xml, json etc. The rest client can ask for specific representation via the HTTP protocol.

HTTP methods : 

RESTful web services use HTTP protocol methods for the operations they perform.Methods are:
  • GET:It defines a reading access of the resource without side-effects.This operation is idempotent i.e.they can be applied multiple times without changing the result
  • PUT :  It creates a new resource.It must also be idempotent.
  • DELETE : It removes the resources. The operations are idempotent i.e. they can get repeated without leading to different results.
  • POST :It updates an existing resource or creates a new resource.

Features of RESTful web services:

Resource identification through URI:Resources are identified by their URIs (typically links on internet). So, a client can directly access a RESTful Web Services using the URIs of the resources (same as you put a website address in the browser’s address bar and get some representation as response).

Uniform interface: Resources are manipulated using a fixed set of four create, read, update, delete operations: PUT, GET, POST, and DELETE.

Client-Server: A clear separation concerns is the reason behind this constraint. Separating concerns between the Client and Server helps improve portability in the Client and Scalability of the server components.

Stateless: each request from client to server must contain all the information necessary to understand the request, and cannot take advantage of any stored context on the server.

Cache: to improve network efficiency responses must be capable of being labeled as cacheable or non-cacheable.

Named resources - the system is comprised of resources which are named using a URL.

Interconnected resource representations - the representations of the resources are interconnected using URLs, thereby enabling a client to progress from one state to another.

Layered components - intermediaries, such as proxy servers, cache servers, gateways, etc, can be inserted between clients and resources to support performance, security, etc.

Self-descriptive messages: Resources are decoupled from their representation so that their content can be accessed in a variety of formats, such as HTML, XML, plain text, PDF, JPEG, JSON, and others. 

Create RESTful web services in java(JAX-RS) using jersey

In this post,we will develop RESTful web service using jersey in eclipse

Web service Tutorial Content:

Part-1:Introduction to web services
Part-2:SOAP web service introduction 
Part-3:RESTful web service introduction 
Part-4:SOAP web service example in java using eclipse
Part-5:JAX-WS web service eclipse tutorial
Part-6:JAX-WS web service deployment on tomcat 
Part-7:Create RESTful web service in java(JAX-RS) using jersey

Java API for RESTful Web Services (JAX-RS), is a set if APIs to developer REST service. JAX-RS is part of the Java EE6, and make developers to develop REST web application easily.

Jersey is the reference implementation for this specification. Jersey contains basically a REST server and a REST client. The core client can communicate with the server using jersey lib.

On the server side Jersey uses a servlet which scans predefined classes to identify RESTful resources. Via the web.xml configuration file for your web application.

The base URL of this servlet is:
http://your_domain:port/display-name/url-pattern/path_from_rest_class 
This servlet analyzes the incoming HTTP request and selects the correct class and method depending on  request. This selection is based on annotations provided in the class and methods. 

Prerequisites:


1) Open eclipse.
2) Create new dynamic web project named "RESTfulWebserviceExample"

3) Now go to location where you have download jersey and go to jersey-archive-1.17->lib
folder.you can have all jars but for now you can copy following jars
  • asm-3.1
  • jersey-client-1.17
  • jersey-core-1.17
  • jersey-server-1.17
  • jersey-servlet-1.17
  • jsr311-api-1.1.1
Paste all above copied jars to WebContent->WEB-INF->lib

Add all these jars to eclipse build path.
Right click on project(RESTfulWebserviceExample)->properties


Click on Java Build Path and then Add jars as shown in above diagram.

go to project->WebContent->WEB-INF->lib and select all jars then click on ok.

Click ok.Jersey jars added to class path.
4) Create new package named "org.arpit.javapostsforlearning.webservice"

5)Create  FeetToInchAndInchToFeetConversionService.java

package org.arpit.javapostsforlearning.webservice;
/**
* @author Arpit Mandliya
*/
 
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
 
@Path("ConversionService")
public class FeetToInchAndInchToFeetConversionService {
     @GET
     @Path("/InchToFeet/{i}")
      @Produces(MediaType.TEXT_XML)
      public String convertInchToFeet(@PathParam("i") int i) {
 
        int inch=i;
        double feet = 0;
        feet =(double) inch/12;
      
        return "<InchToFeetService>"
        + "<Inch>" + inch + "</Inch>"
          + "<Feet>" + feet + "</Feet>"
         + "</InchToFeetService>";
      }
 
      @Path("/FeetToInch/{f}")
      @GET
      @Produces(MediaType.TEXT_XML)
      public String convertFeetToInch(@PathParam("f") int f) {
       int inch=0;
          int feet = f;
          inch = 12*feet;
   
          return "<FeetToInchService>"
            + "<Feet>" + feet + "</Feet>"
            + "<Inch>" + inch + "</Inch>"
            + "</FeetToInchService>";
      }
}

@Path(/your_path_at_class_level) : Sets the path to base URL + /your_path_at_class_level. The base URL is based on your application name, the servlet and the URL pattern from the web.xml" configuration file.

@Path(/your_path_at_method_level): Sets path to base URL + /your_path_at_class_level+ /your_path_at_method_level

@Produces(MediaType.TEXT_XML [, more-types ]): @Produces defines which MIME type is delivered by a method annotated with @GET. In the example text ("text/XML") is produced.

@PathParam: Used to inject values from the URL into a method parameter.This way you inject inch in convertFeetToInch method and convert that to feet.
6)Now you need to create web.xml and put it under /RESTfulWebserviceExample/WebContent/WEB-INF/
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>RESTfulWebServiceExample</display-name>
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>org.arpit.javapostsforlearning.webservices</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
</web-app> 
In above <param-value>,put your web service package.
8) Run project:right click on project->run as ->run on server
9) Test your REST service under: "http://localhost:8080/RESTfulWebServiceExample/rest/ConversionService/FeetToInch/2". 

You will get output as :

If You see web service information page then you are done.

Creating a Restful Web Service Client:

Create ConversionServiceClient.java under org.arpit.javapostsforlearning.websevices.client

package org.arpit.javapostsforlearning.webservices.client;

import javax.ws.rs.core.MediaType;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;

public class ConversionServiceClient {
    static final String REST_URI = "http://localhost:8080/RESTfulWebServiceExample";
    static final String INCH_TO_FEET = "/ConversionService/InchToFeet/";
    static final String FEET_TO_INCH = "/ConversionService/FeetToInch/";

    public static void main(String[] args) {

        int inch=12;
        int feet=2;

        ClientConfig config = new DefaultClientConfig();
        Client client = Client.create(config);
        WebResource service = client.resource(REST_URI);

        WebResource addService = service.path("rest").path(INCH_TO_FEET+inch);
        System.out.println("INCH_TO_FEET Response: " + getResponse(addService));
        System.out.println("INCH_TO_FEET Output as XML: " + getOutputAsXML(addService));
        System.out.println("---------------------------------------------------");

        WebResource subService = service.path("rest").path(FEET_TO_INCH+feet);
        System.out.println("FEET_TO_INCH Response: " + getResponse(subService));
        System.out.println("FEET_TO_INCH Output as XML: " + getOutputAsXML(subService));
        System.out.println("---------------------------------------------------");

    }

    private static String getResponse(WebResource service) {
        return service.accept(MediaType.TEXT_XML).get(ClientResponse.class).toString();
    }

    private static String getOutputAsXML(WebResource service) {
        return service.accept(MediaType.TEXT_XML).get(String.class);
    }
}

Run above program
Output:
INCH_TO_FEET Response: GET http://localhost:8080/RESTfulWebServiceExample/rest/ConversionService/InchToFeet/12 returned a response status of 200 OK
INCH_TO_FEET Output as XML: <InchToFeetService><Inch>12</Inch><Feet>1.0</Feet></InchToFeetService>
---------------------------------------------------
FEET_TO_INCH Response: GET http://localhost:8080/RESTfulWebServiceExample/rest/ConversionService/FeetToInch/2 returned a response status of 200 OK
FEET_TO_INCH Output as XML: <FeetToInchService><Feet>2</Feet><Inch>24</Inch></FeetToInchService>
---------------------------------------------------
Source:Download 
 

Java tutorial for beginners Copyright © 2011 - |- Template created by O Pregador - |- Powered by Blogger Templates