Sei sulla pagina 1di 88

1 POTHURAI

Spring
The frame works are the software that are designed & developed by the developers with good experience. A frame work designer designs the frame work using a good architecture (struts, Spring MVC etc) are designed using Model View Controller architectures/design pattern. A frame work provides a procedure for doing various tasks & the frame work contains the code that is commonly required as part of our projects. The frame work simplifies the development of the projects. Most of the developers are using the frame works the development of medium to large scale projects. We can download spring related from www.springframework.org. springframework-2.0.6-with-dependencies.zip contains all the files that are required for the development of an application using spring.

The above diagram shows various modules that are part of spring. DAO : - Data access object. JMX : - Java management extension. AOP : - Aspect oriented programming. IOC : - Inversion of control. The frameworks like struts, web work can be used for the development of the web application only. But we can use spring for the development of different types of applications like a GUI application, a web application, Applet, EJB application. As part of Core module spring container is provided. The spring container is also called as IOC (Inversion of control) container. org.springframework.beans.factory.BeanFactory . SUDHEER REDDY getBean(..) isSingleton(..)

2 POTHURAI

implements org.springframework.beans.factory.xml.XmlBeanFactory A spring container is a java object that provides a implementation of the BeanFactory interface. .. BeanFactory sprCont=new XmlBeanFactory(..); sprCont This object is the spring container

XmlBeanFactory (BeanFactory) obj. The spring container is responsible for creating the java objects (spring bean objects) & responsible for holding the java objects. Procedure for creating a spring based application: 1) Choose file new Java project.

2) In new java project window provide project name (sprproj) & click on finish button.

3) Choose file new package

SUDHEER REDDY

3 POTHURAI

4) In new java package window provide the name (org.students) & click on finish button.

5) In package explorer view choose sprproj & choose MyEclipse add spring capabilities.

6) In add spring capability window check MyEclipse libraries, user libraries. Check all the libraries except spring 1.2 ORM/DAO/Hibernate2 libraries & spring 2.0 web libraries.

7) Choose copy checked library contents to project folder & click on the browse button.

SUDHEER REDDY

4 POTHURAI

8) In folder selection window select sprproj & click on create new folder button

9) In new folder window provide the folder name (lib) & click on the ok button

10) In folder selection window click on ok button

SUDHEER REDDY

5 POTHURAI

11) In add spring capabilities window click on the next button.

12) Click on the finish button.

Note: - MyEclipse creates the following directories and create applicationContext.xml file. sprproj SUDHEER REDDY

6 POTHURAI

bin applicationContext.xml org students

src applicationContext.xml org students

lib Spring related jar files Procedure for creating a java bean & adding the information about the java bean to applicationContext.xml : 1) Choose file new class

2) In new java class window provide the package (org.students), name (Address) & click on finish button.

SUDHEER REDDY

7 POTHURAI

3) Provide the code to declare the instance variables in Address.java package org.students; public class Address { private String street; private String city; private String state; } } 4) Place the cursor after the instance variables, right click to get the pop up menu & choose source generates getters and setters.

5) In generate getters & setters window click on select all button & click on ok button.

SUDHEER REDDY

8 POTHURAI Note : - The tool adds the getters & setters to Address.java package org.students; public class Address { private String street; private String city; private String state; public String getCity( ) { return city; } public void setCity(String city) { System.out.println("--setCity--"+city); this.city = city; } public String getState( ) { return state; } public void setState(String state) { System.out.println("--setState--"+state); this.state = state; } public String getStreet( ) { return street; } public void setStreet(String street) { System.out.println("--setStreet--"+street); this.street = street; } } 6) Choose window show view other

SUDHEER REDDY

9 POTHURAI 7) In show view window choose MyEclipse enterprise workbench spring beans & click on ok button.

8) In the spring beans view select sprproj src/applicationContext.xml & right click to get a pop up menu & choose Bean

9) In bean wizard provide bean id (addr), Bean class (org.students.Address) Note: - instead of directly typing the Bean class & click on the browse button available in Bean wizard window & choose org.students.address.

SUDHEER REDDY

10 POTHURAI 10) In bean wizard choose the properties tab & click on the add button

11) In property wizard provide name (street), choose value as spring type, provide value (Street One) & click on finish button.

Note : - Repeat the above 2 steps & add the information about city , state properties. 12) In the Bean wizard window click on the finish button.

SUDHEER REDDY

11 POTHURAI applicationContext.xml : <beans> <bean id="addr" class="org.students.Address" > <property name="street"> <value>Street One</value> </property> <property name="city"> <value>City One</value> </property> <property name="state"> <value>State One</value> </property> </bean> </beans>

package org.students; import org.springframework.core.io.*; import org.springframework.beans.factory.*; import org.springframework.beans.factory.xml.*; public class SprApp1 { public static void main(String[ ] args) throws Exception{ Resource res=new ClassPathResource("applicationContext.xml"); System.out.println("--creating spr cont--"); BeanFactory sprCont=new XmlBeanFactory(res); System.out.println("--Calling Bean--"); Object o=sprCont.getBean("addr"); SUDHEER REDDY

12 POTHURAI System.out.println("--Called Bean--"); org.students.Address ad=(org.students.Address)o; System.out.println(ad.getStreet( )); System.out.println(ad.getCity( )); System.out.println(ad.getState( )); } }

--creating spr cont---Calling Bean---setStreet--Street One --setCity--City One --setState--State One --Called Bean-Street One City One State One org.students.Address addr=new org.students.Address( ); 1 addr.setStreet(new String(xxx); 2 addr.setCity(new String(yyy); 3 addr.setStatet(new String(zzz); 4 1 A new Address object will be created.

2 When 2 is executed a String object with xxx will be created & is passed as a parameter to the method setStreet. The setStreet method stores the reference of the string object in the instance variable street. SUDHEER REDDY

13 POTHURAI

The Address object depends upon the String object with xxx (that is the Address object requires the sting object with xxx). By calling the setStreet method our code is providing the string object to the Address object. This process is called as dependency injection. When 3, 4 are executed the String objects with yyy & zzz are injected in to the Address object. xxx String Addr street yyy city String state String zzz Address The Address object depends upon 3 String objects. These 3 String objects are injected in to the Address object by calling the setters. This process is called as setter injection. org.students.Address addr=new org.students.Address(new String(aaa), new String(bbb), new String(ccc)); When the code shown above is executed an Address object will be created, 3 String objects will be created & the dependencies (String objects) are injected in to the Address object. In this case the dependencies are injected by using the constructor. This process is called as constructor injection. aaa street city state bbb String String

ccc String Address In the above 2 cases the Address object is connected with 3 String objects. Connecting object is called as writing the objects. In the above 2 cases we have provided the code that takes the responsibility of injecting the dependencies either by using the setter injection or by using the constructor injection. In this case the process of injecting the dependencies is controlled by our code has to take the responsibility by controlling dependency injection.

SUDHEER REDDY

14 POTHURAI Spring can take care of creating the objects & injecting the dependencies. That is spring can control the process of injecting the dependencies. Normally our code takes the responsibility of controlling the process of injecting the dependencies. But the spring container can control this process. The spring container taking the responsibility of injecting the dependencies is called as Inversion Of Control (IOC). The dependency injection that is supported by the spring container is called as Inversion Of Control & the spring container is called as IOC container. XmlBeanFactory implementing the BeanFactory interface is a basic spring container & it does not support the features like Aspect Oriented Programming (AOP). org.springframework.beans.factory.BeanFactory

extends org.springframework.context.ApplicationContext

implements org.springframework.context.support.ClassPathXmlApplicationContext

XmlWebApplicationContext provides the implementation of ApplicationContext interface. In case of a web application the object based on this class will be created automatically & this object will be used as a spring container. Spring container can create only one object based on a bean class. If it is specify scope=singleton (default value). package org.students; import org.springframework.core.io.*; import org.springframework.beans.factory.*; import org.springframework.beans.factory.xml.*; public class SprApp2 { public static void main(String[ ] args) throws Exception{ Resource res=new ClassPathResource("applicationContext.xml"); System.out.println("--creating spr cont--"); BeanFactory sprCont=new XmlBeanFactory(res); System.out.println("--calling Bean1--"); Object o1=sprCont.getBean("addr"); System.out.println("--Called Bean1--"); org.students.Address ad1=(org.students.Address)o1; SUDHEER REDDY

15 POTHURAI System.out.println(ad1.getStreet( )); System.out.println(ad1.getCity( )); System.out.println(ad1.getState( )); System.out.println("--Calling Bean2--"); Object o2=sprCont.getBean("addr"); System.out.println("--Called Bean2--"); org.students.Address ad2=(org.students.Address)o2; System.out.println(ad2.getStreet( )); System.out.println(ad2.getCity( )); System.out.println(ad2.getState( )); } } <beans> <bean id="addr" class="org.students.Address" scope="singleton" lazy-init="false"> ............. ............. </bean> </beans> SprApp2 Run As Java Application --creating spr cont---setStreet--Street One --setCity--City One --setState--State One --Calling Bean1---Called Bean1-Street One City One State One --Calling Bean2---Called Bean2-Street One City One State One When scope is set to singleton, the spring container can use one of the following strategies for creating the bean objects. 1) If lazy-init="false" is used then the spring container creates the bean object when the container is getting created. This is called as creating the bean object eagerly 2) If lazy-init="true" is used then the spring container will not crate the bean object eagerly. In this case the container creates the bean object when the getBean( ) method is called for the first time. <beans> <bean id="addr" class="org.students.Address" scope="singleton" lazy-init="true"> ............. </bean> </beans> SprApp2 Run As Java Application SUDHEER REDDY

16 POTHURAI --creating spr cont---Calling Bean1 --setStreet--Street One --setCity--City One --setState--State One --Called Bean1-Street One City One State One --Calling Bean2---Called Bean2-Street One City One State One <beans> <bean id="addr" class="org.students.Address" scope="prototype"> ............. . </bean> </beans> SprApp2 Run As Java Application --creating spr cont---Calling Bean1 --setStreet--Street One --setCity--City One --setState--State One --Called Bean1-Street One City One State One --Calling Bean2 --setStreet--Street One --setCity--City One --setState--State One --Called Bean2-Street One City One State One The spring container creates multiple bean objects if we specify scope="prototype". If the getBean( ) method is called for 100 times then the spring container will create 100 bean objects. In case of a web application we can use the values like scope="request", scope="session". If we specify scope="session", the spring container crates a bean object if it is not available in session object. package org.students; SUDHEER REDDY

17 POTHURAI import org.springframework.context.*; import org.springframework.context.support.*; public class SprApp3 { public static void main(String[ ] args) throws Exception{ System.out.println("--creating spr cont--"); ApplicationContext sprCont=new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println("--Calling Bean--"); Object o=sprCont.getBean("addr"); System.out.println("--Called Bean--"); org.students.Address ad=(org.students.Address)o; System.out.println(ad.getStreet( )); System.out.println(ad.getCity( )); System.out.println(ad.getState( )); } } SprApp3 Run As Java Application --creating spr cont---Calling Bean---setStreet--Street One --setCity--City One --setState--State One --Called Bean-Street One City One State One Procedure for using constructor injection mechanism: 1) Remove the information about addr bean from applicationContext.xml. 2) Open the spring beans view 3) Select sprproj src/ applicationContext.xml in spring bean view, right click to get the popup menu & choose new bean 4) In bean wizard provide bean id (addr), click on the browse button & choose org.students.Address class. 5) In the constructor args tab click on the button pick constructor.

