Thursday, November 6, 2008

How to start Spring Spring tutorial

We can use spring in plain java project and web based java project. First I am going to explain the spring in plain java.

1. Create java project in Eclipse say SpringDemo
2. Add two jar files (spring.jar, commons-logging.jar)
3. Create three files.
a.) HelloImpl.java
b.) hello.xml
c.) helloclient.java

HelloImpl.java

public class HelloImpl {
private String greeting;
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
public String sayHello(String name){
return greeting+" "+name;
}
}

hello.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
http://www.springframework.org/dtd/spring-beans.dtd>
<beans>
<bean id="hello" class="HelloImpl">
<property name="greeting">
<value>Good Morning!...</value>
</property>
</bean>
</beans>


helloclient.java

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class helloclient {
public static void main(String[] args) {
new helloclient().connect();
}
public void connect(){
try
{
System.out.println("please Wait.");
Resource res = new ClassPathResource("hello.xml");
BeanFactory factory = new XmlBeanFactory(res);
HelloImpl bean1 = (HelloImpl)factory.getBean("hello");
String s = bean1.sayHello("Binod");
System.out.println(s);
}
catch(Exception e1){ System.out.println(""+e1); }
}

}

Now run helloclient
You will get output

Good Morning!... Binod


We can also implement the interface in the above example
1. Create one interface Ihello.java
public interface Ihello {

public String sayHello(String name);

}
2. Put this interface in HelloImpl.java

public class HelloImpl implements Ihello{
private String greeting;
public String getGreeting() {
return greeting;
}

public void setGreeting(String greeting) {
this.greeting = greeting;
}

public String sayHello(String name){
return greeting+" "+name;
}
}
2. No need to change any thing in hello.xml
3. Only change in helloclient.java
4. Create databae table
CREATE TABLE userdata( id int8 NOT NULL, username text, "password" text, CONSTRAINT "PK" PRIMARY KEY (id))
5. Insert data in userdata table
insert into userdata values (110,'Binod','Binod');
isnert into userdata values(120,'Pramod','Pramod');


import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;


public class helloclient {
public static void main(String[] args) {
new helloclient().connect();
}

public void connect(){
try
{
System.out.println("please Wait.");
Resource res = new ClassPathResource("hello.xml");
BeanFactory factory = new XmlBeanFactory(res);
Ihello bean1 = (Ihello)factory.getBean("hello");
String s = bean1.sayHello("Suman");
System.out.println(s);
}
catch(Exception e1){ System.out.println(""+e1); }
}
}

Now you can run the helloclient.java
you will get output

Good Morning!... Suman

Spring example with Database setup
In this example, I will show you that how to connect the database (PostgresSQL) using spring

1. Add one more jar file in the project (postgresql-8.1dev-403.jdbc2ee.jar)
2. DB2.java
3. Change in hello.xml
4. Change in helloclient.java

hello.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="hello" class="HelloImpl">
<property name="greeting">
<value>Good Morning!...</value>
</property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/postgres"/>
<property name="username"> <value>postgres</value>
</property> <property name="password"><value>suman</value>
</property>
</bean>

<bean id="db2" class="DB2">
<property name="dataSource" ref="dataSource" />
</bean>

</beans>

DB2.java

import java.sql.* ;
import javax.sql.DataSource;
class DB2
{
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void connection(){
try{
Connection con = dataSource.getConnection();
Statement stmt = con.createStatement() ;
ResultSet rs = stmt.executeQuery( "SELECT * FROM userdata" ) ;
System.out.println("CONNECTION USING SPRING");
while( rs.next() ){
System.out.print("ID :: "+rs.getInt(1) +" ") ;
System.out.print("USERNAME :: "+rs.getString(2) +" ") ;
System.out.println( "PASSWORD ::"+rs.getString(3) ) ;
}
// Close the result set, statement and the connection
rs.close() ;
stmt.close() ;
con.close() ;
}catch (SQLException e) {
System.out.println("SOME PROBLEM DURING DATABASE CONNECTION :: "+e);
}
}

}

helloclient.java

import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;
public class helloclient {
public static void main(String[] args) {
new helloclient().dbCheck();
}
public void dbCheck(){
try {
Resource res = new ClassPathResource("hello.xml");
BeanFactory factory = new XmlBeanFactory(res);
DB2 bean1 = (DB2)factory.getBean("db2");
bean1.connection();
} catch(Exception e1){ System.out.println(""+e1); } }
}

After run helloclient.java, you will get the output like this

CONNECTION USING SPRING
ID :: 110 USERNAME :: Binod PASSWORD ::Binod
ID :: 120 USERNAME :: Pramod PASSWORD ::Pramod

How to use the Properties file in Spring
1. Employee.java
2. emp.properties
3. helloConfig.xml
4. helloClient.java
5. Add two jar file in project (spring-2.0.6.jar, commons-logging.jar)

