Professional Documents
Culture Documents
Hi all,
This article presents a simple way to create a web application using
Struts+Spring+Hibernate.
I am also a newbie searching for a startup example integrating all the above said
technologies, but i was fed up as there are many tutorials on the net but explaining them
with an IDE.But here i just used an simple editor to write up my code.
Here i don't give any detailed description about the subjects regarding Struts/Spring/
Hibernate, rather i ll give a step-by-step process to build a sample application.
This example illustrates a simple application asking the user to enter his
FirstName,LastName,Mobile and City. When submitted his data is inserted into the database
and outputs all the records present in the table to the browser.
ok lets have a look over the directory structure that i used to build the application
ok now lets have a look over build.properties and build.xml to build the application
build/build.properties
src.dir=src
dist.dir=dist
web.dir=web
lib.dir=${web.dir}/WEB-INF/lib
classes.dir=${dist.dir}/WEB-INF/classes
app.name=springex
war.dir=war
tomcat.home=C:/Program Files/Apache Software Foundation/Tomcat 5.0
tomcat.webapps=${tomcat.home}/webapps
tomcat.work=${tomcat.home}/work/Standalone/localhost
Please be sure to change the path for Tomcat home and its webapps directory if u installed
some where else.
build.xml
<?xml version="1.0"?>
<project name="StrutsSpringHibernateProject" basedir="." default="install">
<!-- Import properties file into this Build File -->
<property file="build\build.properties"/>
<!-- Set the ClassPath which is used for Compiling and Running the application -->
<path id="classpath">
<fileset dir="${lib.dir}" includes="*.jar"/>
</path>
<!-- Delete the destination Directory and War directory before Building the application -->
<target name="clean">
<delete dir="${dist.dir}"/>
<delete dir="${war.dir}"/>
</target>
<!-- Copy all the resources that are necessary for running the application -->
<target name="copy-resources">
<mkdir dir="${dist.dir}"/>
<mkdir dir="${war.dir} "/>
<copy todir="${dist.dir}">
<fileset dir="${web.dir}">
<exclude name="**/*.java"/>
</fileset>
</copy>
<copy todir="${classes.dir}">
<fileset dir="${src.dir}">
<exclude name="**/*.java"/>
</fileset>
</copy>
<mkdir dir="${classes.dir}"/>
</target>
<!-- copy the war file created into tomcat webapps directory -->
<target name="install" depends="war,tomcat-clean">
<copy file="${war.dir}/${app.name}.war"
tofile="${tomcat.webapps}/${app.name}.war" />
</target>
</project>
As you can see the build.xml file, there are different targets defined to build the application
like clean,compile,copy-resources,tomcat-clean and install.Each has its specific task to do
and depends on others. just build it with ant and it will do all the work for you.
ok now lets have a look over the things under web directory
WEB-INF : This directory holds all the tlds,*.jar files and *.xml files
Index.jsp : The jsp page which asks for user details.
success.jsp : When the application runs file we will be forwarded to this.
failure.jsp : When application fails we will be forwarded to this.
Index.jsp
<html>
<head>
<title>Index</title>
</head>
<body>
<form action="submitDetails.do">
<table>
<tr>
<td>FirstName :</td>
<td><input type="text" size="20" name="fname"></td>
</tr>
<tr>
<td>LastName :</td>
<td><input type="text" size="20" name="lname"></td>
</tr>
<tr>
<td>Mobile :</td>
<td><input type="text" size="20" name="mobile"></td>
</tr>
<tr>
<td>City :</td>
<td><input type="text" size="20" name="city"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="submit"></td>
</table>
</form>
</body>
</html>
success.jsp
<html>
<body>
<form>
<table>
<tr>
<td>
<table border="1">
<tr>
<td>Id</td>
<td>First Name</td>
<td>Last Name</td>
<td>Mobile</td>
</tr>
<tr>
<td><bean:write name="person" property="id"/></td>
<td><bean:write name="person" property="fname"/></td>
<td><bean:write name="person" property="lname"/></td>
<td><bean:write name="person" property="mobile"/></td>
</tr>
</logic:iterate>
</table>
</td>
</tr>
</table>
</form>
</body>
</html>
failure.jsp
<b>Failed</b>
success.jsp is used to display all the records that are present in the table, it used
<logic:iterate/> tag to iterate the list that is present in the scope which holds all the data
present in the table.
tlds : This directory includes all the .tlds files that come with struts framework.Place all
those tlds into this directory.
Now lets have a look over all these xml files that are required to configure the application
web.xml
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>Index.jsp</welcome-file>
</welcome-file-list>
<taglib>
<taglib-uri>/WEB-INF/tlds/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/tlds/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/tlds/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/tlds/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/tlds/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/tlds/struts-logic.tld</taglib-location>
</taglib>
</web-app>
This file just configures the ActionServlet and all the tlds required for the application.
struts-config.xml:
<struts-config>
<form-beans>
<form-bean name="personalForm"
type="org.apache.struts.validator.DynaValidatorActionForm">
<form-property name="fname" type="java.lang.String"/>
<form-property name="lname" type="java.lang.String"/>
<form-property name="mobile" type="java.lang.String"/>
<form-property name="city" type="java.lang.String"/>
<form-property name="details" type="java.util.List"/>
</form-bean>
</form-beans>
<action-mappings>
<action path="/submitDetails"
type="org.springframework.web.struts.DelegatingActionProxy"
input="/index.jsp"
name="personalForm">
<forward name="success" path="/success.jsp"/>
<forward name="failure" path="/failure.jsp"/>
</action>
</action-mappings>
<message-resources parameter="ApplicationResources"/>
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/
springBeans.xml"/>
</plug-in>
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-
INF/validation.xml" />
<set-property property="stopOnFirstError" value="false" />
</plug-in>
</struts-config>
As shown above, we are using a DynaValidatorActionForm as our form bean and all there
properties set according to the inputs specified in Index.jsp.
Now just have a look over the plugin that is useful for interating with Spring.
The class 'ContextLoderPlugin' is used to include the spring context in the application and
we are specifing the location of its configuration file.
springBeans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/
dtd/spring-beans.dtd">
<beans>
<bean id="HibernateProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.query.substitutions">true 'T', false 'F'</prop>
<prop key="hibernate.c3p0.minPoolSize">5</prop>
<prop key="hibernate.c3p0.maxPoolSize">20</prop>
<prop key="hibernate.c3p0.timeout">600</prop>
<prop key="hibernate.c3p0.max_statement">50</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
</props>
</property>
</bean>
<bean id="SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource"><ref local="DataSource"/></property>
<property name="hibernateProperties">
<ref bean="HibernateProperties" />
</property>
<property name="mappingResources">
<list>
<value>com/spring/bo/hibernate/Details.hbm.xml</value>
</list>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref bean="SessionFactory"/></property>
</bean>
<bean id="personalDAO"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref
local="transactionManager"/></property>
<property name="target"><ref local="personalDAOTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="addPersonalDetails">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
Dont just panic seeing this file, its just a spring config file holding all the details of the beans
we use. As we are integrating this with hibernate , all the configuration details regarding the
url,username,password are specified here.
It just wires all the beans accordingly to build the application.Just have a look over the xml
file and you will get to know which bean has reference to other and how they will work.
ok thats all with WEB-INF directory , now we shall see the java code in the src directory
errors.required={0} is required.
errors.minlength={0} can not be less than {1} characters.
errors.maxlength={0} can not be greater than {1} characters.
errors.invalid={0} is invalid.
<log4j:configuration debug="true">
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} [%t] %p %c %x -
%m%n"/>
</layout>
</appender>
<category name="org.apache">
<priority value="warn"/>
</category>
<category name="org.apache.axis">
<priority value="debug"/>
</category>
<root>
<priority value="debug"/>
<appender-ref ref="stdout"/>
</root>
</log4j:configuration>
k so now we have all the stuff except the java code that is required for this sample
application.
As you can see in the above figure, except in action package the rest of business and bo
includes 2 java files, these include one interface and one implementation classes.
action.PersonalAction.java
package com.spring.action;
import java.io.*;
import java.util.List;
import java.util.LinkedList;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import com.spring.business.*;
import com.spring.bo.hibernate.Details;
personalService.setDetails(personalForm);
return mapping.findForward("success");
}
}
business/PersonalService.java :
package com.spring.business;
import org.apache.struts.action.*;
import java.util.List;
import com.spring.bo.PersonalDAO;
import com.spring.bo.hibernate.Details;
business/PersonalServiceImpl.java :
package com.spring.business;
import java.util.List;
import java.util.LinkedList;
import com.spring.bo.PersonalDAO;
import com.spring.bo.hibernate.Details;
import org.apache.struts.action.*;
pdetails.setFname((String)personalForm.get("fname"));
pdetails.setLname((String)personalForm.get("lname"));
pdetails.setMobile((String)personalForm.get("mobile"));
pdetails.setCity((String)personalForm.get("city"));
personalDAO.addPersonalDetails(pdetails);
}
return details;
}
bo/PersonalDAO.java
package com.spring.bo;
import java.util.List;
import com.spring.bo.hibernate.*;
}
bo/PersonalDAOImpl.java
package com.spring.bo;
import java.util.List;
import com.spring.bo.hibernate.Details;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
return list;
}
}
As shown above in the directory structure, the bo package includes another sub package
'hibernate' , this package includes the java class and mapping file for the table that we are
going to use in our application.
The java file includes all the getters and setters methods for the fields for the table and
.hbm.xml file includes the mapping details with the fields in the table.
The table i used for this application is 'PERSONAL_DETAILS' with one primary key and four
fileds that hold the information passed from Index.jsp.
bo/hibernate/Details.java
package com.spring.bo.hibernate;
/*
* Setters for all the fields
*/
public void setId(long id){
this.id = id;
}
public void setFname(String fname){
this.fname = fname;
}
public void setLname(String lname){
this.lname = lname;
}
public void setMobile(String mobile){
this.mobile = mobile;
}
public void setCity(String city){
this.city = city;
}
/*
* getters for all the fields
*/
public long getId(){
return id;
}
public String getFname(){
return fname;
}
public String getLname(){
return lname;
}
public String getMobile(){
return mobile;
}
public String getCity(){
return city;
}
The toString() method is useful when we are displaying the content on success.jsp when
iterating the List element.
bo/hibernate/Details.hbm.xml
<?xml version="1.0"?>
<hibernate-mapping>
<class name="com.spring.bo.hibernate.Details" table="PERSONAL_DETAILS">
<id name="id" column="id" type="java.lang.Long" unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="fname" column="FIRST_NAME"/>
<property name="lname" column="LAST_NAME"/>
<property name="mobile"/>
<property name="city"/>
</class>
</hibernate-mapping>
as specified above, there is one primary key as 'id' and the rest of the propertys set
specified with there name and column. When we dont specify the column, hibernate checks
for them with the name specified, so when we have same name for both 'name' and
'column' attribute its not necessary to include the column attribute.
So thats it, now u have all the java code stuff, all the .xml files and .jsp files.
just build ur application using ant. You can see two directorys created 'dist' and 'war' as
shown below
Now just restart your tomcat and type the url ' http://localhost:8080/springex/ '
you should be able to see the screen as such if the application runs fine..
just give your inputs and submit the form, you should see the result in success page if no
error occurs during processin your request
now go back again and give another set of details and submit you should be seeing
something like this
Just have a look over the java code and xml files after running the application.
Detailed explanation is not given here as this is just a basic application and can be
understood by the ones who had an overview of all Struts/Spring/Hibernate.
Ok thats all with this example. I just did this one in order to have a pratice over all of these
three. If at all you get any errors, just copy the exception thrown and search in google, I
tried the same way and atlast i got the result. If all the JAR files are placed properly you
wouldnt get any error.
Regards,