SUDHEER REDDY

18 POTHURAI 6) In new spring bean window choose the constructor with 3 arguments & click on the ok button.

7) Use the edit button for providing the values of the three arguments & click on ok button.

Note: - Before carrying out the above steps we must add a constructor that takes 3 parameters in the Address class. package org.students; public class Address { private String street; private String city; private String state; SUDHEER REDDY

19 POTHURAI public Address(String street, String city, String state) { System.out.println("-- Address (street, city, state) created --"); this.street=street; this.city=city; this.state=state; } public String getCity( ) { return city; } public void setCity(String city) { System.out.println("--setCity--"+city); this.city = city; } public String getState( ) { return state; } public void setState(String state) { System.out.println("--setState--"+state); this.state = state; } public String getStreet( ) { return street; } public void setStreet(String street) { System.out.println("--setStreet--"+street); this.street = street; } } The information shown below will be added to applicationContext.xml by MyEclipse IDE. <beans> <bean id="addr" class="org.students.Address" abstract="false" lazy-init="default" autowire="default" dependency-check="default"> <constructor-arg index="0" type="java.lang.String"> <value>Street One</value> </constructor-arg> <constructor-arg index="1" type="java.lang.String"> <value>City One</value> </constructor-arg> <constructor-arg index="2" type="java.lang.String"> <value>State One</value> </constructor-arg> </bean> </beans>

SUDHEER REDDY

20 POTHURAI SprApp1 Run As Java Application --creating spr cont---Calling Bean--- Address (street, city, state) created ---Called Bean-Street One City One State One If we specify the index & the type attribute in the constructor-arg tag there will be no confusion regarding which constructor has to be used for creating the object. Ex: <constructor-arg index="0" type="int"> <value> 10 </value> </constructor-arg> <constructor-arg index="1" type="java.lang.String"> <value> 10 </value> </constructor-arg> name fatherName addr street city state

Student Address package org.students; public class Student { private String name; private String fatherName; private org.students.Address addr; public String getName( ) { return name; } public void setName(String name) { System.out.println("--setName--"+name); this.name = name; } public String getFatherName( ) { return fatherName; } public void setFatherName(String fatherName) { System.out.println("--setFatherName--"+fatherName); this.fatherName = fatherName; } public org.students.Address getAddr( ) { return addr; SUDHEER REDDY

21 POTHURAI } public void setAddr(org.students.Address addr) { this.addr = addr; } } <beans> <bean id="xxxx" class="org.students.Address"> <property name="street"> <value>Street One</value> </property> <property name="city"> <value>City One</value> </property> <property name="state"> <value>State One</value> </property> </bean> <bean id="stud" class="org.students.Student"> <property name="name"> <value>SName</value> </property> <property name="fatherName"> <value>FName</value> </property> <property name="addr"> <ref bean="xxxx"></ref> </property> </bean> </beans> package org.students; import org.springframework.context.*; import org.springframework.context.support.*; public class SprApp4 { public static void main(String[ ] args) throws Exception{ System.out.println("--creating spr cont--"); ApplicationContext sprCont=new ClassPathXmlApplicationContext ("applicationContext.xml"); System.out.println("--Calling Bean--"); Object o=sprCont.getBean("stud"); System.out.println("--Called Bean--"); org.students.Student ad=(org.students.Student)o; System.out.println(ad.getName( )); System.out.println(ad.getFatherName( )); System.out.println(ad.getAddr( ).getStreet( )); System.out.println(ad.getAddr( ).getCity( )); SUDHEER REDDY

22 POTHURAI System.out.println(ad.getAddr( ).getState( )); } } SprApp4 Run As Java Application --creating spr cont---setStreet--Street One --setCity--City One --setState--State One --setName--SName --setFatherName--FName --Calling Bean---Called Bean-SName FName Street One City One SName State One FNam e street city state Address

Street One City One

name fatherName addr Student

State One

With the above configuration, the spring container creates various objects & sets the dependencies as shown above. A diagram that represents various objects & the links between different objects is called as a object graph. Spring container supports auto writing feature. When this feature is used spring will establish the connections between the objects using the data type of the property, the name of the property etc but some times auto writing leads to confusion & the spring container will fail to establish the links between various objects. <beans> <bean id="xxxx" class="org.students.Address"> ............ </bean> <bean id="stud" class="org.students.Student" autowire="byType" > <property name="name"> <value>SName</value> </property> <property name="fatherName"> <value>FName</value> </property> </bean> </beans> SUDHEER REDDY

23 POTHURAI SprApp4 Run As Java Application --creating spr cont---setStreet--Street One --setCity--City One --setState--State One --setName--SName --setFatherName--FName --Calling Bean---Called Bean-SName FName Street One City One State One As part of the bean class we can provide the init methods & destroy methods. The spring container executes the init( ) method when the object is created (after calling the setters). package org.students; public class Address { private String street; private String city; private String state; // getters & setters public void yyy( ){ System.out.println("--- yyy ---"); } } <beans> <bean id="xxxx" class="org.students.Address" init-method="yyy"> ............ </bean> <bean id="stud" class="org.students.Student" autowire="byType" > . </bean> </beans> SprApp4 Run As Java Application --creating spr cont---setStreet--Street One --setCity--City One --setState--State One --- yyy ----setName--SName --setFatherName--FName --Calling Bean---Called Bean-SUDHEER REDDY

24 POTHURAI SName FName Street One City One State One A set of connections is called as a connection pool. A DataSource object is linked up with a connection pool. We can use DataSource.getConnection( ) method to get the connection from the connection pool.

JdbcTemplate

DataSource

As part of spring a class with the name JdbcTemplate is provided. The internal code of this class takes care of using DataSource.getConnection for getting the connection from the connection pool.

DataSource DB srv JdbcTemplat e

JVM Our spring based applications can use JDBC API for accessing the database. For this our application can use JdbcTemplate object. DBCP: - Data Base Connection Pool is a software provided by Apache. This software can be used for managing a connection pool as part of our application. As part of DBCP classes are provided implementing javax.sql.DataSource interface. For using DBCP as part of our application follow the steps given below: 1) Copy the following jar files (available in CD) under d:\eclws. commons-collections-3.2.jar, commons-dbcp-1.2.2.jar, commons-pool-1.3.jar, ojdbc14.jar.

SUDHEER REDDY

25 POTHURAI 2) Add the above 4 jar files to the build path of the project. a) Choose sprproj4 in the package explorer view and choose project properties

b) In properties for sprproj4 window choose Java Build Path & select the libraries tab

c) Click on Add External JARs & choose the 4 jar files listed above & cicck on OK button

Procedure for setting up the DataSource bean in applicationContext.xml: 1) Open spring bean view & select sprproj4 src/applicationContext.xml, right click to get the pop up menu & choose New DataSource

SUDHEER REDDY

26 POTHURAI

2) In the DataSource wizard provide OraDs as Bean Id & choose OraDrv as DB Driver

3) Click on the finish button. Note: - MyEclipse add the information shown below to applicationContext.xml <beans> <bean id="OraDs" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"> </property> <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"> </property> <property name="username" value="scott"> </property> <property name="password" value="tiger"> </property> </bean> </beans> The spring container uses the above information for creating a connection pool with connections, creating the DataSource object, setting up the link between the connection pool & the DataSource object. SUDHEER REDDY

27 POTHURAI Procedure for setting up the JdbcTemplate bean: 1) In the spring beans view select sprproj4 src/applicationContext.xml 2) Right click to get the pop up menu & choose new Bean 3) In bean wizard provide JdbcTem as Bean Id. 4) Click on the browse button & choose org.springframework.jdbc.core.JdbcTemplate as the Bean Class 5) Select the properties tab & click on the add button. 6) In the properties wizard provide DataSource as Name, ref as Spring type, OraDs as a reference & click on the finish button.

7) Click on the finish button in the Bean Wizard window.

Note: - The information shown below will be added to applicationContext.xml <beans> <bean id="OraDs" class="org.apache.commons.dbcp.BasicDataSource"> . </bean> <bean id="JdbcTem" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"> <ref bean="OraDs"></ref> </property> </bean> </beans> SUDHEER REDDY

28 POTHURAI The spring container uses the above information for creating the JdbcTemplate object & setting up the link with the DataSource object. SQL> create table student(sid number(9) primary key, sname varchar(20),age number(3), fname varchar(20)); Table created. SQL> select * from student; no rows selected As part of our spring based application we can use JDBC API for dealing with the database. For this we can use JdbcTemplate object. package org.students; import org.springframework.context.*; import org.springframework.context.support.*; import org.springframework.jdbc.core.*; public class SprApp1 { public static void main(String[ ] args) throws Exception{ ApplicationContext sprCont=new ClassPathXmlApplicationContext ("applicationContext.xml"); JdbcTemplate jt=(JdbcTemplate)sprCont.getBean("JdbcTem"); String vsql="insert into student values (1,'sone',24,'fone')"; jt.execute(vsql); } } The execute method on JdbcTemplate can be used for executing non select statements. SprApp1 Run As Java Application SQL> select * from student; SID SNAME AGE FNAME ---------- -------------------- ---------- -------------------1 sone 24 fone Spring team has used the template design pattern. The designing classes like JdbcTemplate, HibernateTemp;ate, TopLink etc.. ----------- - - - -Spring code -------------------------- - - - -Spring Code ---------------JdbcTemplate SUDHEER REDDY ************ ************ OurCode ************ ************ OurCls

