eclipse下的ssh框架整合过程及測试
最近在搭建Stuts2+hibernate+spring的框架,网上看的教程,大部分都是非常easy的步骤。没有比較具体的步骤以及每一个步骤完毕之后怎样检查是否配置成功。下面是笔者依据自己搭建的过程进行了总结。有兴趣的可按下面步骤搭建。
整体说来配置的步骤起始比較简单。可是由于三个框架的版本号较多,常常会由于一些包的不匹配而报错误。
全部下文所涉及的代码包。已总体打包到http://download.csdn.net/detail/q19334473/8937743可直接下载。
因本教程主要介绍SSH框架的搭建。关于ECLIPSE、java虚拟机、TOMCAT的配置将不再阐述,直接自WEB程序的搭建開始介绍。
所用的工具及相关包清单
开发工具:
Eclipse Java EE IDE forWebDevelopers.Version: Luna Service Release 2 (4.4.2)
JDK: jdk1.6.0_39;
TOMCAT: apache-tomcat-6.0.43;
三大框架的版本号:
hibernate-distribution-3.3.1.GA-dist
struts-2.3.20
spring-2.5.6
数据库为了方便刚開始学习的人,使用的是ACCESS作为数据库;因此教程中数据库使用的是sun.jdbc.odbc.JdbcOdbcDriver的驱动(JDK自带rt.jar中的底层包,不用额外下载),若实际的应用中不建议使用该驱动。
假设要使用ORACLE等其它数据库可自行下载对应驱动。
普通WEB程序的建立与測试
file>new>DynamicWeb Project 新建立一个动态webproject
填写须要搭建的project的基本信息:
依照默认配置Finish就可以。完毕后左边的文件夹结构例如以下
一个空白的WEBproject已经建好,先进行下该WEBproject的測试。
在WebContent目录下建立一个index.jsp页面。
注意,眼下WEB-INF下的页面是默认不能被同意訪问的。
測试页面index.jsp代码很easy:
index.jsp
<%@ page language="java"contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type"content="ext/html; charset=utf-8"> <title>welcome</title> </head> <body> hello web! </body> </html>
选中index.jsp>右键> run as > run on server
按默认选项完毕后在IDE里显演示样例如以下:
WEB执行的基础环境等已搭建完毕。无论怎么说,已经成功了第一步!
,
以下開始搭建struts2框架。配置与独立測试
首先是复制全部struts2的包到web-inf的lib文件加下,eclipse不会自己复制。所以必须手动复制下面。
又一次配置Web.xml文件:代码例如以下
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>ssh-2</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>default.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
此处添加了filter的配置文件。对URL中全部的/*进行过滤拦截;
在web-inf下新建classes目录。后期全部的框架配置文件都放在里面,方便读取。注意classes目录的名字不能任意更改。
另外在web-inf下新建pages目录放置收保护的JSP文件,pages可依据自己的想法改动名字。
如今先新建一个struts.xml文件,文件代码例如以下:
struts.xml
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD StrutsConfiguration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation"value="true" /> <package name="action" extends="struts-default"> <action name="login" class="ywcai.ssh.action.LoginAction"> <result>/WEB-INF/pages/success.jsp</result> </action> </package> </struts>
主要是这个标签下的内容
<actionname="login"class="ywcai.ssh.action.loginAction">
标识url接收到名为”login”的action请求,该请求将由ywcai.ssh.action包以下的loginAction这个类的execute方法处理,须要注意大写和小写,不能有误。默觉得配置方法即是採用execute方法。
<result>/WEB-INF/pages/success.jsp</result>
依据方法返回的值重定向页面到“/WEB-INF/pages/success.jsp”页面。这里默认返回”success”值。
如今stuts2的配置文件已经改动好。
须要编写处理action的类,
类名和上面action里面的class名字保持一致;
先选中java resources路径下的src目录,新建一个class。
Package名字,这里我任意编写的包名字ywcai.ssh.action
Name既填写你的类名,以下复选框均不要勾选。我这里相应上面的配置文件,新建了一个叫LoginAction的类,因为是搭建配置环境,这里我没有继承其它类,实际应用中依据自己的需求进行处理。
在类里面,加入一个int属性、加入一个String属性,做測试。而且分别编写set、get方法。
另外就是写一个execute方法。代码例如以下:
LoginAction.java
package ywcai.ssh.action; public classLoginAction { private int id ; private String username; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String execute() { return "success"; } }
接下来编写一个表单页面index.jsp放置在根文件夹,编写一个success.jsp文件,放置在pages文件夹。
index.jsp可直接訪问。suceess.jsp则必须通过action处理后方可訪问。
index.jsp里面简单的编写一个表单,代码例如以下:
index.jsp
<%@ page language="java"contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="s"uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type"content="text/html; charset=utf-8"> <title>welcome</title> </head> <body> <s:form action="login"> <s:textfield name="id" label="id"></s:textfield> <br> <s:textfield name="username" label="用户名"></s:textfield> <br> <s:submit value="提交"></s:submit> </s:form> </body> </html>
success.jsp将index.jsp提交的表单内容经过LoginAction处理后打印出来,代码例如以下
success.jsp
<%@ page language="java"contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="s"uri="/struts-tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type"content="text/html; charset=utf-8"> <title>success</title> </head> <body> id:<s:property value="id"/> <br/> name:<s:property value="username"/> </body> </html>
这里value的id,username必须好LoginAction里面的属性匹配,而LoginAction的属性里形參名字必须与index.jsp提交的表单属性名字一致。否则则须要通过requst对数据进行处理。
接下来struts2的环境即測试页面也搭建完毕,文件夹结构例如以下:
选择index.jsp 打开run as server进行測试,页面例如以下:
提交后页面跳转至page/success.jsp,页面例如以下:
直接在浏览器输入WEB-INF/pages/success.jsp。无法訪问,例如以下所看到的:
直接输入 login?id=xxx&username=test 也能够訪问。 这里对于login和login.action两种方式,struts2都能够进行默认处理,.action的后缀能够依据自己的想法在struts2的配置文件里进行改动。
这里能够自行研究struts2的教程,就不予以过多描写叙述。
好,到如今,基本上struts2也基本上配置完毕。
Spring框架的配置与独立測试
首先导入Spring的包
编写web.xml代码,改动后代码例如以下:
web.xml
<?xml version="1.0"encoding="UTF-8"?
> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <display-name>ssh-2</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>default.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
<param-value>classpath:applicationContext.xml</param-value>这里描写叙述了spring配置文件名及路径,classpath:及代表了web-inf/classes的路径。
接下来在web-inf/classes下添加applicationContext.xml文件,代码例如以下:
applicationContext.xml<?xml version="1.0"encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd" default-autowire="byName" default-lazy-init="true"> <bean id="testspring" class="ywcai.ssh.acion.LoginAction"> </bean> </beans>
当中id="testspring" 作为Struts2.xml文件里 action的class名称, class填写bean的id。
class="ywcai.ssh.action.LoginAction"该bean引入的类名
LoginAction.java文件与上面保持一样,例如以下:
LoginAction.java
package ywcai.ssh.action; public class LoginAction { private int id; private String username; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String execute() { return "success"; } }
Struts.xml文件代码例如以下:
Struts.xml
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD StrutsConfiguration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation"value="true" /> <package name="action" extends="struts-default"> <action name="login" class="testspring"> <result>/WEB-INF/pages/success.jsp</result> </action> </package> </struts>
Index.jsp和success.jsp页面代码不变。
打开index.jsp页面測试,页面和之前用struts2效果一致,外表看不出不论什么变化。例如以下:
提交后:
以下建一个类进行单独測试。
先在原来的LoginAction.java类里添加一个test函数;
public void test() { System.out.println("运行了test()"); }
新建包名ywcai.ssh.test
新建类,类名TestSpring, 而且建立一个main函数入口。代码例如以下:
TestSpring.java
package ywcai.ssh.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import ywcai.ssh.action.LoginAction; public classTestSpring { public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); LoginAction la=(LoginAction)ac.getBean("testspring"); la.test(); } }
打开并选中TestSpring文件,例如以下图所看到的:
选择下面按纽
在classes以下新建log4j.properties,打印工作日志。
代码例如以下
log4j.properties
# Configure logging for testing:optionally with log file log4j.rootLogger=INFO, Console, File ###### Console appender definition####### # All outputs currently set to bea ConsoleAppender. log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c{3}] %m%n log4j.appender.Console.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c] %m%n ###### File appender definition####### log4j.appender.File=org.apache.log4j.DailyRollingFileAppender log4j.appender.File.File=spring.log log4j.appender.File.Append=false log4j.appender.File.layout=org.apache.log4j.PatternLayout log4j.appender.File.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c] %m%n
执行Java Application ,结果例如以下图所看到的:
控制台输出test函数打印的文字,測试通过。
Spring配置完毕。
配置hibernate框架与独立測试
首先引入所须要的包,例如以下所看到的:
当中hibernate3是基本的包。hibernate包提供数据库方言的类,c3p0是支持数据库连接池的类。
新建数据连接的配置文件代码例如以下:
hibernate.cfg.xml
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class"> sun.jdbc.odbc.JdbcOdbcDriver </property> <property name="connection.url"> jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb,*.accdb)};DBQ=D:\\db\\test.accdb </property> <!-- 数据库连接设置 --> <property name="eclipse.connection.profile">access</property> <property name="connection.username"></property> <property name="connection.password"></property> <property name="dialect">com.hxtt.support.hibernate.HxttAccessDialect</property> <!-- show_sql 生成SQL语句 --> <property name="show_sql">true</property> <!-- SQL dialect 方言 --> <property name="hibernate.dialect"> org.hibernate.dialect.SQLServerDialect </property> <mapping resource="ywcai/ssh/service/UserInfo.hbm.xml"/> </session-factory> </hibernate-configuration>
数据库放在D盘的db目录下,名字是test.accbd;
映射文件为UserInfo.hbm.xml,放在ywcai.ssh.service这个包以下。
UserInfo.hbm.xml文件与数据库的字段相相应,代码例如以下
UserInfo.hbm.xml
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="ywcai.ssh.service"> <class name="UserInfo" table="users"> <id name="id"type="java.lang.Integer"> <column name="id"></column> <generator class="increment" /> </id> <property name="username" type="java.lang.String"> <column name="username"length="200"></column> </property> </class> </hibernate-mapping>
当中name=”UserInfo” 相应UserInfo.java类,table=”users” 指数据库表名
<generator class="increment"/>指key是自增长的,这个须要和数据库的ID字段属性保持一致。
Property 指向UserInfo.java类中的属性,type是该属性的字符类型,columu 是字段名字,两者相互相应。
UserInfo.java代码
package ywcai.ssh.service; public classUserInfo { private int id; private String username; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
在新建一个ywcai.ssh.dao包。一个工厂类
工厂类代码例如以下
HibernateSessionFactory.java
package ywcai.ssh.dao; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; importorg.hibernate.cfg.Configuration; public class HibernateSessionFactory{ privatestatic final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); privatestatic final Configuration cfg = new Configuration(); privatestatic SessionFactory sessionFactory; publicstatic Session getcurrentSession() throws HibernateException { Sessionsession = threadLocal.get(); if(session == null || session.isOpen() == false) { if(sessionFactory == null) { try{ sessionFactory= cfg.configure().buildSessionFactory(); }catch (Exception e) { e.printStackTrace(); } } session= sessionFactory.openSession(); threadLocal.set(session); } returnsession; } publicstatic void closeSession() throws HibernateException { Sessionsession = threadLocal.get(); threadLocal.set(null); if(session != null) { session.close(); } } }
相关的hibernate 基础类部署完毕,。在ywcai.ssh.test包下新建一个代main函数的类进行測试。
測试文件代码:
TestHibernate.java
package ywcai.ssh.test; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import ywcai.ssh.service.UserInfo; public classTestHibernate { public static void main(String[] args) { // TODO Auto-generated method stub UserInfouserinfo=new UserInfo(); userinfo.setId(7); userinfo.setUsername("測试測试測试"); Configurationcfg= newConfiguration(); SessionFactorysf = cfg.configure().buildSessionFactory(); Sessionsession= sf.openSession(); session.beginTransaction(); session.update(userinfo); session.getTransaction().commit(); session.close(); sf.close(); System.out.println("运行完毕"); } }
先查看数据库ID=7的行。数据初始值为“a”
运行TestHibernate.java,显示结果例如以下:
再次打开数据库查看第7行,username已改动为”測试測试測试”;
Hibernate框架的測试已成功完毕。
接下来完毕Spring对hibernate、stuts2的接管
上面的 hibernate.cfg.xml 相关数据库的配置信息将在applicationContext.xml文件里配置。hibernate.cfg.xml不会被用到。另外应spring包中已有了sessionFactory,因此HibernateSessionFactory.java文件也不须要了。
能够删除这两个文件。
先在ywcai.ssh.dao包下建一个UsersDao.java文件。继承自HibernateDaoSupport类,
UserDao.java
package ywcai.ssh.dao; importorg.hibernate.HibernateException; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class UsersDao extendsHibernateDaoSupport { publicvoid updateObject(Object obj) throws HibernateException { getHibernateTemplate().update(obj); System.out.println("运行了update"); } }
这里由于是測试。因此相同仅仅写了update方法。通过该方法能够改动数据库内容;
在在ywcai.ssh.service包下建一个业务处理类。代码例如以下
UserEdit.java
package ywcai.ssh.service; import org.hibernate.HibernateException; import ywcai.ssh.dao.*; public classUserEdit { private UsersDao usersDao; public UsersDao getUsersDao(){ return usersDao; } public void setUsersDao(UsersDao usersDao) { this.usersDao = usersDao; } public void updateUser(Object obj) throws HibernateException { usersDao.updateObject(obj); System.out.println("OK"); } }
使用这个类做主要业务的处理。
applicationContext.xml
<?xml version="1.0"encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd" default-autowire="byName" default-lazy-init="true"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" lazy-init="false"> <property name="driverClass" value="sun.jdbc.odbc.JdbcOdbcDriver" /> <property name="jdbcUrl" value="jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb,*.accdb)};DBQ=D:\\db\\test.accdb" /> <property name="user" value=""/> <property name="password" value=""/> <property name="testConnectionOnCheckin" value="true" /> <property name="automaticTestTable" value="TestTable" /> <property name="idleConnectionTestPeriod" value="18000" /> <property name="maxIdleTime" value="25000" /> <property name="testConnectionOnCheckout" value="true" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref local="dataSource" /> </property> <property name="mappingResources"> <list> <value>ywcai/ssh/service/UserInfo.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop> <prop key="show_sql">true</prop> <prop key="hibernate.jdbc.batch_size">20</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="usersDao" class="ywcai.ssh.dao.UsersDao"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean> <!--用户注冊业务逻辑类 --> <bean id="useredit" class="ywcai.ssh.service.UserEdit"> <property name="usersDao"> <ref bean="usersDao" /> </property> </bean> <bean id="loginAction" class="ywcai.ssh.action.LoginAction"> <property name="useredit"> <ref bean="useredit" /> </property> </bean> </beans>
<propertyname="useredit">指 该bean指向的类new一个useredit对象,而new这个useredit对象所使用的类为 <beanid="useredit"class="ywcai.ssh.service.UserEdit">指向的类,
<refbean="useredit"/> 则是将这个useredit对象注入到LoginAction类。
这里loginaction将表单的信息传递给了userinfo对象。并在接下来的applicationconext.xml配置文件里对全部相关的对象进行了注入
接下来是在改动业务控制的action类,代码例如以下
LoginAction.java
package ywcai.ssh.action; import com.opensymphony.xwork2.ModelDriven; import ywcai.ssh.service.UserEdit; import ywcai.ssh.service.UserInfo; public classLoginAction implements ModelDriven<UserInfo> { /** * */ private UserInfo userinfo=new UserInfo(); public UserEdit useredit; @Override public UserInfo getModel() { // TODO Auto-generated method stub return userinfo; } public void setUserinfo(UserInfo userinfo) { this.userinfo = userinfo; } public void setUseredit(UserEdit useredit) { this.useredit = useredit; } public UserEdit getUseredit(){ return useredit; } public String execute() { try { useredit.updateUser(this.getModel()); return "success"; }catch(Exception e) { e.printStackTrace(); return"error"; } } public void test() { System.out.println("运行了test()"); } }
execute方法中userEdit通过applicationcontext.xml文件进行了注入;
注意struts2.xml的action中 class填写为applicationContext.xml的bean的id > loginAction
struts.xml
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD StrutsConfiguration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation"value="true" /> <package name="action" extends="struts-default"> <action name="login" class="loginAction"> <result>/WEB-INF/pages/success.jsp</result> </action> </package> </struts>
index.jsp和success.jsp代码不变,现进行測试:
数据库原始数据例如以下。我们这次改动id=12的username数据,这条记录的username字段内容为hhh;
打开index.jsp页面例如以下所看到的:
提交后例如以下:
好了,大功告成!