Monday, 31 March 2014

Accessing resources from Spring Application context

The following example illustrates accessing resources (both external to the project and internal) from the spring application context.

To learn this, we need to first learn about the org.springframework.core.io.Resource interface. This interface contains some methods which you can learn from the above url. All those methods are are self-explanatory. One method that I would like to pin point is the createRelative() method.
This method takes in a string, the relative path of the current resource and creates a resource object for it. An example, will give you a better understand. For example, consider a resource 'r' pointing to the E:/java/sample.txt. Now, when i call r.createRelative("ding/asdf.txt"); then I will get a Resource object pointing to E:/java/ding/asdf.txt

Create a project in eclipse

So, I'll be naming the project as spring1 since this is the first demo. Note that I haven't used STS (Spring Tool Suite) which most will probably be using. Rather, I have just downloaded the required jar files we need to create our project and included them in the library. Therefore, we will be carrying on creating a simple eclipse project and adding the necessary spring jars. I am using Eclipse KEPLER.

  1. File -> New -> Project -> Java Project
  2. Give the project name spring28 and click Finish 
  3. Now, the project is created.
  4. Under the Project Explorer (in the sidebar) you will see spring1. If you aren't able to see Project Explorer, go to Window menu -> Show view -> Project Explorer.
  5. Right click on the spring28 and click Properties
  6. On the left side, click on Java Build Path.
  7. Select the Libraries tab and then click on Add External Jars
  8. Now, add these jar files starting with: spring-beans, spring-context, spring-core, commons-logging
  9. Click on OK and then you are ready.

Project structure


SpringPrg.java - Main class



package spring28;



import java.io.InputStream;



import org.springframework.context.support.GenericXmlApplicationContext;

import org.springframework.core.io.Resource;



public class SpringPrg {



    @SuppressWarnings("resource")

    public static void main(String args[])

    {

        GenericXmlApplicationContext gc=new GenericXmlApplicationContext();

       

        Resource r1=gc.getResource("classpath:resources/sample.txt");

        Resource r2=gc.getResource("file:///e:/java/ascii.java");

       

        displayInfo(r1);

        displayInfo(r2);

    }

   

    public static void displayInfo(Resource r)

    {

        System.out.println("The file name is "+r.getFilename());

        System.out.println("The description is "+r.getDescription());

       

        try

        {

        System.out.println("The contents of the file is \n"+getContentAsString(r.getInputStream()));

        }catch(Exception e){}

        System.out.println("-------------------------------------");

    }

   

    public static String getContentAsString(InputStream is) throws Exception

    {

    StringBuffer sb=new StringBuffer();

    int k;

   

        while((k=is.read())!=-1)

        {

            sb.append((char)k);

        }

       

    return sb.toString();

    }

   

}

Friday, 28 March 2014

Using inherit attribute in Spring bean tag

The following example illustrates using inherit attribute in the spring <bean> tag.




1. Create a project in eclipse

  1. File -> New -> Project -> Java Project
  2. Give the project name spring3 and click Finish 
  3. Now, the project is created.
  4. Under the Project Explorer (in the sidebar) you will see spring3. If you aren't able to see Project Explorer, go to Window menu -> Show view -> Project Explorer.
  5. Right click on the spring3 and click Properties
  6. On the left side, click on Java Build Path.
  7. Select the Libraries tab and then click on Add External Jars
  8. Now, add these jar files starting with: spring-beans, spring-context, spring-core, spring-expression, commons-logging
  9. Click on OK and then you are ready.
Now right click on the src folder under spring3 and New -> Class and name it SpringPrg

Main program - SpringPrg.java



package spring3;

import org.springframework.context.support.GenericXmlApplicationContext;

public class SpringPrg {

    @SuppressWarnings("resource")
    public static void main(String args[])
    {
        GenericXmlApplicationContext gc=new GenericXmlApplicationContext();
        gc.load("classpath:applicationContext.xml");
        gc.refresh();
       
        Student st=gc.getBean("st2",Student.class);
       
        System.out.println(st.getSno()+" "+st.getSname()+" "+st.getAge());
    }
   
}

The code here is normal. I have used the GenericXmlApplicationContext class which loads the given xml file and reads the bean definitions i.e. it reads how to create bean class objects from the xml file.

The gc.getBean() method returns the object st2 defined in the XML file. The xml file is given below.

Now, again in the package explorer, right click on spring3 and then New -> Class and name it Student