29 POTHURAI As part of the JdbcTemplate the standard code (the code that is required commonly in almost all the applications) is provided. We need to provide our code to take care of the other issues & attach our code to the code in the JdbcTemplate, while the application is running our code will be executed along with JdbcTemplate code. 1) Code to get the connection from CP 2) Code to create the statement object. 3) Code to call executeQuery for executing the select statement & create the ResultSet object 4) Code to use the data available in the ResultSet 5) Code to return the connection to CP ResultSet extractor: -ResultSet extractor is an interface with the method extractData( ). The internal code of spring takes care of calling the extractData( ) method. package org.students; import java.sql.*; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.ResultSetExtractor; public class OurCls implements ResultSetExtractor { public Object extractData(ResultSet rs) throws SQLException,DataAccessException { System.out.println("--Start our code in OurCls--"); while(rs.next( )){ System.out.print(rs.getString("sid")+"\t"); System.out.print(rs.getString("sname")+"\t"); System.out.print(rs.getString("age")+"\t"); System.out.println(rs.getString("fname")); } System.out.println("--End our code in OurCls--"); return null; } } package org.students; import org.springframework.context.*; import org.springframework.context.support.*; import org.springframework.jdbc.core.*; public class SprApp { public static void main(String[ ] args) { ApplicationContext sprCont=new ClassPathXmlApplicationContext ("applicationContext.xml"); JdbcTemplate jt=(JdbcTemplate)sprCont.getBean("JdbcTem"); SUDHEER REDDY

Standard code as part JdbcTemplate Our code in OurCls

30 POTHURAI String vsql="select * from student"; System.out.println("--Calling query--"); jt.query(vsql, new OurCls( )); System.out.println("--Called query--"); } } SprApp Run As Java Application --Calling query---Start our code in OurCls-1 sone 24 fone --End our code in OurCls---Called query Note: - When our code calls the query method of JdbcTemplate, the spring code that is part of JdbcTemplate executes the select statement & extractData( ) method of OurCls will be called the process of spring code calling our method is called as call back mechanism. HibernateTemplate class contains the standard code for dealing with the databases using Hibernate. The standard code takes care of creating a Configuration object, creating a SessionFactory object, creating a Session object creating a Query object etc... SessionFactory Interface provided as part of Hibernate

implements LocalSessionFactoryBean Class provided as part of spring In order to deal with database using Hibernate from a spring based application, HibernateTemplate object is required. SessionFactory DataSource

HibernateTemplate Connection pool HibernateTemplate obj requires (depends on) the SessionFactory obj & the SessionFactroy requires the DataSource obj. SUDHEER REDDY

31 POTHURAI Procedure for creating a spring application with Hibernate: Step 1) Copy the following 4 jar files eclws directory commons-collections-3.2.jar, commons-dbcp-1.2.2.jar, commons-pool-1.3.jar, ojdbc14.jar. 2) Create a directory (D:\Pskr\eclws\sprlibs) 3) Copy the spring related jar files (provided as part of spring-framework-2.0.6-withdependencies.zip) to sprlibs directory. 4) Remove hibernate2.jar from sprlibs directory. 5) Create a project using file new Java Project Menu option (sprproj) 6) Choose the project in package explorer & choose project properties 7) Select Java Build Path & Choose the libraries tab. 8) Click on add External jars & choose the jar files available in eclws. 9) Again click on external jar button & choose all the jar files that are part of sprlibs directory & click on the ok button.

10) Create a package with the name org.students. 11) Select the project in the package explorer & choose MyEclipse Add Spring capabilities. 12) In Add Spring capabilities window uncheck the 2 check boxes & click on the finish button.

SUDHEER REDDY

32 POTHURAI 13) Choose MyEclipse Add Hibernate capabilities. 14) In new Hibernate capabilities window uncheck the check boxes & click on the next button

15) Choose Spring configuration file radio button & click on the next button.

16) Choose existing Spring configuration file radio button & provide SFBean as SessionFactory ID & click on next button

SUDHEER REDDY

33 POTHURAI 17) Provide OraSF as Bean Id, choose OraDrv as DB Driver & Click on next button.

18) Uncheck create SessionFactory class check box & click on finish button.

Note: - MyEclipse IDE adds the information about the DataSource bean & the SessionFactory bean to applicationContext.xml <beans> <bean id="OraSF" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"> </property> <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"> </property> <property name="username" value="scott"></property> <property name="password" value="tiger"></property> </bean> <bean id="SFBean" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="OraSF"></ref> SUDHEER REDDY

34 POTHURAI </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.Oracle9Dialect </prop> </props> </property> </bean> </beans> Add the information about HibernateTemplate bean : A) Choose Spring Bean view & select applicationContext.xml, right click to get the popup menu & choose New Bean. B) In the Bean Wizard window provide HibTem as the Bean Id

C) Click on the browse button & choose

D) Select the properties tab click on the add button & provide sessionFactory as a Name, select ref as Spring type, provide SFBean as a reference in the property wizard window & click on the finish button. SUDHEER REDDY

35 POTHURAI

E) In the Bean wizard window click on the finish button. Add scope="prototype" for the bean with the Id HibTem <beans> <bean id="OraSF" class="org.apache.commons.dbcp.BasicDataSource"> .......... </bean> <bean id="SFBean" .......... </bean> <bean id="HibTem" class="org.springframework.orm.hibernate3. HibernateTemplate" scope="prototype"> <property name="sessionFactory"> <ref bean="SFBean"></ref> </property> </bean> </beans> Genarate the hbm files, the POJO classes using MyEclipse DataBase prospective.

SUDHEER REDDY

36 POTHURAI

SQL> select * from student; no rows selected package org.students; import org.springframework.context.*; import org.springframework.context.support.*; import org.springframework.orm.hibernate3.*; public class SprApp { public static void main(String[ ] args)throws Exception { ApplicationContext sprCont=new ClassPathXmlApplicationContext ("applicationContext.xml"); HibernateTemplate ht=(HibernateTemplate)sprCont.getBean ("HibTem"); org.students.Student stud=new org.students.Student( ); stud.setSid(new Long(1)); stud.setAge(new Long(21)); stud.setSname("SOne"); stud.setFname("FOne"); ht.save(stud); } } SUDHEER REDDY

37 POTHURAI SprApp Run As Java Application SQL> select * from student; SID SNAME AGE FNAME ---------- -------------------- ---------- -------------------1 SOne 21 FOne The internal code HibernateTemplate uses the SessionFactory, Session, Query etc objects that are related to Hibernate to perform the database operations. package org.students; import org.springframework.context.*; import org.springframework.context.support.*; import org.springframework.orm.hibernate3.*; public class SprApp1 { public static void main(String[ ] args)throws Exception { ApplicationContext sprCont=new ClassPathXmlApplicationContext ("applicationContext.xml"); HibernateTemplate ht=(HibernateTemplate)sprCont.getBean ("HibTem"); org.students.Student stud=new org.students.Student( ); ht.load(stud, new Long(1)); System.out.println(stud.getSid( )); System.out.println(stud.getSname( )); System.out.println(stud.getFname( )); System.out.print(stud.getAge( )); } } SprApp1 Run As Java Application 1 SOne 21 FOne package org.students; import org.springframework.context.*; import org.springframework.context.support.*; import org.springframework.orm.hibernate3.*; public class SprApp2 { public static void main(String[ ] args)throws Exception { ApplicationContext sprCont=new ClassPathXmlApplicationContext ("applicationContext.xml"); HibernateTemplate ht=(HibernateTemplate)sprCont.getBean ("HibTem"); String vhql="from org.students.Student"; java.util.List slist=ht.find(vhql); for(int i=0;i<slist.size( );i++){ Object o=slist.get(i); SUDHEER REDDY

38 POTHURAI org.students.Student stud=(org.students.Student)o; System.out.println(stud.getSname( )); System.out.println(stud.getFname( )); } } } SprApp2 Run As Java Application SOne FOne package org.students; import org.springframework.context.*; import org.springframework.context.support.*; import org.springframework.orm.hibernate3.*; public class SprApp3 { public static void main(String[ ] args)throws Exception { ApplicationContext sprCont=new ClassPathXmlApplicationContext ("applicationContext.xml"); HibernateTemplate ht=(HibernateTemplate)sprCont.getBean ("HibTem"); org.students.Student stud=new org.students.Student( ); ht.load(stud, new Long(1)); ht.delete(stud); } } SprApp3 Run As Java Application SQL> select * from student; no rows selected We can develop the web applications using the spring web module of the spring framework. As part of the web module of spring support is provided to use spring from the other frame works like struts, web work etc In the spring web module spring web MVC is provided. Using this we can develop the web applications. Procedure for creating a spring based web project: 1) Choose File New Project 2) In the new project window select web project & click on the next button

SUDHEER REDDY

39 POTHURAI

3) In the new web project window provide the project name (swproj), web root directory (swap), context root URL (/swap) & check add jstl libraries. chexk box & click on the finish button.

Note: - The following directories will be created & various files will be copied under these directories by MyEclipse swproj src swapp WEB-INF classes lib 4) Choose file new package SUDHEER REDDY

40 POTHURAI 5) A new java package provides org.students as name & click on finish button. 6) In the package explorer swap, right click to get the popup menu & choose new folder

7) Provide pages as folder name in new folder window & click on finish button.

8) Select swproj in the package explorer & choose MyEclipse add spring capabilities. 9) In add spring capabilities window select all check boxes except Hibernate2, select copy checked library radio button & click on finish button.

10) Copy applicationContext.xml file under WEB-INF directory. 11) Create a file with the name spring-servlet.xml (copy applicationContext.xml as springservlet.xml) to WEB-INF directory. 12) Provide the information about ContextLoaderListener in web.xml <web-app> SUDHEER REDDY

41 POTHURAI <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class> </listener> </web-app> 13) Provide the information about the DispatcherServlet in web.xml <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> 14) Add the information about the beans in spring-servlet.xml <beans> <bean id="jspViewResolver" class= "org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="prefix" value="/pages/" /> <property name="suffix" value=".jsp"/> </bean> <bean name="/hw.htm" class="org.students.HWController"> </bean> </beans> Note: - HWController must be provided us. package org.students; import javax.servlet.http.*; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; public class HWController extends AbstractController { public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("---HWController. handleRequestInternal---"); return null; } public HWController( ){ SUDHEER REDDY

42 POTHURAI System.out.println("---HWController created---"); } } Copy swapp under D:\Tomcat5.0\webapps\ directory http://localhost:8000/swapp/hw.htm ---HWController created-----HWController.handleRequestInternal--ServletContextListener (interface) contextInitialized(..) contextDestroyed(..) implements ContextLoaderListener (class) contextInitialized(..) { spring code} contextDestroyed(..) { .. } While starting spring based application web container performs the following tasks: 1) Web container reads web.xml 2) Web container creates ServletContext object. 3) Web container creates ContextLoaderListener & calls contextInitialized( ) method. 1 2 ServletContext web.xml contextInitialized(.. ){ spring code } ContextLoaderListener Web container The spring code available in ContextLoaderListener creates the spring container & this spring container reads the information available in applicationContext.xml & stores the spring container inside the ServletContext object.