Employee.java

public class Employee {
private String name;
private String com;
public String getCom() { return com; }
public void setCom(String com) { this.com = com; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public void show(){
System.out.println("Employee Name :: "+name);
System.out.println("Company Name :: "+com);
}

}

emp.properties
name=Binod Kumar Suman
company=Satyam Computer Service Ltd

helloConfig.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "https://imailhyd.satyam.com/OWA/redir.aspx?C=1701758999134b0eb8caa391006ac45b&URL=http%3a%2f%2fwww.springframework.org%2fdtd%2fspring-beans.dtd">
<beans>
<beanid="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="location" value="emp.properties" />

</bean>
<bean id="employee" class="Employee">
<property name="name" value="${name}"/>
<property name="com" value="${company}"/>
</bean>

</beans>


helloClient.java
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class helloclient {
public static void main(String[] args) {
new helloclient().check();
}
public void check() {
try {
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("helloConfig.xml");
BeanFactory factory = (BeanFactory) appContext;
//Resource res = new ClassPathResource("helloConfig.xml");
//BeanFactory factory = new XmlBeanFactory(res);
Employee bean1 = (Employee) factory.getBean("employee");
bean1.show();
} catch (Exception e1) { System.out.println("" + e1); }
}
}

NOTE: Properties file DOES NOT WORK with ClassPathResource. You have to use ClassPathXmlApplicationContext.As I have commented the not working code.
No need to define any where bean id="propertyPlaceholder". ${} will take automatically data from properties file.

Run the helloClient.java, you will get output
Employee Name :: Binod Kumar Suman
Company Name :: Satyam Computer Service Ltd

How to use two different properties file in Spring
(How to use two propertyPlaceholder)

When you will use two properties file then only first one will load, and will give the run time error that other properties file property not found.

I am adding one more bean class to the previos example
Company.java
public class Company {
private String name;
private String city;
private String country;
public void show(){
System.out.println("Company Name :: "+name);
System.out.println("City :: "+city);
System.out.println("Country :: "+country);
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

com.properties
cname=Satyam Computer
city=Bangalore
county=India


helloConfig.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "https://imailhyd.satyam.com/OWA/redir.aspx?C=1701758999134b0eb8caa391006ac45b&URL=http%3a%2f%2fwww.springframework.org%2fdtd%2fspring-beans.dtd"><beans><bean id="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="emp.properties" />

</bean>
<bean id="propertyPlaceholder_Company"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="com.properties" />
</bean>

<bean id="employee" class="Employee">
<property name="name" value="${name}"/>
<property name="com" value="${company}"/>
</bean>

<bean id="company" class="Company">
<property name="name" value="${cname}"/>
<property name="city" value="${city}"/>
<property name="country" value="${country}"/>
</bean>

</beans>

NOTE: Give two bean id for both propertyPlaceholder.
But it will error
Error registering bean with name 'company' defined in class path resource [helloConfig.xml]: Could not resolve placeholder 'cname'

Because only first properties got load during run time.

SOLUTION: We can user different placeholder syntax for different property file. PropertyPlaceholderConfigurer's "placeholderPrefix" and "placeholderSuffix" settings use for that how to retrieve the data from properties file. By default is ${}. For example, one configurer can use ${...} and another one can have resolve #{...}

Now correct helloConfig.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" http://www.springframework.org/dtd/spring-beans.dtd>

<beans>
<bean id="propertyPlaceholder"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="proper/emp.properties" />
</bean>

<bean id="propertyPlaceholder_Company"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="proper/com.properties" />
<property name="placeholderPrefix" value="#{"/>
<property name="placeholderSuffix" value="}"/>
</bean>

<bean id="employee" class="Employee">
<property name="name" value="${name}"/>
<property name="com" value="${company}"/>
</bean>

<bean id="company" class="Company">
<property name="name" value="#{cname}"/>
<property name="city" value="#{city}"/>
<property name="country" value="#{country}"/>
</bean>

</beans>

Now run the helloClient.java
You will output from both properties file

Employee Name :: Binod Kumar Suman
Company Name :: Satyam Computer Service Ltd
Company Name :: Satyam Computer
City :: Bangalore
Country :: India

Loading Application properties from a database



I am using DB2 database, so need a lot of jar file for DB2 JDBC driver (db2jcc.jar, db2jcc_licence_cu.jar, db2jcc_licnece_cisuz.jar) and other jar files (spring-2.0.6.jar, commons-collectins-3.1.jar, commons-configuration-1.4.jar,spring-modules-jakarta-commons-0.6.zip, commons-lang-2.2.jar)

1. ImageStatus.java
2. hello.xml
3. Client.java
4. Create one table (Image_status_mstr) in database

Image_status_mstr Table Structure

sqltype sqllen sqlname.data sqlname.length -------------------- ------ ------------------------------ --------------
INTEGER 4 STAT_CODE_I
VARCHAR 50 STAT_N

insert into Image_status_mstr values(1,'Validated');
insert into Image_status_mstr values(2,'NonValidated');
insert into Image_status_mstr values(3,'ReadyToPublish');
insert into Image_status_mstr values(4,'Published');

ImageStatus.java

public class ImageStatus {
private String val;
private String nonVal;
private String ready;
private String pub;
public String getNonVal() {
return nonVal;
}
public void setNonVal(String nonVal) {
this.nonVal = nonVal;
}
public String getPub() {
return pub;
}
public void setPub(String pub) {
this.pub = pub;
}
public String getReady() {
return ready;
}
public void setReady(String ready) {
this.ready = ready;
}
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
public void displayAllProperties() {
System.out.println("val :: " + this.val);
System.out.println("nonVal :: " + this.nonVal);
System.out.println("ready :: " + this.ready);
System.out.println("pub :: "+pub);
}
}

hello.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "https://imailhyd.satyam.com/OWA/redir.aspx?C=1701758999134b0eb8caa391006ac45b&URL=http%3a%2f%2fwww.springframework.org%2fdtd%2fspring-beans.dtd">
<beans>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver"/>
<property name="url" value="jdbc:db2://localhost:2001/Suamn_DB2"/>
<property name="username">
<value>binod_db2</value>
</property>
<property name="password">
<value>suman_db2</value>
</property></bean>
<bean name="PropertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="properties" ref="CommonsConfigurationFactoryBean"/>
</bean>
<bean name="CommonsConfigurationFactoryBean" class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean"> <property name="configurations" ref="DatabaseConfiguration"/>
</bean>
<bean name="DatabaseConfiguration" class="org.apache.commons.configuration.DatabaseConfiguration">
<constructor-arg type="javax.sql.DataSource" ref="dataSource"/>
<constructor-arg index="1" value="Image_status_mstr"/>
<constructor-arg index="2" value="STAT_CODE_I"/>
<constructor-arg index="3" value="STAT_N"/>
</bean>

<bean name="imageStatus" class="ImageStatus"> <property name="val" value="${1}"/>
<property name="nonVal" value="${2}"/>
<property name="ready" value="${3}"/>
<property name="pub" value="${4}"/>
</bean>

</beans>

Client.java

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Client { public static void main(String[] args) {
new Client().propertyCheck();
}
public void propertyCheck() {
try {
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("hello.xml");
BeanFactory factory = (BeanFactory) appContext;
//Resource res = new ClassPathResource("hello.xml");
//BeanFactory factory = new XmlBeanFactory(res);
ImageStatus imageStatus = (ImageStatus) factory.getBean("imageStatus"); imageStatus.displayAllProperties();
} catch (Exception e1) {
System.out.println("" + e1);
}
}
}

Run Client.java, Output would be

val :: Validated
nonVal :: NonValidated
ready :: ReadyToPublish
pub :: Published

Now we will see that how we can use two master table and two bean to load the data.

1. Create one table and bean
Table : ImageTypeMaster
INTEGER IMG_TYPE_I
VARCHAR 30 IMG_TYPE_N

insert into ImageTypeMaster values(1,'Front Cover');
insert into ImageTypeMaster values(2,'Back Cover');
insert into ImageTypeMaster values(3,'PT01');
insert into ImageTypeMaster values(4,'PT02');
insert into ImageTypeMaster values(5,'PT03');
insert into ImageTypeMaster values(6,'PT04');
insert into ImageTypeMaster values(12,'SS');

Bean ImageType.java

public class ImageType {
private String main;
private String backCover;
private String p1;
private String p2;
private String p3;
private String p4;
private String p5;
private String p6;
private String s;
public String getBackCover() {
return backCover;
}
public void setBackCover(String backCover) {
this.backCover = backCover;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getP1() {
return p1;
}
public void setP1(String p1) {
this.p1 = p1;
}
public String getP2() {
return p2;
}
public void setP2(String p2) {
this.p2 = p2;
}
public String getP3() {
return p3;
}
public void setP3(String p3) {
this.p3 = p3;
}
public String getP4() {
return p4;
}
public void setP4(String p4) {
this.p4 = p4;
}
public String getP5() {
return p5;
}
public void setP5(String p5) {
this.p5 = p5;
}
public String getP6() {
return p6;
}
public void setP6(String p6) {
this.p6 = p6;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}

public void show(){
System.out.println("main :: "+main);
System.out.println("backCover :: "+backCover);
System.out.println("p1 :: "+p1);
System.out.println("p2 :: "+p2);
System.out.println("p3 :: "+p3);
System.out.println("p4 :: "+p4);
System.out.println("p5 :: "+p5);
System.out.println("p6 :: "+p6);
System.out.println("s :: "+s);
}
}

hello.xml (After made change)
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "https://imailhyd.satyam.com/OWA/redir.aspx?C=1701758999134b0eb8caa391006ac45b&URL=http%3a%2f%2fwww.springframework.org%2fdtd%2fspring-beans.dtd>

<beans>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver"/>
<property name="url" value="jdbc:db2://localhost:2001/Suamn_DB2"/>
<property name="username"> <value>binod_db2</value>
</property>
<property name="password">
<value>suman_db2</value>
</property></bean>
<bean name="PropertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="properties" ref="CommonsConfigurationFactoryBean"/>
</bean>
<bean name="CommonsConfigurationFactoryBean" class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean"> <property name="configurations" ref="DatabaseConfiguration"/>

</bean>
<bean name="DatabaseConfiguration" class="org.apache.commons.configuration.DatabaseConfiguration">
<constructor-arg type="javax.sql.DataSource" ref="dataSource"/>
<constructor-arg index="1" value="Image_status_mstr"/>
<constructor-arg index="2" value="STAT_CODE_I"/>
<constructor-arg index="3" value="STAT_N"/>
</bean>

<bean name="imageStatus" class="ImageStatus">
<property name="val" value="${1}"/>
<property name="nonVal" value="${2}"/>
<property name="ready" value="${3}"/>
<property name="pub" value="${4}"/>
</bean>

<!-- Adding code for add one more master database table and respective bean class -->

<bean name="PropertyPlaceholderConfigurerForImageType" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="properties" ref="CommonsConfigurationFactoryBeanForImageType"/> <property name="placeholderPrefix" value="#{"/>
<property name="placeholderSuffix" value="}"/>
</bean>
<bean name="CommonsConfigurationFactoryBeanForImageType" class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean"> <property name="configurations" ref="DatabaseConfigurationForImageType"/>
</bean>
<bean name="DatabaseConfigurationForImageType" class="org.apache.commons.configuration.DatabaseConfiguration">
<constructor-arg type="javax.sql.DataSource" ref="dataSource"/>
<constructor-arg index="1" value="ImageTypeMaster"/>
<constructor-arg index="2" value="IMG_TYPE_I"/>
<constructor-arg index="3" value="IMG_TYPE_N"/>
</bean>
<bean name="imageType" class="ImageType">
<property name="main" value="#{1}"/>
<property name="backCover" value="#{2}"/>
<property name="p1" value="#{3}"/>
<property name="p2" value="#{4}"/>
<property name="p3" value="#{5}"/>
<property name="p4" value="#{6}"/>
<property name="p5" value="#{7}"/>
<property name="p6" value="#{8}"/>
<property name="s" value="#{12}"/>
</bean>

</beans>

NOTE 1: When have to add more than one propertyPlaceholder then have to set different prefix and suffix for resolvoer. Thats why I have used # in second propertyPlaceholder.

NOTE2 :
<bean name="CommonsConfigurationFactoryBean" class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean"> <property name="configurations" ref="DatabaseConfiguration"/>
</bean>

I have seen in many blog or link that this bean (CommonsConfigurationFactoryBean) has <constructor-arg ref="DatabaseConfiguration"/>,
but it is not woking.

Change in Client.java

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Client {
public static void main(String[] args) {
new Client().propertyCheck();
}
public void propertyCheck() {
try {
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("hello.xml");
BeanFactory factory = (BeanFactory) appContext;
//Resource res = new ClassPathResource("hello.xml");
//BeanFactory factory = new XmlBeanFactory(res);
ImageStatus imageStatus = (ImageStatus) factory.getBean("imageStatus"); imageStatus.displayAllProperties();
ImageType it = (ImageType) factory.getBean("imageType");
it.show();
} catch (Exception e1) { System.out.println("" + e1); }
}
}

Run Cleint.java, output would be
val :: Validated
nonVal :: NonValidated
ready :: ReadyToPublish
pub :: Published
main :: Front Cover
backCover :: Back Cover
p1 :: PT01
p2 :: PT02
p3 :: PT03
p4 :: PT04
p5 :: PT05
p6 :: PT06
s :: SS




4 comments:

  1. Yadnesh, if you any problem during exceute any spring example. Please let me know.

    ReplyDelete
    Replies
    1. Hi Binod,

      I am getting following error while executing your loading application preperties from database:

      Caused by: java.lang.ClassNotFoundException: org.springmodules.commons.configuration.CommonsConfigurationFactoryBean

      Eventhough i have added all dependency in pom.xml and i have all required jars.

      Delete
  2. hi suman
    Your program is so easy to execute.
    thanks for simple and useful program .
    please give an example of spring with struts and hibernate integration.

    ReplyDelete
  3. put an example for Spring MVC Development.
    Thanks.

    ReplyDelete

You can put your comments here (Either feedback or your Question related to blog)