Bean class - Student.java



package spring3;

public class Student {

private int sno;
private String sname;
private int age;

    public void setSno(int sno)
    {
        this.sno=sno;
    }
   
    public int getSno()
    {
        return sno;
    }
   
    public void setSname(String sname)
    {
        this.sname=sname;
    }
   
    public String getSname()
    {
        return sname;
    }
   
    public void setAge(int age)
    {
        this.age=age;
    }
   
    public int getAge()
    {
        return age;
    }
   
}

This is a very simple bean class that takes three general properties of a Student sno, sname and age. Values to these properties are set in the xml file.

Now right click on the src in package explorer, and New -> Other and type xml file in the textbox, hit enter and give it the name applicationContext.xml.

Bean definitions - applicationContext.xml



<?xml version="1.0" encoding="UTF-8"?>
<beans     xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
       
        <bean id="st1" class="spring3.Student">
            <property name="sno" value="101"/>
            <property name="sname" value="Rama"/>
            <property name="age" value="20"/>
        </bean>
       
        <bean id="st2" class="spring3.Student" parent="st1">
            <property name="age" value="22"/>
        </bean>
       
</beans>

As you can see, first we have created a bean object called st1 for the class spring3.Student and then in it we have set the properties, sno to 101, sname to Rama, age to 20. That code can be interpreted into Java like this..



Student st1=new Student();


st1.setSno(101);


st1.setSname("Rama");


st1.setAge(20);

Now, we have also created another object for Student class called st2. You can notice the parent attribute which points to st1. This means that the properties of st1 will be copied to st2.
Additionally, we have included a property tag in st2 setting age to 22. This line, tells that it overrides the age property copied from the st1. In Java the code can be interpreted as..



Student st2=new Student();


st2.setSno(st1.getSno());


st2.setSname(st1.getSname());


st2.setAge(st1.getAge());


st2.setAge(22);


abstract attribute

In the SpringPrg.java program, you can also get the st1 object like this..

Student st=gc.getBean("st1",Student.class);
System.out.println(st1.getSno()+" "+st1.getSname()+" "+st1.getAge());

But if you don't want st1 to be accessed i.e. looked up or don't want to create an object for it, then you should place the abstract="true" while defining the st1. Replace the line..



<bean id="st1" class="spring3.Student">

with the following..



<bean id="st1" class="spring3.Student" abstract="true">

Tuesday, 25 March 2014

Using @Autowired and @Component - Spring Dependency Injection

In this example we will discuss spring dependency injection using annotations. Here I'll introduce you to two simple annotations, @Component and @Autowired. In the previous example, we have declared those beans in the application context xml file. But in this file, we will create only one bean and we will inject that bean into another class via annotations.

Simple bean - Message.java


package spring2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Component("msgObject")
public class Message {

private String message;

    @Autowired
    public void setMessage(String message)
    {
        this.message=message;
    }
   
    public String getMessage()
    {
        return message;
    }
}

The @Autowired annotation allows the container to automatically inject the message property from the application-context.xml file. The container searches for String bean object in the xml file and injects it here. If multiple String beans exist, then we will get an error.

The @Component tells that Message is a component, a bean whose object has to be created. The "msgObject" is the name of the created object.

Application context - application-context.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans     xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
       
        <context:annotation-config/>
        <context:component-scan base-package="spring2"/>
       
        <bean id="myMsg" class="java.lang.String">
            <constructor-arg type="java.lang.String" value="Rama"/>
        </bean>
</beans>


Here we have created only one bean that too for java.lang.String. As you can the name of the object is myMsg and we are using the String(String) constructor to create the object. In Java code, the snippet will be


String myMsg=new String("Rama");


The first line, <context:annotation-config/> searches for annotations i.e. it searches for where the dependencies has to be injected.
The second line, <context:component-scan/> searches for dependencies (those values which has to be injected). This takes base-package attribute which will be the package where the dependencies are scanned.

Dependencies are nothing but objects that are essential to create/use other objects.

http://www.springframework.org/schema/context/spring-context-3.0.xsd contains definitions for annotation-config and component-scan tags.

Namespace is a name given to a set of tags. These tags are defined in XSD files (xml schema definition files). In our application-context.xml we will be using tags from different xsd files and sometimes multiple xsd files might contain tags with the same name. So in order to avoid the ambiguous situation, a namespace is provided. Here, context is the namespace. We call it tag prefix here, telling the container that we are using the tag that is defined in the spring-context-3.0.xsd file.