ServletContext

spring container

SUDHEER REDDY

43 POTHURAI

applicationContext.xml Note: - The DispatcherServlet creates a spring container & this spring container reads the information available in the file spring-servlet.xml. When we start a spring based application 2 spring containers will be created. The 1st spring container reads the information available in applicationContext.xml & 2nd spring container reads the information from spring-servlet.xml.

applicationContext.xml

spring-servlet.xml

sprCont

sprCont

DispatcherServlet (*.htm) Web container (*.htm ) DispatcherServlet req /hw.htm

resp Browser /hw.htm HWController Web container The following steps will be carried out in the server when it receives the request for /hw.htm: SUDHEER REDDY

44 POTHURAI 1) Web container creates req, resp objects. 2) Web container starts the execution of the spring code available in the DispatcherServlet. Web container passes req, resp objects to DispatcherServlet 3) The spring code calls handleRequest( ) method on HWController object. 4) The JVM checks for handleRequest( ) in HWController & then in AbstractCommandController class. The JVM starts the execution of handleRequest( ) available in AbstractCommandController class & this method calls handleRequestInternal( ) method. 5) The JVM executes handleRequestInternal( ) method available in HWController. 6) As our code returns null the spring code stops processing the request. org.springframework.web.servlet.mvc.Controller (interface) .. handleRequest( .. ) implements org.springframework.web.servlet.mvc.AbstractController (class) .. handleRequest( .. ) { .. handleRequestInternal( .. ); Model AndView handleRequestInternal( .. ) { return null; } extends org.students.OurController handleRequestInternal( ..) { Our code } package org.students; import javax.servlet.http.*; import org.springframework.web.servlet.*; import org.springframework.web.servlet.mvc.*; public class HWController1 extends AbstractController { public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("---HWController1.handleRequestInternal---"); ModelAndView mav=new ModelAndView("xxx"); return mav; } public HWController1( ){ System.out.println("---HWController1 created---"); } } <bean name="/hw1.htm" class="org.students.HWController1"> </bean> <% System.out.println("--- executing xxx.jsp ---"); %> OP of xxx.jsp SUDHEER REDDY

45 POTHURAI http://localhost:8000/swapp/hw1.htm --- HWController1 created------HWController1.handleRequestInternal----- executing xxx.jsp --OP of xxx.jsp jspViewResolver: - The jspViewResolver Bean is responsible for adding the prefix & the suffix to the view name. If xxx is the view name then the jspViewResolver returns /pages/xxx.jsp. package org.students; import javax.servlet.http.*; import org.springframework.web.servlet.*; import org.springframework.web.servlet.mvc.*; public class HWController2 extends AbstractController { public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { String model=new String("Hellow Sudheer"); ModelAndView mav=new ModelAndView("yyy","mname",model); return mav; } } <bean name="/hw2.htm" class="org.students.HWController2"> </bean> <% System.out.println("--- executing yyy.jsp ---"); %> <%= request.getAttribute("mname") %> http://localhost:8000/swapp/hw2.htm --- executing yyy.jsp --Hellow Sudheer In spring we can use a java project as a model object. The model object contains the data that is used in generating the output send to the browser. yyy is the view name, mname is called as the name of the model & model is called as model object. (*.htm ) DispatcherServlet req mnam e resp /hw.htm HWController2 / pages/yyy.jsp . String Hello Sudheer /hw2.htm Content generated by yyy.jsp Browser

SUDHEER REDDY

46 POTHURAI

Web container The following steps will be carried out in the server when it receives the request for /hw2.htm: 1) Web container starts the execution of spring code available in DispatcherServlet. 2) Spring code executes HWController2 code. 3) HWController2 returns ModelAndView object. 4) The spring code stores the model object with mname as attribute name in request object. 5) The spring code uses jspViewResolver to get /pages/yyy.jsp. 6) Web container forwards the request to /pages/yyy.jsp. package org.students; import javax.servlet.http.*; import org.springframework.web.servlet.*; import org.springframework.web.servlet.mvc.*; public class HWController3 extends AbstractController { public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { java.util.HashMap hm=new java.util.HashMap( ); hm.put("mnone", "Sunil"); hm.put("mntwo", "Sudheer"); hm.put("mnthr", "Reddy"); ModelAndView mav=new ModelAndView("aaa",hm); return mav; } } <bean name="/hw3.htm" class="org.students.HWController3"> </bean> <% System.out.println("--- executing aaa.jsp ---"); %> <%= request.getAttribute("mnone") %> <br> <%= request.getAttribute("mntwo") %> <br> <%= request.getAttribute("mnthr") %> http://localhost:8000/swapp/hw3.htm --- executing aaa.jsp --Sunil Sudheer Reddy The spring code takes the objects stored in the HashMap & places those objects inside the request object. Sunil SUDHEER REDDY

47 POTHURAI
mnone mntwo mnthr

Sudheer Reddy

request Attribute keys/ names / scoped variables As part of JSP 2.0 version (released along with servlet 2.4), EL expressions can be used directly as part of the Template text. <% System.out.println("--- executing aaa.jsp ---"); %> ${requestScope.mnone} <br> ${requestScope.mntwo} <br> ${requestScope.mnthr} http://localhost:8000/swapp/hw3.htm --- executing aaa.jsp --Sunil Sudheer Reddy If <%@ page isELIgnored="true" %> is used in a JSP then the ELExpressions in the template text will be ignored. <% System.out.println("--- executing aaa.jsp ---"); %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <%@ page isELIgnored="true" %> <c:out value="${requestScope.mnone}"/> <br> <c:out value="${requestScope.mntwo}"/> <br> <c:out value="${requestScope.mnthr}"/> http://localhost:8000/swapp/hw3.htm --- executing aaa.jsp --Sunil Sudheer Reddy A view component is responsible for generating the output that is presented/ deployed by the browser & the user views the output. In the above application aaa.jsp acts as a view component. Generally JSPs are used as the view components. Instead of using the JSP we can use the view classes as view components. package org.students; import javax.servlet.http.*; import org.springframework.web.servlet.*; import org.springframework.web.servlet.mvc.*; SUDHEER REDDY

48 POTHURAI public class HWController4 extends AbstractController { public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { java.util.Vector model=new java.util.Vector( ); model.add("Emp One"); model.add("Emp Two"); model.add("Emp Three"); ModelAndView mav=new ModelAndView("bbb","elist",model); return mav; } } <bean name="/hw4.htm" class="org.students.HWController4"> </bean> <% System.out.println("--- executing bbb.jsp ---"); %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <%@ page isELIgnored="true" %> <c:forEach var="str" items="${requestScope.elist}"> <c:out value="${str}"/> <br> ........ <br> </c:forEach> http://localhost:8000/swapp/hw4.htm --- executing bbb.jsp --Emp One ........ Emp Two ........ Emp Three ........ org.springframework.web.servlet.View getContentType( ) render( ) implements org.springframework.web.servlet.view.document.AbstractPdfView class provided as part of spring extends OurPdfView Our class As spring an interface with the name org.springframework.web.servlet.View is provided. A class implementing this interface is called as a view class. SUDHEER REDDY

49 POTHURAI There are 2 methods in the View interface. 1) render ---- we must provide the code to generate the output in the render method. 2) getContentType ---- this method should return the content type that is generated by the render method. As part of spring several View classes are provided for simplifying the generation of Excel sheets, pdf documents etc . AbstractJExcelView simplifies the generation of Excel documents(sheets). AbstractPdfView simplifies the generation of the pdf documents. OurPdfView indirectly provides the implementation of the View interface. This class is called as a View class. package org.students; import java.util.Map; import javax.servlet.http.*; import org.springframework.web.servlet.view.document.*; import com.lowagie.text.Document; import com.lowagie.text.Chunk; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.PdfWriter; import java.awt.*; public class OurPdfView extends AbstractPdfView { public void buildPdfDocument(Map model, Document doc, PdfWriter pdfWriter,HttpServletRequest request, HttpServletResponse response) throws Exception { Chunk heading=new Chunk("List of Employees"); heading.setBackground(Color.yellow); heading.setUnderline(0.5f,-3f); doc.add(heading); Paragraph para=new Paragraph( ); java.util.Collection c=model.values( ); java.util.Iterator it=c.iterator( ); while(it.hasNext( )) { para.add(it.next( )); para.add("\r\n"); } doc.add(para); } } package org.students; import javax.servlet.http.*; import org.springframework.web.servlet.*; import org.springframework.web.servlet.mvc.*; public class PdfController extends AbstractController { public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { SUDHEER REDDY

50 POTHURAI java.util.Map hm=new java.util.HashMap( ); hm.put("OOne","Emp One"); hm.put("OTwo","Emp Two"); hm.put("OThr","Emp Three"); hm.put("OFour","Emp Four"); ModelAndView mav=new ModelAndView(new OurPdfView( ),hm); return mav; } } <bean name="/pdf.htm" class="org.students.PdfController"> </bean>

The internal code of handleRequest( ) method of AbstractController takes care of the following tasks. 1) Browser caching. 2) Decides whether a particular request method is supported or not. 3) Calls handleRequestInternal( ) method. package org.students; import javax.servlet.http.*; import org.springframework.web.servlet.*; import org.springframework.web.servlet.mvc.*; public class HWController5 extends AbstractController { public HWController5( ){ System.out.println("---HWController5---"); setCacheSeconds(0); 1 String smet[ ]=new String[1]; smet[0]="GET"; setSupportedMethods(smet); } public ModelAndView handleRequestInternal(HttpServletRequest request, SUDHEER REDDY

51 POTHURAI HttpServletResponse response) throws Exception { System.out.println("---handleRequestInternal---"); ModelAndView mav=new ModelAndView("xxx"); return mav; } } <bean name="/hw5.htm" class="org.students.HWController5"> </bean> http://localhost:8000/swapp/hw5.htm ---HWController5-----handleRequestInternal----- executing xxx.jsp --OP of xxx.jsp Tools Internet Options Settings View Files

1 setCacheSeconds(600); http://localhost:8000/swapp/hw5.htm ---HWController5-----handleRequestInternal----- executing xxx.jsp --OP of xxx.jsp Tools Internet Options Settings View Files

1 setCacheSeconds(-400); http://localhost:8000/swapp/hw5.htm ---HWController5-----handleRequestInternal----- executing xxx.jsp --OP of xxx.jsp Tools Internet Options Settings View Files

SUDHEER REDDY

52 POTHURAI

If 0 is CacheSeconds, the content will be not be cached by the browser. If a positive value like 600 is used then the browser will cache the content for 10 minits. If a negative value is used as a CacheSeconds then the expiry time of the content will not be set. User Name: Age: userName age

