Spring2.5.3+Hibernate3.2+Struts2.0.11整合
只有Struts2基礎(chǔ)(初學(xué)Hibernate/Spring第三天就想著整合),有些地方不是很懂,看了網(wǎng)上大部分的例子、blog,百分百的MyEclipse插件,本人不太習(xí)慣使用MyEclipse,主要是Eclipse使用的時間比較長,使用MyEclipse6.0.1時(第一次用)比如你要輸入.getHibernateTemplate()時,輸入點(diǎn)時就有提示,但是當(dāng)我輸入點(diǎn)后面的字母出錯時,只能返回到輸入點(diǎn)之前才按點(diǎn)“.”可以提示,按ALT+/也不會出現(xiàn),是不是我不知道快捷鍵,或是其它的方式,總之我在Eclipse中輸入一半錯誤時按ALT+/可以又出來提示,雖然不是特依賴提示功能,但是用起來還是不爽,畢竟每天都在使用它,哪位要是知道的話煩請告訴一聲bulktree@126.com。
僅僅看了兩天的官方文檔就寫了這個整合的新聞發(fā)布系統(tǒng),感覺蠻好的,是個好的開始 come on!
以下是一個新聞發(fā)布系統(tǒng)的登錄模塊:(兩天看文檔,一夜寫成的,不是很完善,僅僅實現(xiàn)基本的增刪查改功能,主要是整合練習(xí))
首先配置三個框架,有人說要是使用MyEclipse自動生成會有順序Spring->Hibernate->Struts,太依賴工具不是本人的習(xí)慣,這些是后話。
開發(fā)工具Eclipse J2EE Developer Tomcat6.0.13 Mysql 6.0
新建Dynamic Web Project
拷貝工程所需的jar包到WEB-INF/lib下
數(shù)據(jù)庫創(chuàng)建腳本
DROPTABLE context; CREATETABLE context ( id VARCHAR(32) NOTNULLPRIMARYKEY, title VARCHAR(100), times DATETIME, content VARCHAR(500), author VARCHAR(50), click INT, typeVARCHAR(50) ); DROPTABLEuser; CREATETABLEuser ( uid VARCHAR(50) NOTNULLPRIMARYKEY, uname VARCHAR(50), password VARCHAR(50) NOTNULL ); |
在web.xml中配置Struts2和Spring
<filter> <filter-name>Struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.FilterDispatcher </filter-class> </filter> <filter> <filter-name>encodingFilter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encodingFilter</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>Struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> |
項目中我使用的是Tomcat數(shù)據(jù)源配置如下,如果你不使用Tomcat數(shù)據(jù)源也可以在下面的配置文件中配置:
<Context docBase="news-SSH2" path="/news-SSH2" reloadable="true" source="org.eclipse.jst.jee.server:news-SSH2"> <Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/news" password="1234" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/news?autoReconnect=true" username="root"/> </Context> |
也在在配置applicationContext.xml文件中配置數(shù)據(jù)源
<!-- 定義數(shù)據(jù)源Bean,使用C3P0數(shù)據(jù)源實現(xiàn) --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <!-- 指定連接數(shù)據(jù)庫的驅(qū)動 --> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <!-- 指定連接數(shù)據(jù)庫的URL --> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/news"/> <!-- 指定連接數(shù)據(jù)庫的用戶名 --> <property name="user" value="root"/> <!-- 指定連接數(shù)據(jù)庫的密碼 --> <property name="password" value="1234"/> <!-- 指定連接數(shù)據(jù)庫連接池的最大連接數(shù) --> <property name="maxPoolSize" value="20"/> <!-- 指定連接數(shù)據(jù)庫連接池的最小連接數(shù) --> <property name="minPoolSize" value="1"/> <!-- 指定連接數(shù)據(jù)庫連接池的初始化連接數(shù) --> <property name="initialPoolSize" value="1"/> <!-- 指定連接數(shù)據(jù)庫連接池的連接的最大空閑時間 --> <property name="maxIdleTime" value="20"/> </bean> |
在applicationContext.xml中配置sessionFactory
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/news"></property> </bean> <!-- 管理Hibernate --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="mappingResources"> <list> <value>org/bulktree/ssh2/news/vo/User.hbm.xml</value> <value>org/bulktree/ssh2/news/vo/News.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect </value> </property> </bean> |
3. 開始編碼:
我們必須明確Spring框架的體系結(jié)構(gòu),新建以下幾個包
User.java
package org.bulktree.ssh2.news.vo; publicclass User { private String uid; private String uname; private String password; public String getUid() { returnuid; } Getter/setter’’’’’’’’’’’ publicvoid setPassword(String password) { this.password = password; } } |
在User類同包下即org.bulktree.ssh2.news.vo新建User.hbm.xml文件
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.bulktree.ssh2.news.vo"> <class name="User" table="user"> <id column="uid" name="uid" type="string"> <generator class="assigned"/> </id> <property column="uname" name="uname" type="string"/> <property column="password" name="password" type="string"/> </class> </hibernate-mapping> |
新建UserDao.java接口
package org.bulktree.ssh2.news.dao; import java.util.List; import org.bulktree.ssh2.news.vo.User; publicinterface UserDao { /** *增加一個用戶 *@throwsException */ publicvoid addUser(User user) throws Exception; /** *根據(jù)uid/password查詢User *@paramuid *@parampassword *@return *@throwsException */ public User queryByUidAndPassword(String uid, String password) throws Exception; /** *刪除用戶 *@paramuid *@throwsException */ publicvoid delete(String uid) throws Exception; /** *查詢?nèi)坑脩?/span> *@returnList *@throwsException */ public List<User> queryAll() throws Exception; } |
UserDaoImpl.java接口實現(xiàn)類
package org.bulktree.ssh2.news.dao.impl; import java.util.List; import org.bulktree.ssh2.news.dao.UserDao; import org.bulktree.ssh2.news.vo.User; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; /** * 繼承HibernateDaoSuppor類實現(xiàn)getHibernateTemplate() * * @author bulktree * */ public class UserDaoImpl extends HibernateDaoSupport implements UserDao { @Override public void addUser(User user) throws Exception { this.getHibernateTemplate().save(user); } @Override public void delete(String uid) throws Exception { // TODO Auto-generated method stub } @Override public List<User> queryAll() throws Exception { // TODO Auto-generated method stub return null; } @Override public User queryByUidAndPassword(String uid, String password) throws Exception { String hql = "FROM User as u WHERE u.uid=? and u.password=?"; String[] str = new String[] { uid, password }; List<User> users = this.getHibernateTemplate().find(hql, str); if (users != null && users.size() >= 1) { return users.get(0); } else { return null; } } } |
Service層,新建一UserService.java接口
package org.bulktree.ssh2.news.service; publicinterface UserService { /** *添加一個用戶 *@paramuid *@paramuname *@parampassword *@return新增用戶的uid *@throwsException */ public String addUser(String uid, String uname, String password) throws Exception; /** *驗證登錄 *@paramuid *@parampassword *@returnuid *@throwsException */ public String isLogin(String uid, String password) throws Exception; } |
接口實現(xiàn)類
package org.bulktree.ssh2.news.service.impl; import org.bulktree.ssh2.news.dao.UserDao; import org.bulktree.ssh2.news.service.UserService; import org.bulktree.ssh2.news.vo.User; /** * UserService實現(xiàn)類 * * @author bulktree * */ public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public String addUser(String uid, String uname, String password) throws Exception { User user = new User(); user.setUid(uid); user.setUname(uname); user.setPassword(password); userDao.addUser(user); return user.getUid(); } @Override public String isLogin(String uid, String password) throws Exception { User user = userDao.queryByUidAndPassword(uid, password); if(user != null) { return user.getUname(); } else { return null; } } } |
最后我們新建一Action,LoginAction.java
package org.bulktree.ssh2.news.action; import java.util.Map; import org.bulktree.ssh2.news.service.UserService; import org.bulktree.ssh2.news.vo.User; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; /** * 登錄Action * @author bulktree * */ public class LoginAction extends ActionSupport { private User user; private UserService userService; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } @Override public String execute() throws Exception { if (isInvalid(user.getUid())) { this.addFieldError("uid", "登錄ID不能為空"); return INPUT; } if (isInvalid(user.getPassword())) { this.addFieldError("password", "密碼項不能為空"); return INPUT; }
String uname = userService.isLogin(user.getUid(), user.getPassword()); if (uname != null) { Map session = ActionContext.getContext().getSession(); session.put("uname", uname); session.put("uid", user.getUid()); return SUCCESS; } else { this.addFieldError("idorpassword", "登錄ID或密碼錯誤"); return INPUT; } } private boolean isInvalid(String value) { return (value == null || value.length() == 0); } } |
下來就是login.jsp頁面文件了
<center> <div style="color: red"><s:fielderror /><s:actionmessage /></div> <s:form action="login" method="post"> <s:textfield name="user.uid" label="UID" tooltip="ENTER YOUR UID" /> <s:password name="user.password" label="PASSWORD" tooltip="ENTER YOUR PASSWORD" /> <s:submit></s:submit>
</s:form> <s:a href="regist.jsp">REGIST NEW COUNT</s:a></center> |
下來就是applicationContext.xml文件的配置
<bean id="userdao" class="org.bulktree.ssh2.news.dao.impl.UserDaoImpl"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean>
<!-- bean配置 --> <bean id="newsdao" class="org.bulktree.ssh2.news.dao.impl.NewsDaoImpl"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean> <bean id="loginAction" class="org.bulktree.ssh2.news.action.LoginAction"> <property name="userService"> <ref bean="userservice"/> </property> </bean>
</bean> |
·bean的id屬性就是對應(yīng)類class的實例
·property元素的name屬性為bean的class屬性對應(yīng)類的屬性名,
·ref為引用bean,引用的是bean的id
Struts.xml文件完整配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.i18n.encoding" value="UTF-8" /> <package name="SSH2" extends="struts-default"> <action name="login" class="loginAction"> <result>/addNews.jsp</result> <result name="input">/login.jsp</result> </action>
<action name="regist" class="registAction"> <result>/login.jsp</result> <result name="input">/regist.jsp</result> </action>
<action name="listall" class="listallAction"> <result>/newsList.jsp</result> <result name="input">/addNews.jsp</result> </action>
<action name="notice" class="noticeAction"> <result type="redirect-action">listall</result> <result name="input">/addNews.jsp</result> </action> </package>
</struts> |
·form表單的action對應(yīng)struts.xml文件中的action的name屬性,由于Strust由Spring管理,struts.xml文件中的action元素class屬性對應(yīng)的是applicationContext.xml文件中bean元素id屬性
最后貼上完整的applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <!-- 使用JNDI數(shù)據(jù)源 --> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/news"></property> </bean> <!-- 管理Hibernate --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="mappingResources"> <list> <value>org/bulktree/ssh2/news/vo/User.hbm.xml</value> <value>org/bulktree/ssh2/news/vo/News.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect </value> </property> </bean>
<bean id="userdao" class="org.bulktree.ssh2.news.dao.impl.UserDaoImpl"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean>
<!-- bean配置 --> <bean id="newsdao" class="org.bulktree.ssh2.news.dao.impl.NewsDaoImpl"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean> <bean id="userservice" class="org.bulktree.ssh2.news.service.impl.UserServiceImpl"> <property name="userDao"> <ref bean="userdao"/> </property> </bean>
<bean id="newservice" class="org.bulktree.ssh2.news.service.impl.NewsServiceImpl"> <property name="newsDao"> <ref bean="newsdao"/> </property> </bean>
<bean id="loginAction" class="org.bulktree.ssh2.news.action.LoginAction"> <property name="userService"> <ref bean="userservice"/> </property> </bean>
<bean id="registAction" class="org.bulktree.ssh2.news.action.RegistAction"> <property name="userService"> <ref bean="userservice"/> </property> </bean> <bean id="noticeAction" class="org.bulktree.ssh2.news.action.NoticeNewsAction"> <property name="newsService"> <ref bean="newservice"/> </property> </bean>
<bean id="listallAction" class="org.bulktree.ssh2.news.action.QueryAllNews"> <property name="newsDao"> <ref bean="newsdao"/> </property> </bean> </beans> |
·applicationContext.xml文件默認(rèn)加載路徑classpath下,也就是WEB-INF下
·整個工程沒有用到hibernate.cfg.xml文件,Spring管理了hibernate,這個文件不起什么作用了,但是最好還是加上
<?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="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <mapping class="com.bulktree.ssh2.vo.User" package="com.bulktree.ssh2.vo" resource="com/bulktree/ssh2/vo/User.hbm.xml"/> </session-factory> </hibernate-configuration> |