Main class - SpringPrg1.java



package spring2;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringPrg1 {
    public static void main(String args[])
    {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("spring2/application-context.xml");
        Message msg=ctx.getBean("msgObject",Message.class);
        System.out.println(msg.getMessage());
    }
}

Here, we will get the msgObject which is not defined in the XML file, as you can see. Instead, it is written using annotation in the Message class itself.

Here, we have used ctx.getBean("msgObject",Message.class) instead of ctx.getBean("msgObject") in order to avoid explicit type-casting.

Spring Core Hello World example

Here is a very simple spring core hello world example that will guide you to learning the spring in an easy way. The following example will contain two simple classes and an xml file which makes it easy for you to understand the very large concepts of spring.

1. Download Spring framework


Many of the developers use maven, a tool that will automatically download the necessary jar files for a project. But in this tutorial, I'll not be using maven instead, the theme of the tutorial is to teach spring and not maven with spring, I suggest manually downloading the jar files so that you'll get a better idea of what jar files you require for your project. However, at real time it is recommended to use a tool like the maven.

http://repo.spring.io/release/org/springframework/spring/

In the above link, you will be provided with several versions of spring. Download the latest version possible. Download those that end with -dist.zip because these files contain the jar files that we need for our project.
After downloading extract them to a location. You will also need commons-logging because spring uses it for logging purposes.

http://commons.apache.org/proper/commons-logging/download_logging.cgi

Till now, in this blog, we have seen writing programs in Notepad and then compiling them and executing them in the command prompt. While this is a good practice for starters, I recommend using Eclipse (the most popular IDE for Java developers) to continue with the Spring because a developer, in real time environment will be using an IDE to write programs. Hope you will embrace this change.

2. Create a project in eclipse

So, I'll be naming the project as spring1 since this is the first demo. Note that I haven't used STS (Spring Tool Suite) which most will probably be using. Rather, I have just downloaded the required jar files we need to create our project and included them in the library. Therefore, we will be carrying on creating a simple eclipse project and adding the necessary spring jars. I am using Eclipse JUNO.

  1. File -> New -> Project -> Java Project
  2. Give the project name spring1 and click Finish 
  3. Now, the project is created.
  4. Under the Project Explorer (in the sidebar) you will see spring1. If you aren't able to see Project Explorer, go to Window menu -> Show view -> Project Explorer.
  5. Right click on the spring1 and click Properties
  6. On the left side, click on Java Build Path.
  7. Select the Libraries tab and then click on Add External Jars
  8. Now, add these jar files starting with: spring-beans, spring-context, spring-core, spring-expression, commons-logging
  9. Click on OK and then you are ready.
 

Simple bean - Message.java

A bean is nothing more than a class that represents a particular entity. This class will contain details about that entity which can be accessed using its object.



package spring1;



public class Message {



private String message;



    public void setMessage(String message)

    {

        this.message=message;

    }

   

    public String getMessage()

    {

        return message;

    }

}

The class contains setMessage() which is used to set the message and getMessage() which is used to get the message.

Main class - SpringPrg.java

This class will contain the main method and here we will be getting the object of Message class from the factory.



package spring1;



import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



public class SpringPrg {

    public static void main(String[] args)

    {

        ApplicationContext ctx=new ClassPathXmlApplicationContext("spring1/context.xml");

        Message m=(Message)ctx.getBean("message");

        System.out.println(m.getMessage());

    }

}

Here ApplicationContext is an interface that is implemented by ClassPathXmlApplicationContext class. This class will take an XML file which will contain how bean objects are created. According to this, the spring container creates the bean objects and gets them for us.

The advantage of getting a bean object from the container is that, the container reads the xml file and creates the object according to the procedure mentioned in that file. So, if you would like to change the way you create the object, for example, if you want to use a different constructor, then you need not change the code of your Java program, you'll only need to change that in the xml file. Therefore, you will remove the burden of recompiling the class file every time you want to change the message or use a different constructor.
Also, sometimes you might need to create a lot of objects for use in different classes. So at that time, you'll probably write the creation code like this.


Message m=new Message();

m.setMessage("Hello world!");

Two lines of code, every time you want to use it in a class. It will be a problem, especially if you have 100+ classes that will use this object and therefore you will need to write 200 lines of code. In some cases, object creation might take 5 lines or more , so you'll need to write 500 extra lines of code. For example,