For capturing the data, command bean (nothing but java bean) in spring based application. BindException is used to represent the errors that are encounter during the bind process. Storing the data in the command bean object by calling the setters is called as binding the data to the command bean. AbstractController

implements BaseCommandController

extends AbstractCommandController

AbstractCommandController class is a sub class of AbstractController class. As part of AbstractCommandController a method with the name handleRequestInternal( ) method is provided. The internal code of this method takes care of calling handle method. In order to capture the data provided in the above form a command bean supporting username, age properties must be provided. package org.students; SUDHEER REDDY

53 POTHURAI public class CBOne { private String userName; private int age; public String getUserName( ) { return userName; } public void setUserName(String userName) { System.out.println("-- setUserName --"+userName); this.userName = userName; } public int getAge() { return age; } public void setAge(int age) { System.out.println("-- setAge --"+age); this.age = age; } public void CBOne( ){ System.out.println("-- CBOne created --"); } } <% System.out.println("-- form.jsp --"); %> <html> <head> <title> Form </title> </head> <body> <form action="hf.htm"> User Name <input type="text" name="userName"> <br> Age <input type="text" name="age"> <br> <input type="submit" value="Send Req"> <br> </form> </body> </html> When the form is submitted the browser sends the request for hf.htm & the web container executes the code of the DispatcherServlet. If we use the setting shown below the DispatcherServlet executes the code of org.students.FHController. <bean name="/hf.htm" class="org.students.FHController"> </bean> package org.students; import javax.servlet.http.*; import org.springframework.validation.*; import org.springframework.web.servlet.*; SUDHEER REDDY

54 POTHURAI import org.springframework.web.servlet.mvc.*; public class FHController extends AbstractCommandController { public FHController( ){ System.out.println("-- FHController created --"); setCommandName("cbname"); setCommandClass(org.students.CBOne.class); } public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object obj, BindException be) throws Exception { System.out.println("-- handle --"); org.students.CBOne ocb=(org.students.CBOne)obj; System.out.println(ocb.getUserName( )); System.out.println(ocb.getAge( )); System.out.println(be.getErrorCount( )); System.out.println(be.getAllErrors( )); ModelAndView mav=new ModelAndView ("dispinfo",getCommandName( ),ocb); return mav; } } <% System.out.println("-- dispinfo.jsp --"); %> OP of dispinfo.jsp <br> ${requestScope.cbname.userName} <br> ${requestScope.cbname.age} http://localhost:8000/swapp/form.jsp -- form.jsp -User Name Age Click -- FHController created --- setUserName --- handle -0 1 [Field error in object 'cbname' on field 'age': rejected value [ ]; codes [typeMismatch. cbname.age,typeMismatch.age,typeMismatch.int,typeMismatch]; arguments [org. springframework.context.support.DefaultMessageSourceResolvable: codes [cbname. age,age]; arguments [ ]; default message [age]]; default message [Failed to convert property value of type [java.lang.String] to required type [int] for property 'age'; nested exception is java.lang.NumberFormatException: For input string: ""]] -- dispinfo.jsp -OP of dispinfo.jsp 0 http://localhost:8000/swapp/form.jsp -- form.jsp -SUDHEER REDDY

55 POTHURAI User Name Age Click -- FHController created --- setAge --24 -- setUserName --P.Sudheer Reddy -- handle -P.Sudheer Reddy 24 0 [] -- dispinfo.jsp -OP of dispinfo.jsp P.Sudheer Reddy 24 The following steps will be carried out in the server when the above form is submitted: 1) Spring code captures the data. 2) Command bean object will be created. 3) The setters will be called to store the data in the command bean object. This is called as binding. 4) handle( ) method will be called. Student Name: DOB: dob Address: URL: url Height: studName address height

Must be converted as float Must be converted as java.nte.URL Must be converted as java.util.Date Spring capture the data as string objects & it will be able to automatically take care of converting the string objects in to primitive data types. For converting the string to URL we can use URLEditor, for converting string to Date we must used CustomDateEditor. The spring internally uses the binder object to take care of binding the data to the command bean. The binder can be initialized by providing the initBinder( ) method inside the controller.

SUDHEER REDDY

56 POTHURAI package org.students; public class Test { public static void main(String a[ ]) throws Exception { Class test1=Class.forName("org.students.CBOne"); boolean b1=org.students.CBOne.class.isAssignableFrom(test1); System.out.println(b1); boolean b2=org.students.CBTwo.class.isAssignableFrom(test1); System.out.println(b2); } } Test Run As Java Application true false As part of spring an interface with the name org.springframework.validation. Validator is provided. We must implement this interface to take care of the validations. org.springframework.validation.Errors is an interface. BindException is a class that provides the implementation of Errors interface. package org.students; public class CBTwo { private String studName; private float height; java.util.Date dob; java.net.URL url; String address; public String getStudName( ) { return studName; } public void setStudName(String studName) { System.out.println("-- setStudName --"+studName); this.studName = studName; } public float getHeight( ) { return height; } public void setHeight(float height) { System.out.println("-- setHeight --"+height); this.height = height; } public java.util.Date getDob( ) { return dob; } public void setDob(java.util.Date dob) { System.out.println("-- setDob --"+dob); this.dob = dob; } SUDHEER REDDY

57 POTHURAI public java.net.URL getUrl( ) { return url; } public void setUrl(java.net.URL url) { System.out.println("-- setUrl --"+url); this.url = url; } public String getAddress( ) { return address; } public void setAddress(String address) { System.out.println("-- setAddress --"+address); this.address = address; } public void CBTwo( ){ System.out.println("-- CBTwo created --"); } } package org.students; import org.springframework.validation.*; public class CBTValidator implements Validator { public boolean supports(Class clazz) { return org.students.CBTwo.class.isAssignableFrom(clazz); } public void validate(Object obj, Errors errors) { System.out.println("-- validate --"); System.out.println("-- errors -->"+errors.getClass( )); org.students.CBTwo co=(org.students.CBTwo)obj; if(co.getStudName( )==null || co.getStudName( ).equals("")) { errors.rejectValue("studName", "sname.req"); } if(co.getHeight( )<1 || co.getHeight( )>7) { errors.rejectValue("height", "height.not.valid"); } } } sname.req, height.not.valid are called as keys of the error messages. package org.students; import javax.servlet.http.*; import org.springframework.validation.*; import org.springframework.web.servlet.*; import org.springframework.web.servlet.mvc.*; import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.beans.propertyeditors.*; import java.text.SimpleDateFormat;; SUDHEER REDDY

58 POTHURAI public class FHController1 extends AbstractCommandController { public FHController1( ){ System.out.println("-- FHController1 created --"); setCommandName("cbname"); setCommandClass(org.students.CBTwo.class); setValidator(new org.students.CBTValidator( )); } public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { System.out.println("-- initBinder --"); binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor (new SimpleDateFormat("dd-MM-yyyy"),true)); binder.registerCustomEditor(java.net.URL.class, new URLEditor( )); } protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object obj, BindException be) throws Exception { System.out.println("-- handle --"); org.students.CBTwo ocb=(org.students.CBTwo)obj; System.out.println(ocb.getDob( )); System.out.println(ocb.getUrl( )); System.out.println(ocb.getHeight( )); System.out.println(be.getErrorCount( )); System.out.println(be.getAllErrors( )); ModelAndView mav=new ModelAndView ("dinfo",getCommandName( ),ocb); return mav; } } <bean name="/hf1.htm" class="org.students.FHController1"> </bean> <% System.out.println("-- dinfo.jsp --"); %> OP of dinfo.jsp <br> ${requestScope.cbname.studName} <br> ${requestScope.cbname.address} <% System.out.println("-- form1.jsp --"); %> <html> <head> <title> Form1 </title> </head> <body> <form action="hf1.htm"> Student Name: <input type="text" name="studName"> <br> DOB: <input type="text" name="dob"> <br> Address: SUDHEER REDDY

59 POTHURAI <input type="text" name="address"> <br> URL: <input type="text" name="url"> <br> Height: <input type="text" name="height"> <br> <input type="submit" value="Send Req"> <br> </form> </body> </html> http://localhost:8000/swapp/form1.jsp -- form1.jsp -Student Name: DOB: Address: URL: Height: Click -- FHController1 created --- initBinder --- setAddress --Anantapur -- setDob --Wed Sep 19 00:00:00 IST 1984 -- setHeight --9.0 -- setStudName --Sudheer Reddy -- setUrl --http:://www.sudheer.com -- validate --- errors -->class org.springframework.validation.BindException -- handle -Wed Sep 19 00:00:00 IST 1984 http:://www.sudheer.com 9.0 1 [Field error in object 'cbname' on field 'height': rejected value [9.0]; codes [height.not. valid.cbname.height,height.not.valid.height,height.not.valid.float,height.not.valid]; arguments [ ]; default message [null]] -- dinfo.jsp -OP of dinfo.jsp Sudheer Reddy Anantapur http://localhost:8000/swapp/form1.jsp -- form1.jsp -Student Name: DOB: Address: URL: Height: Click -- initBinder -SUDHEER REDDY

60 POTHURAI -- setAddress --Anantapur -- setDob --Wed Sep 19 00:00:00 IST 1984 -- setHeight --6.0 -- setStudName --Sudheer Reddy -- setUrl --http:://www.sudheer.com -- validate --- errors -->class org.springframework.validation.BindException -- handle -Wed Sep 19 00:00:00 IST 1984 http:://www.sudheer.com 6.0 0 [] -- dinfo.jsp -OP of dinfo.jsp Sudheer Reddy Anantapur AbstractCommandController

extends SimpleFormController

Accept-Language: en-US

Context in English bone

Accept-Language :fr-CA server

Context in French btwo

As part of every request the browser sends a header with the name AcceptLanguage. The value of this header provides the local setting of the browser. We can use the code shown below to detect the locale setting of the browser. <% System.out.println("-- loc.jsp --"); %> <% java.util.Locale loc=request.getLocale( ); out.println(loc); out.println("<br>"+loc.getLanguage( )); out.println("<br>"+loc.getCountry( )); %> http://localhost:8000/swapp/loc.jsp SUDHEER REDDY

61 POTHURAI -- loc.jsp -en_US en US If a web application is designed to generate the content in English for bone & in French language for btwo (content generated according to the locale setting of the browser) then the application is called as i18n (internationalization) application. Procedure for implementing i18n application: 1) Provide the MessageResources in the properties files. pg.title=Welcome pg.pone=Hello Customer pg.ptwo=Thanks for buying {0} pg.title=Welcome in fr pg.pone=Hello Customer in fr pg.ptwo=Thanks for buying {0} in fr ourmsgs_en_US.properties

ourmsgs_fr_CA.properties

key of the resource value of the resource argument/ parameter ourmsgs is called as base name of the properties files. 2) For reading the information about the MessageResources available in the properties file configure the MessageSourceBean in spring-servlet.xml <bean id="messageSource" class="org.springframework.context.support. ResourceBundleMessageSource"> <property name="basename" value="ourmsgs"/> </bean> The message tag of the spring tag library picks up the value of the MessageResource based on the locale setting on the browser & sends the values to the browser. package org.students; import javax.servlet.http.*; import org.springframework.validation.*; import org.springframework.web.servlet.*; import org.springframework.web.servlet.mvc.*; public class INController extends AbstractController { public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mav=new ModelAndView("genop"); return mav; } } <bean name="/in.htm" class="org.students.INController"> SUDHEER REDDY

62 POTHURAI </bean> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <html> <head><title> <spring:message code="pg.title"/> </title> </head> <body> <p> <spring:message code="pg.pone"/> </p> <p> <spring:message code="pg.ptwo" arguments="pen"/> </p> </body> </html>

Tools Internet Options Languages

Note: - It is better to choose one of the Locale as the default Locale & place the messageResources of that Locale in a properties file with the name basename.properties (ex: - ourmsga.properties).

SUDHEER REDDY

63 POTHURAI SimpleFormController is a sub class of AbstractCommandController. Simple FormController inherits the capability of capturing the data creating the command bean, storing the in the command bean using the Binder object & validating the data using the Validator form AbstractCommandController. Apart from this functionality code is provided to take care of the Form View, the Success View as part of the SimpleFormController. Product Id: prodId Product name: prodName Price: price

Validations: 1) prodId must be between 1 & 10000 2) price must be greater than 1.0 3) A minimum of 3 chars must be provided for prodName. We must provide the error messages inside a properties file (ourmsgs.properties) pid.invalid=Product id not valid price.invalid=Price not valid pname.minlen.err=minimum of 3 chars must be provided for product name For using the information available in the properties file we must configure the MessageSourceBean in spring-servlet.xml <bean id="messageSource" class="org.springframework.context.support. ResourceBundleMessageSource"> <property name="basename" value="ourmsgs"/> </bean> 1) Provide the command bean class package org.students; public class ProdcutCB { int prodId; String prodName; float price; public int getProdId( ) { return prodId; } public void setProdId(int prodId) { System.out.println("--- setProdId ---"+prodId); this.prodId = prodId; } public String getProdName( ) { return prodName; SUDHEER REDDY

64 POTHURAI } public void setProdName(String prodName) { System.out.println("--- setProdName ---"+prodName); this.prodName = prodName; } public float getPrice( ) { return price; } public void setPrice(float price) { System.out.println("--- setPrice ---"+price); this.price = price; } public ProdcutCB( ){ System.out.println("--- ProdcutCB created ---"); } } 2) Provide the validator class to take care of validating the data available in ProductCB object package org.students; import org.springframework.validation.*; public class PCBValidator implements Validator { public boolean supports(Class clazz) { return org.students.ProdcutCB.class.isAssignableFrom(clazz); } public void validate(Object command, Errors errors) { org.students.ProdcutCB pcb=(org.students.ProdcutCB)command; if(pcb.getProdId( )<1 || pcb.getProdId( )>10000){ errors.rejectValue("prodId", "pid.invalid"); } if(pcb.getPrice( )<1.0f){ errors.rejectValue("price", "priceinvalid"); } if(pcb.getProdName( ).length( )<3){ errors.rejectValue("prodName", "pname.minlen.err"); } } } 3) Provide the JSP that generates the form. This JSP is called as form view (prodFrm.jsp) 4) Provide the JSP that generates that output after dealing with the form successfully. This is called as success view (pds.jsp) 5) Provide the controller to deal with the form (PFController)

SUDHEER REDDY

65 POTHURAI The code in the SimpleFormController forwards the request to the form view, if browser sends the GET request. If the POST request is sent by the browser then the internal code of SimpleFormController executes the tasks to deal with the data provided in the form. We can provide the code shown below to display all the error messages. <% System.out.println("--- prodFrm.jsp ---"); %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%@ page isELIgnored="true" %> <spring:hasBindErrors name="prodcb"> <c:forEach var="err" items="${errors.allErrors}"> <spring:message code="${err.code}"/> <br> </c:forEach> </spring:hasBindErrors> <html> <head> <title> new product </title> </head> <body> <form action="/swapp/hpf.htm" method="POST"> Product Id: <input type="text" name="prodId"> <br> Product name: <input type="text" name="prodName"> <br> Price: <input type="text" name="price"> <br> <input type="submit" value="STORE"> <br> </form> </body> </html> <% System.out.println("--- pds.jsp ---"); %> Product data stored in DB <br> Product Id --> ${requestScope.prodcb.prodId} <br> Product Name --> ${requestScope.prodcb.prodName} <br> Price --> ${requestScope.prodcb.price} <br> package org.students; import org.springframework.web.servlet.mvc.*; import javax.servlet.http.*; import org.springframework.web.bind.*; import org.springframework.web.servlet.*; public class PFController extends SimpleFormController { public PFController( ){ System.out.println("--PFController --"); this.setValidator(new org.students.PCBValidator( )); SUDHEER REDDY

66 POTHURAI } public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { // no need to register PE'S in this app System.out.println("-- initBinder --"); } public ModelAndView onSubmit(Object command)throws Exception { org.students.ProdcutCB pcb=(org.students.ProdcutCB)command; System.out.println("--- onSubmit ---"); System.out.println(pcb.getProdId( )); System.out.println(pcb.getProdName( )); System.out.println(pcb.getPrice( )); // code to store product data in DB ModelAndView mav=new ModelAndView (getSuccessView( ),getCommandName( ),pcb); return mav; } } <bean name="/hpf.htm" class="org.students.PFController"> <property name="formView"> <value>prodFrm</value> </property> <property name="successView"> <value>pds</value> </property> <property name="commandName"> <value>prodcb</value> </property> <property name="commandClass"> <value>org.students.ProdcutCB</value> </property> </bean> http://localhost:8000/swapp/hpf.htm --PFController ---- ProdcutCB created ---- initBinder ---- prodFrm.jsp --Product Id: Product name: Price: Click --- ProdcutCB created ---- initBinder ---- setPrice ---0.5 --- setProdId ---11111 --- setProdName ---su SUDHEER REDDY

67 POTHURAI --- prodFrm.jsp --Product id not valid Price not valid minimum of 3 chars must be provided for product name Product Id: Product name: Price: Click --- ProdcutCB created ---- initBinder ---- setPrice ---500.0 --- setProdId ---9000 --- setProdName ---sunil --- onSubmit --9000 sunil 500.0 --- pds.jsp --Product data stored in DB Product Id --> 9000 Product Name --> sunil Price --> 500.0 The following flow chart shows the steps that are carried out by the spring code when the form is submitted. Capture the data, create command bean object, call initBinder method, bind the data to the CB object by calling setters

Call validate method on the Validator object

No

is data valid?

Yes

forward request to form view

Call onSubmit method

We can provide the code shown below to display all the error messages. <spring:hasBindErrors name="prodcb"> <c:forEach var="err" items="${errors.allErrors}"> <spring:message code="${err.code}"/> <br> SUDHEER REDDY

68 POTHURAI </c:forEach> </spring:hasBindErrors> The body of hasBindErrors will be skipped when there are no errors associated with the command bean whose name is prodcb. If there are errors a variable will be created with the name errors. This variable points to Errors object. To get the list of errors getAllErrors( ) method can be used on Errors object. errors List getAllErrors( ) Errors object request scoped variable

The forEach tag will be evaluated for n number of times where n=the number of error messages available in the Errors object. status getExpression( ) getValue( ) getErrors( ) scoped variable/ attribute name BindStatus

request

<% System.out.println("--- prodFrm.jsp ---"); %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%@ page isELIgnored="true" %> <spring:bind path="prodcb"> <c:out value="${status.expression}"/> <c:out value="${status.value}"/> <c:out value="${status.errors}"/> </spring:bind> <html> <head> <title> new product </title> </head> <body> <form action="/swapp/hpf.htm" method="POST"> Product Id: <input type="text" name="prodId"> <br> <input type="submit" value="STORE"> <br> </form> </body> </html> SUDHEER REDDY

69 POTHURAI http://localhost:8000/swapp/hpf.htm org.springframework.validation.BeanPropertyBindingResult: 0 errors Product Id: Click org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'prodcb' on field 'prodId': rejected value [11111]; codes [pid.invalid.prodcb. prodId,pid.invalid.prodId,pid.invalid.int,pid.invalid]; arguments [ ]; default message [null] Product Id: The bind tag creates a variable with the name status & this status points to BindStatus object, in case of the code shown above the information about prodId property. To display the error messages of a particular field, we can use the code shown below. <% System.out.println("--- prodFrm.jsp ---"); %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%@ page isELIgnored="true" %> <html> <head> <title> new product </title> </head> <body> <form action="/swapp/hpf.htm" method="POST"> Product Id: <input type="text" name="prodId"> <spring:bind path="prodcb.prodId"> <c:forEach var="emsg" items="${status.errorMessages}"> <c:out value="${emsg}"/> </c:forEach> </spring:bind> <br> Product name: <input type="text" name="prodName"> <spring:bind path="prodcb.prodName"> <c:forEach var="emsg" items="${status.errorMessages}"> <c:out value="${emsg}"/> </c:forEach> </spring:bind><br> Price: <input type="text" name="price"> <spring:bind path="prodcb.price"> <c:forEach var="emsg" items="${status.errorMessages}"> <c:out value="${emsg}"/> </c:forEach> SUDHEER REDDY

70 POTHURAI </spring:bind> <br> <input type="submit" value="STORE"> <br> </form> </body> </html> http://localhost:8000/swapp/hpf.htm Product Id: Product name: Price: Click Product Id: Product id not valid Product name: minimum of 3 chars must be provided for product name Price: Price not valid Account One: Account Two: Amount: accOne accTwo amount

Validations: Amount must be greater than 1000. Steps: 1) Provide the command bean class package org.students; public class FundTransferCB { int accOne; int accTwo; float amount; public int getAccOne( ) { return accOne; } public void setAccOne(int accOne) { this.accOne = accOne; } public int getAccTwo( ) { return accTwo; } public void setAccTwo(int accTwo) { this.accTwo = accTwo; } public float getAmount( ) { return amount; SUDHEER REDDY

71 POTHURAI } public void setAmount(float amount) { this.amount = amount; } } 2) Provide the validator class package org.students; import org.springframework.validation.*; public class FTCBValidator implements Validator { public boolean supports(Class clazz) { return org.students.FundTransferCB.class.isAssignableFrom(clazz); } public void validate(Object command, Errors errors) { org.students.FundTransferCB cb= (org.students.FundTransferCB)command; if(cb.getAmount( )<1000){ errors.rejectValue("amount","amount.invalid"); } } } 3) Provide the JSP to generate the input form (form view) <% System.out.println("--- fundTrfForm.jsp ---"); %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%@ page isELIgnored="true" %> <spring:hasBindErrors name="ftcb"> <c:forEach var="err" items="${errors.allErrors}"> <spring:message code="${err.code}"/> <br> </c:forEach> </spring:hasBindErrors> <html> <head> <title> FT Form </title> </head> <body> <form action="/swapp/tf.htm" method="POST"> Account One: <input type="text" name="accOne"> <br> Account Two: <input type="text" name="accTwo"> <br> Amount: <input type="text" name="amount"><br> <input type="submit" value="Transfer"> <br> SUDHEER REDDY