A a=new A();

B b=new B();

C c=new C();

D d=new D();

X x=new X(a,b,c,d);

Application Context - context.xml



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- Create object for spring1.Message with name message -->
    <bean id="message" class="spring1.Message">
   
        <!-- Call message.setMessage("Hello world!") -->
        <property name="message" value="Hello world!"/>
   
    </bean>

</beans>

This is an XML file which you might have undergone several times. The <beans> tag contains several bean definitions i.e. how those bean object has to be created. A bean here is a class.

xmlns: This stands for xml namespace. When you declare xmlns="" means that it is the default namespace. Here the only namespace we are using is beans.
xsi:schemaLocation : Specifies the location of the schema. The http://www.springframework.org/schema/beans/spring-beans-3.0.xsd file contains definitions for the <beans> and <bean> tag and so on.

You can give this file any name you want but make sure that the same name is passed in the ClassPathXmlApplicationContext.

Wednesday, 19 February 2014

Import CSV file to Oracle using JDBC (in 5 lines!)

Here is a simple 5 line program that imports CSV file to Oracle as a table using JDBC.
Here we will be using the concept of external tables in Oracle. We will just be executing that command from our JDBC program.

C:\java\sample.csv



sno,sname,age


101,"smith",20


102,"scott",25

csv3.java


import java.sql.*;
class csv3
{
    public static void main(String args[]) throws Exception
    {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        System.out.println("driver loaded");

        Connection c=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","scott","tiger");
        System.out.println("connection established");

        Statement s=c.createStatement();

        s.executeUpdate("create or replace directory my_dir as 'C:\\java\\'");

        System.out.println("dir created");

        s.executeUpdate("create table mytab(sno number(4),sname varchar2(40), age number(4)) organization external(type ORACLE_LOADER default directory my_dir access parameters(records delimited by newline fields terminated by \",\") location('sample.csv')) reject limit unlimited");
        System.out.println("table imported");

    }
}

Note: You will need Oracle Type 4 driver in your system classpath for this program to work. So make sure that you copy the path of required jar files (classes12.jar, ojdbc14.jar) to your classpath in system variables.
Those jars can be found in the installation directory of oracle. I'm not sure about the path, but just hit search for those files. You will find both jar files exist in the same directory. If you don't find those files, better download them here. For Oracle 11g you can search them or download ojdbc5.jar here (I think you can even download this for Oracle 10g instead of downloading those two files).

Sunday, 16 February 2014

How to read a CSV file using JDBC (in 4 lines!)

Here is a 4 line JDBC program that reads a csv file and prints records in it. You will not need lengthy IO code to do this if you have Windows operating system. Here I will be using Type 1 driver and all you need to do is just write queries.

First you need to add a system dsn in your Windows operating system.

1. Go to Control Panel > Switch to classic view (if not in classic view)
2. Go to Administrative Tools
3. In it Data Sources (ODBC)
4. Go to System DSN tab and then click Add
5. Select Microsoft Text Driver (*.txt;*.csv) and then click Finish
6. Now give a name in the first field and hit Enter. Here i gave the name google

CSV File

CSV stands for Comma separated values. In this data is stored in the form of a table but each cell in a row is separated by a comma and each record (row) is separated by a new line. The first line is the heading of the columns. Each column heading is separated by a comma. Here is a simple CSV file that I'll be using

sample1.csv



sno,sname,age


101,"smith",20


102,"scott",25

Here sno,sname,age are column headings and 101,"smith",20 is a record where 101 is sno, "smith" is sname and 20 is age.

csv1.java



import java.sql.*;
class csv1
{
    public static void main(String args[]) throws Exception
    {
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
   
    Connection c=DriverManager.getConnection("jdbc:odbc:google");
   
    Statement s=c.createStatement();

    ResultSet rs=s.executeQuery("select * from sample1.csv where sno=101");

    // to select all records
    // select *from sample1.csv
   
        while(rs.next())
        {
        System.out.println(rs.getObject(1)+"  "+rs.getObject(2)+"  "+rs.getObject(3));
        }
   
    // you can insert a record
    // here sample1.csv exists in current dir
    s.executeUpdate("insert into sample1.csv values(103,'scott',20)");
   
    s.close();
    c.close();
    }
}

Output of csv1



101  smith  20