72 POTHURAI </form> </body> </html> 4) Provide success view (ftsuc.jsp) <% System.out.println("--- ftsuc.jsp ---"); %> Transferd ${requestScope.ftcb.amount} from ${requestScope.ftcb.accOne} to ${requestScope.ftcb.accTwo} 5) Provide the controller class package org.students; import org.springframework.web.servlet.mvc.*; public class FTCon extends SimpleFormController { public FTCon(){ this.setValidator(new org.students.FTCBValidator( )); } public void doSubmitAction(Object command)throws Exception { org.students.FundTransferCB cb= (org.students.FundTransferCB)command; System.out.println(cb.getAccOne( )); System.out.println(cb.getAccTwo( )); System.out.println(cb.getAmount( )); // code to transfer funds from accone to acctwo in DB } } The internal code of SimpleFormController takes care of creating the ModelAndView object & returns it, if we implement doSubmitAction method. In this case the successView will be used as the view & command bean will be used as model & the command name is used as the model name. <bean name="/tf.htm" class="org.students.FTCon"> <property name="formView"> <value>fundTrfForm</value> </property> <property name="successView"> <value>ftsuc</value> </property> <property name="commandName"> <value>ftcb</value> </property> <property name="commandClass"> <value>org.students.FundTransferCB</value> </property> </bean> http://localhost:8000/swapp/tf.htm --- fundTrfForm.jsp --SUDHEER REDDY

73 POTHURAI Account One: Account Two: Amount: Click --- fundTrfForm.jsp --Amount must be greater than 1000 Account One: Account Two: Amount: Click 12 24 3000.0 --- ftsuc.jsp --Transferd 3000.0 from 12 to 24 Field One: Field Two: fldOne fldTwo pg0.jsp

Field Three: Field Four:

fldThr fldFour

pg1.jsp

Field Five: Field Six:

fldFive fldSix

pg2.jsp

<% System.out.println("--- pg0.jsp ---"); %> <html> <head> <title> Page Zero </title> </head> <body> <form action="/swapp/hmf.htm" method="POST"> <input type="hiddeen" name="_page0" value="true"> <input type="hiddeen" name="_target1" value="true"> <br> Field One: <input type="text" name="fldOne"> <br> Field Two: <input type="text" name="fldTwo"> <br> <input type="submit" value="Next"> <br> SUDHEER REDDY

74 POTHURAI </form> </body> </html> <% System.out.println("--- pg1.jsp ---"); %> <html> <head> <title> Page One </title> </head> <body> <form action="/swapp/hmf.htm" method="POST"> <input type="hiddeen" name="_page1" value="true"> <input type="hiddeen" name="_target2" value="true"> <br> Field Three: <input type="text" name="fldThr"> <br> Field Four: <input type="text" name="fldFour"> <br> <input type="submit" value="Next"> <br> </form> </body> </html> <% System.out.println("--- pg2.jsp ---"); %> <html> <head> <title> Page Two </title> </head> <body> <form action="/swapp/hmf.htm" method="POST"> <input type="hiddeen" name="_page2" value="true"> <input type="hiddeen" name="_finish" value="true"> <br> Field Five: <input type="text" name="fldFive"> <br> Field Six: <input type="text" name="fldSix"> <br> <input type="submit" value="Store"> <br> </form> </body> </html> In order to deal with the three forms we must provide a command bean & a controller package org.students; public class MultiFormCB { String fldOne; String fldTwo; SUDHEER REDDY

75 POTHURAI String fldThr; String fldFour; String fldFive; String fldSix; public String getFldOne( ) { return fldOne; } public void setFldOne(String fldOne) { this.fldOne = fldOne; } public String getFldTwo( ) { return fldTwo; } public void setFldTwo(String fldTwo) { this.fldTwo = fldTwo; } public String getFldThr( ) { return fldThr; } public void setFldThr(String fldThr) { this.fldThr = fldThr; } public String getFldFour( ) { return fldFour; } public void setFldFour(String fldFour) { this.fldFour = fldFour; } public String getFldFive( ) { return fldFive; } public void setFldFive(String fldFive) { this.fldFive = fldFive; } public String getFldSix( ) { return fldSix; } public void setFldSix(String fldSix) { this.fldSix = fldSix; } } package org.students; import javax.servlet.http.*; import org.springframework.validation.*; import org.springframework.web.servlet.*; SUDHEER REDDY

76 POTHURAI import org.springframework.web.servlet.mvc.*; public class MFCon extends AbstractWizardFormController { public MFCon( ){ String pgList[ ]=new String[3]; pgList[0]="pg0"; pgList[1]="pg1"; pgList[2]="pg2"; this.setPages(pgList); this.setCommandClass(org.students.MultiFormCB.class); this.setCommandName("mfcb"); } public void validatePage(Object command, Errors errors, int page){ System.out.println("--- validate Page --->"+page); } public ModelAndView processFinish(HttpServletRequest request, HttpServletResponse response, Object command, BindException be) throws Exception { // code to store data in DB System.out.println("--- processFinish ---"); ModelAndView mav=new ModelAndView ("ds",getCommandName( ),command); return mav; } } <bean name="/hmf.htm" class="org.students.MFCon"> </bean> <% System.out.println("--- ds.jsp ---"); %> Data Strored in DB <br> ${requestScope.mfcb.fldOne} <br> .........<br> ${requestScope.mfcb.fldSix} http://localhost:8000/swapp/hmf.htm --- pg0.jsp --Field One: Field Two: Click --- validate Page --->0 --- pg1.jsp --Field Three: Field Four: Click --- validate Page --->1 --- pg2.jsp --SUDHEER REDDY

77 POTHURAI Field Five: Field Six: Click --- validate Page --->0 --- validate Page --->1 --- validate Page --->2 --- processFinish ----- ds.jsp --Data Strored in DB 1 ......... 6 We must provide a separate set of classes called as business services classes with business logic. Acc One: TxPwd: accOne txPwd

ftfZero.jsp Validations: accOne is required txPwd is required

Acc Two: amount:

accTwo amount

ftfOne.jsp Validations: accTwo is required amount must be greater than 999 SQL> select * from acctab; ACCNO UNAME TXPWD BALANCE --------------- ------------- ----------------- -------------------1 uone pone 10000 2 utwo ptwo 20000 public class FTService( ) { public transferFunds(org.students.FundTrfCB) throws Exception{ SUDHEER REDDY

78 POTHURAI jdbc code to get data reg accOne check txPwd, if it is not valid thrown an Exception check the balance, if the funds are not enough thrown Exception jdbc code to get data reg accTwo reduce balance of accOne increase balance of accTwo jdbc code to update data in DB } } The code that is responsible for dealing with the database is called as Data Access logic. In majority of cases business logic is the combination of Data Access logic + some other logic that does not deal with the database. In the above class we have mixed the Data Access logic with other logic. Instead of mixing we must used separate set of classes called as DAO (data access object) classes for the implementation of the Data Access logic. To simplify the development of the DAO classes, the classes like HibernateDaoSupport, TopLinkDaoSupport, JdbcDaoSupport etc are provided. HibernateDao class uses SessionFactory object & it takes care of creating the HibernateTemplate object & sets up the link between HibernateTemplate object & SessionFactory object. For accessing Acctab must provide a POJO class (org.students.Acctab) & a hbm file (acctab.hbm.xml). apport from these two files we can provide org.students.AcctabDAO with the code that takes care of storing retrieving, modifying, deleting the data in Acctab (the Data Access logic must be provided as part of DAO classes). We must follow the steps given below to solve the problem in running the web application with the jar files supplied as part of MyEclipse. Steps: 1) Remove the jar files that are copy by MyEclipse under WEB-INF/lib 2) Extract the content spring-framework-2.0.6-with-dependencies.zip & copy all the jar files available in the extracted contentment to WEB-INF/lib directory. 3) Remove hibernate2.0.jar 4) Copy commons-attributes-compiler.jar to a directory like d:\temp 5) Open the DOS window, use the cd command & move to the temp directory 6) Use the command shown below to extract the jar files content. D:\temp>jar xf commons-collections.jar 7) Remove META-INF directory & jar from the temp directory. 8) Create the fresh jar file using the command shown below. D:\temp>jar cf commons-collections.jar . 9) Replace the old jar file with the new jar file in WEB-INF/lib directory. 10) Copy commons-collections-3.2.jar, commons-dbcp-1.2.2.jar, commons-pool-1.3.jar, ojdbc14.jar to WEB-INF/lib directory. Procedure for setting a spring based web application with Hibernate: 1) Create the web project in MyEclipse IDE SUDHEER REDDY

79 POTHURAI 2) Add spring capabilities to the web project. 3) Create spring-servlet.xml & add the required information to web.xml & springservlet.xml files <bean name="/htf.htm" class="org.students.HTFController"> </bean> 4) In the package explorer select swproj & choose MyEclipse add Hibernate Capabilities. 5) In new Hibernate Project window check all the check boxes & select copy checked libraries jars . radio button & click on the next button. 6) Select spring configuration file radio button & click on next button. 7) Select existing spring configuration file radio button and provide SFBean as SessionFactory Id & click on the next button. 8) Provide DSBean as Bean Id & choose OraDrv as Db Driver & click on the next button. 9) Uncheck create SessionFactory checkbox & click on the finish button. Note: - MyEclipse adds the information about the DataSource bean & the SessionFactory bean in applicationContext.xml Procedure for generating hbm, POJO, DAO: 1) Select MyEclipse DataBase explorer prospective. 2) Connect the database using OraDrv. 3) Select the table(s) & choose Hibernate reverse engineering. 4) In the Hibernate reverse engineering window check the firat 3 check boxes & check the Java Data Access Object, Generate preside find by --- & click on the finish button.

Note: - MyEclipse IDE creates acctab.hbm.xml, Acctab.java, AcctabDAO.java files & it adds the information about AcctabDAO as a Bean to applicationContext.xml <bean id="AcctabDAO" class="org.students.AcctabDAO"> <property name="sessionFactory"> <ref bean="SFBean"></ref> SUDHEER REDDY

80 POTHURAI </property> </bean> package org.students; public class IsFundsException extends Exception { public IsFundsException(String msg){ super(msg); } } package org.students; public class TxPwdException extends Exception { public TxPwdException(String msg){ super(msg); } } <% System.out.println("--- ftfZero.jsp ---"); %> <html> <head> <title> Form Zero </title> </head> <body> <form action="/swapp/htf.htm" method="POST"> <input type="hiddeen" name="_page0" value="true"> <input type="hiddeen" name="_target1" value="true"> <br> Account One: <input type="text" name="accOne"> <br> Tx Pwd: <input type="password" name="txPwd"> <br> <input type="submit" value="Next"> <br> </form> </body> </html> <% System.out.println("--- ftfOne.jsp ---"); %> <html> <head> <title> Form One </title> </head> <body> <form action="/swapp/htf.htm" method="POST"> <input type="hiddeen" name="_page1" value="true"> <input type="hiddeen" name="_finish" value="true"> <br> Account Two: <input type="text" name="accTwo"> <br> Amount: SUDHEER REDDY

81 POTHURAI <input type="text" name="amount"> <br> <input type="submit" value="Transfer"> <br> </form> </body> </html> package org.students; public class FTCommand { Long accOne; Long accTwo; Double amount; String txPwd; public Long getAccOne( ) { return accOne; } public void setAccOne(Long accOne) { this.accOne = accOne; } public Long getAccTwo( ) { return accTwo; } public void setAccTwo(Long accTwo) { this.accTwo = accTwo; } public Double getAmount( ) { return amount; } public void setAmount(Double amount) { this.amount = amount; } public String getTxPwd( ) { return txPwd; } public void setTxPwd(String txPwd) { this.txPwd = txPwd; } } We can use the jar signer to sign a jar file when a jar field signed, a JVM as well as several other tools will be to identify the name of the company that has supplied the classes available in the jar file. Starting a Transaction & ending the Transaction either by committing or roiling back Transaction is called as controlling the Transactions. Transaction tx=hsession.beginTransaction( ); SUDHEER REDDY

82 POTHURAI tx.commit( ); (or) tx.rollback( ); Code to controlling the tx The code shown above is used for controlling the Transactions. We need provided the code like this in a spring based application as the Transactions can be managed automatically by spring. This feature is similar to EJBs automatic Transaction management. RunTimeException( ) & the sub classes of RunTimeExceptions are called as unchecked Exceptions. Spring roles back the Transaction when unchecked Exception is thrown. The developers can decide about what must be done by spring when checked Exception is thrown. The developer can provide the information about what must be done by spring when as Exception is thrown by configuring a bean as shown below. <bean id="transAttributeSource" class="org.springframework.transaction. interceptor.NameMatchTransactionAttributeSource"> <property name="properties"> <props> <prop key="*"> PROPAGATION_REQUIRED,-Exception </prop> </props> </property> </bean> (* stands for all the methods available in various classes, stands for rollback & + stands for commit). In the above case as we have used Exception, spring will rollback the Transaction when the Exception with the name Exception is thrown. package org.students; public class FTService { public void tansferFunds(org.students.AcctabDAO adao, org.students. FTCommand cb) throws Exception { // our business logic } } We should not call the transferFunds( ) method on FTService object directly. We must used a Proxy object to take of starting a Transaction, calling the business method on the target (FTService), ending the Transaction. Proxy object transferFunds( .. ) { start tx call FTService. transferFunds( .. ) end tx } Target of Proxy

transferFunds( .. ) { business logic }

SUDHEER REDDY

83 POTHURAI FTService fts FTService$$xx The Proxy class is generated by TransactionProxyFactoryBean by using software called CGLIB (code generation library). package org.students; public class FTService { public void tansferFunds(org.students.AcctabDAO adao, org.students.FTCommand cb) throws Exception { org.students.Acctab a1,a2; a1=adao.findById(cb.getAccOne( )); if(! a1.getTxpwd( ).equals(cb.getTxPwd( ))) { throw new TxPwdException("Wrong Pwd"); } if(a1.getBalance( )<cb.getAmount( )) { throw new IsFundsException("Funds not Enough"); } a2=adao.findById(cb.getAccTwo( )); a1.setBalance(a1.getBalance( )-cb.getAmount( )); a2.setBalance(a2.getBalance( )+cb.getAmount( )); } } package org.students; import javax.servlet.http.*; import org.springframework.validation.*; import org.springframework.web.servlet.*; import org.springframework.web.*; import org.springframework.web.servlet.mvc.*; import org.springframework.context.*; public class HTFController extends AbstractWizardFormController { public HTFController( ){ String pages[ ]={"ftfZero","ftfOne"}; this.setPages(pages); this.setCommandClass(org.students.FTCommand.class); this.setCommandName("ftcb"); } public ModelAndView processFinish(HttpServletRequest request, HttpServletResponse response, Object cmd, BindException be) throws Exception { org.students.FTCommand cb=(org.students.FTCommand)cmd; ApplicationContext sprCont=this.getApplicationContext( ); org.students.FTService fts=(org.students.FTService) sprCont.getBean("FTService"); SUDHEER REDDY

84 POTHURAI org.students.AcctabDAO adao=(org.students.AcctabDAO) sprCont.getBean("AcctabDAO"); fts.tansferFunds(adao, cb); ModelAndView mav=new ModelAndView ("ftsuc",getCommandName( ),cb); return mav; } } <% System.out.println("--- ftsuc.jsp ---"); %> Fund transfer successful <br> Rs. ${requestScope.ftcb.amount} /transferred from ${requestScope.ftcb.accOne} to ${requestScope.ftcb.accTwo} <bean id="tansactionManager" class="org.springframework.orm.hibernate3. HibernateTransactionManager"> <property name="sessionFactory"> <ref local="SFBean"/> </property> </bean> <bean id="transAttributeSource" class="org.springframework.transaction. interceptor.NameMatchTransactionAttributeSource"> <property name="properties"> <props> <prop key="*"> PROPAGATION_REQUIRED,-Exception </prop> </props> </property> </bean> <bean id="FTServiceTarget" class="org.students.FTService"> </bean> <bean id="FTService" class="org.springframework.transaction. interceptor.TransactionProxyFactoryBean"> <property name="target"> <ref local="FTServiceTarget"/> </property> <property name="transactionManager"> <ref local="tansactionManager"/> </property> <property name="transactionAttributeSource"> <ref local="transAttributeSource"></ref> </property> </bean>

SUDHEER REDDY

85 POTHURAI As part of the project there will be several Service classes. We must provide the information about all these several classes as the beans with the ids like XxxService & XxxServiceTarget. http://localhost:8000/swapp/htf.htm --- ftfZero.jsp --Account One: Tx Pwd: Click --- ftfOne.jsp --Account Two: Amount: Click HTTP Status 500 org.students.TxPwdException: Wrong Pwd http://localhost:8000/swapp/htf.htm --- ftfZero.jsp --Account One: Tx Pwd: Click --- ftfOne.jsp --Account Two: Amount: Click HTTP Status 500 org.students.IsFundsException: Funds not Enough http://localhost:8000/swapp/htf.htm --- ftfZero.jsp --Account One: Tx Pwd: Click --- ftfOne.jsp --Account Two: Amount: Click --- ftsuc.jsp --Fund transfer successful Rs. 2000.0 /- transferred from 1 to 2 SQL> select * from acctab; ACCNO UNAME TXPWD BALANCE --------------- ------------- ---------------- ------------------1 uone pone 8000 SUDHEER REDDY

86 POTHURAI 2 utwo ptwo 22000

We can use the code shown below to start a Transaction. org.springframework.orm.hibernate3.HibernateTransactionManager org.springframework.orm.hibernate3.HibernateTransactionManager) sprCont.getBean("tansactionManager"); htm.getTransaction(null); PROPAGATION DESCRIPTION An Exception will be thrown, if there is no Transaction while calling a method. If the Transaction is already available then the method will be executed using the existing Transaction If there is no Transaction then the method will be executed without a Transaction. If there is a Transaction an Exception will be thrown & method will not be executed. If the Transaction is available the method will be executed as part of the existing Transaction. If the Transaction is not available a new Transaction will be started & the method will be executed in the new Transaction. If the Transaction is available a new Transaction will be started & the method will be executed in the new Transaction. If the Transaction is not available a new Transaction will be started and the method will be executed in new Transaction. The method will be executed without a Transaction if there is a no Transaction & if there is a Transaction the method will be executed using the existing Transaction. If there is a Transaction then the method will be executed without using the existing Transaction & if there is no Transaction the method will be executed without a Transaction. htm=(

PROPAGATION_MANDATORY

PROPAGATION_ NEVER

PROPAGATION_ REQUIRED

PROPAGATION_ REQUIRES_NEW

PROPAGATION_ SUPPORTS

PROPAGATION_ NOT_SUPPORTED

Ex: SUDHEER REDDY

87 POTHURAI SrvOne bmOne { } P_R SrvTwo bmTwo { } P_M

TabX

TabY

OurController Note: - Spring uses Aspect Oriented Programming (AOP) for supporting Transaction management. AOP: The object oriented programming languages always us to reuse the code by creating super classes & sub classes. In some cases we will be forced to create a super class, sub class relationship between unrelated classes. A class like TxMgr is responsible managing the Transactions & SecMgr is responsible for managing the security of the application. These 2 classes are unrelated. In our project if there is a classes with the name XSrv with the business logic. If the security & Transactions has to be taking care while executing the business logic, we can create class hierarchy as shown below. TxMgr

SecMgr

XSrv In the above class hierarchy we have forced to create the super class & sub class relation ship between unrelated classes. To address this problem Aspect Oriented Programming (technique) is introduce. An Aspect is defined as a cross cutting concern. .

SUDHEER REDDY

88 POTHURAI dot Line Paper In the above diagram a dot (.) covers only one point on a paper & the line covers/ used at multiple points on the paper. As Aspect is piece of code which can be used at multiple parts (classes) of the projects. This is why an Aspect is called as a cross cutting concern. Typically Log Management, Transaction management has to be used at multiple parts of the projects. So these thing can be called as Aspects.

LogMgr

TxMgr

XCon

YCon

MCb

XSrv

YSrv

NCb

An Aspect will be typically used/ applied/ advised before the connection of a method, after execution of the method. The point at which the Aspect is advised is called as a join point.

THE END

SUDHEER REDDY

Potrebbero piacerti anche