Note: The problem here is that you cannot update a record or delete a record following this procedure.

Set Session Expire Time in Servlets

Here is a very simple method that sets the session expire time in servlets.

Description

The following servlet application takes 2 numbers which it will add. This contains two servlets called MyServlet and AddServlet. The MyServlet class is intended to take the input parameters from HTML page and then check whether they are numbers or not. When they are numbers, those numbers are set as session attributes and a link to the /add url is shown. This url corresponds to the AddServlet class.
The AddServlet class takes these session attributes set in the MyServlet and converts them to int and prints their sum.
When creating session in MyServlet that session is set an expiry time after which it will expire. When the session is expired that session object no longer exists which means that the attributes set to it will no longer exist. Here it the expiry time is set to 5 seconds.

The method used to set an attribute to a session is setAttribute(String key, Object value)
The method used to get an attribute value from a session is getAttribute(String key). When you pass a key to this method that doesn't exist, it will return null.

Folder structure



ses1
│   index.html
│
└───WEB-INF
    │   web.xml
    │
    └───classes
            AddServlet.class
            AddServlet.java
            MyServlet.class
            MyServlet.java

index.html


<html>
    <body>
        <center>
            <form action="./first" method="post">
                <table>
                    <tr>
                        <td>Enter first number</td>
                        <td><input type="text" name="t1"/><br/></td>
                    </tr>

                    <tr>
                        <td>Enter second number</td>
                        <td><input type="text" name="t2"/><br/></td>
                    </tr>

                    <tr>
                        <td><input type="submit" value="add"/></td>
                        <td><input type="reset" value="clear"/></td>
                    </tr>
                </table>
            </form>
        </center>
    </body>
</html>

web.xml (deployment descriptor)



<web-app>
    <servlet>
        <servlet-name>firstser</servlet-name>
        <servlet-class>MyServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>firstser</servlet-name>
        <url-pattern>/first</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>finalser</servlet-name>
        <servlet-class>AddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>finalser</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>   
</web-app>

MyServlet.java



import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
public class MyServlet extends HttpServlet
{
    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    {
        PrintWriter pw=res.getWriter();

        // create session object or get existing session object (if any)
        HttpSession ses=req.getSession();

        // set 5 seconds
        // default is 1800 seconds (30 minutes)
        ses.setMaxInactiveInterval(5);

        String num1=req.getParameter("t1");
        String num2=req.getParameter("t2");

        try
        {
        int x=Integer.parseInt(num1);
        int y=Integer.parseInt(num2);

        ses.setAttribute("fno",num1);
        ses.setAttribute("sno",num2);

        pw.println("<html>");
        pw.println("<body>");
        pw.println("Add before "+ses.getMaxInactiveInterval()+" seconds.. Quick\n");
        pw.println("<a href='./add'>Click here to add</a>");
        pw.println("</body>");
        pw.println("</html>");
        }catch(Exception e){
            pw.println("Enter valid input");
        }

        pw.close();
    }
}

AddServlet.java



import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.util.*;
public class AddServlet extends HttpServlet
{
    // doGet because AddServlet is called via anchor tag <a href='./add'>Click here to add</a>
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    {
        PrintWriter pw=res.getWriter();

        // create session object or get existing session object (if any)

        // when session expires i.e. if the user doesn't click on the link
        // within 5 seconds then new session is created and its object is returned
        // When this happens, the new session object will contain no attributes
        // i.e. no fno, no sno
        HttpSession ses=req.getSession();

        // Get attributes from session created in MyServlet
        try
        {

        // here both number1 and number2 will be null if session
        // expires
        String number1=(String)ses.getAttribute("fno");
        String number2=(String)ses.getAttribute("sno");

        // You get a NumberFormatException when session expires
        // because you cannot parse null to int
        int x=Integer.parseInt(number1);
        int y=Integer.parseInt(number2);

        pw.println("The sum is "+(x+y));
        }catch(NumberFormatException e)
        {
            pw.println("Session expired");
        }

        // print when the session was created
        // getCreationDate() returns long (milliseconds) from Jan 1 1970, 00:00:00
        // to current date, this is passed to Date constructor for a viewable format
        pw.println("The session was created on "+new Date(ses.getCreationTime()));

        // when was session last accessed i.e. last getSession() call
        pw.println("The session was last accessed on "+new Date(ses.getLastAccessedTime()));

        pw.close();
    }
}