SSH框架搭建全過程詳解


本項目使用Struts2+spring3+hibernate3;

第一步:引入jar包,具體需要哪些包根據實際情況加入。注意:把jar包導入后需要對所有包Add to Build Path;然后對工程名右鍵Build Path——>configure Build Path——>Add External JARS選擇tomcat路徑,添加"servlet-api.jar"  "el-api.jar"  "jsp-api.jar" 這三個jar包。

 

第二步:配置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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
           
    <context:component-scan base-package="ssh.demo.dao,ssh.demo.service,ssh.demo.action" />      
    
    <import resource="dao.xml"/>       
    <import resource="service.xml"/>  
    
</beans>

 

 我把配置根據作用對象不同分別寫在兩個配置文件中,再在applicationContext.xml文件中import.

1.dao.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    
    <!--c3p0連接池參數設置說明 -->
    <!--maxPoolSize表示連接池中保留的最大連接數,default為15 -->
    <!--minPoolSize表示連接池中保留的最小連接數 -->
    <!--initialPoolSize表示初始化時獲取的連接數,取值應該在maxPoolSize和minPoolSize之間,default為3 -->
    <!--maxIdleTime表示最大空閑時間,60秒內未使用則連接被丟棄,若為0則永不丟棄,default為0 -->
    <!--acquireIncrement當連接池用連接被耗盡的時候c3p0一次同時獲取的連接數,default 3 -->
    <!--maxStatements,JDBC的標准參數,用於控制數據源內加載的PreparedStatements數量,但由於預緩存的statements屬於單個connection而不是整個連接池。 所以設置這個參數需要考慮到多方面的因素。如果maxStatements與maxStatementsPerConnection均為0,則緩存被關閉,default 0 -->
    <!--idleConnectionTestPeriod表示每多少秒檢查連接池中的空閑連接,default 0 -->
    <!--acquireRetryAttempts定義在數據庫獲取新連接失敗后重新嘗試的次數,default -->
    <!--breakAfterAcquireFailure獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。但是數據源仍有效保留,並在下次調用getConnection()的時候繼 續嘗試獲取連接。如果設為true,那么在嘗試獲取連接失敗后該數據源將申明已斷開並永久關閉。Default: false -->
    <!--testConnectionOnCheckout因性能消耗大請只在需要的時候使用它。如果設為true那么在每個connection提交的時候都將校驗其有效性。建議使用 idleConnectionTestPeriod或automaticTestTable等方法來提升連接測試的性能。Default: false -->
<!-- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/sshanno" /> <property name="user" value="root" /> <property name="password" value="root" /> <property name="maxPoolSize" value="20" /> <property name="minPoolSize" value="5" /> <property name="maxStatements" value="50" /> <property name="maxIdleTime" value="1800" /> </bean> -->
    
    <!-- location值為參數配置文件的位置 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--dbcp連接池參數設置說明 -->
    <!--initialSize表示池啟動時創建的連接數量 -->
    <!--maxActive表示同一時間可以從池分配的最多連接數量,設置為0時表示無限制 -->
    <!--maxIdle表示池里不會釋放的最多的空閑的連接數量,設置為0時表示無限制 -->
    <!--minIdle表示在不新建連接條件下,池中保持空閑的最少連接數 -->
    <!--removeAbandoned設置自動回收超時連接,value為true或false -->
    <!--removeAbandonedTimeout設置自動回收超時時間(以秒數為單位) -->
    <!--logAbandoned設置在自動回收超時連接的時候打印連接的超時錯誤,value為true或false -->
    <!--maxWait等待超時以毫秒為單位,在拋出異常前,池等待連接被回收的最長時間(當沒有可用連接時),設置為-1表示無限等待 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${driverClassName}" p:url="${url}" p:username="${username}" p:password="${password}" p:maxActive="${maxActive}" p:maxIdle="${maxIdle}" p:minIdle="${minIdle}"/>
    
    <!--在hibernate3中獲取sessionFactory ,hibernate4則class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" -->
    <!--設置屬性說明 -->
    <!--hibernate.dialect設置方言 -->
    <!--hibernate.format_sql輸出格式化的sql -->
    <!--hibernate.show_sql控制台輸出sql -->
    <!--hibernate.hbm2ddl.auto 自動創建|更新|驗證數據庫表結構。有以下幾個參數: create:每次加載hibernate時都會刪除上一次的生成的表,然后根據你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執行,這就是導致數據庫表數據丟失的一個重要原因。 create-drop:每次加載hibernate時根據model類生成表,但是sessionFactory一關閉,表就自動刪除。 update:最常用的屬性,第一次加載hibernate時根據model類會自動建立起表的結構(前提是先建立好數據庫),以后加載hibernate時根據 model類自動更新表結構,即使表結構改變了 但表中的行仍然存在不會刪除以前的行。要注意的是當部署到服務器后,表結構是不會被馬上建立起來的,是要等 應用第一次運行起來后才會。 validate :每次加載hibernate時,驗證創建數據庫表結構,只會和數據庫中的表進行比較,不會創建新表,但是會插入新值。 -->
    <!--current_session_context_class使用緩存機制。(hibernate3:Thread或jta);(hibernate4:org.springframework.orm.hibernate4.SpringSessionContext) -->
    <!--hibernate.cache.provider_class 使用Ehcache緩存;hibernate3是org.hibernate.cache.HashtableCacheProvider;hibernate4是net.sf.ehcache.hibernate.EhCacheProvider -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <!-- <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2005Dialect</prop> -->
                <!-- <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> -->
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="current_session_context_class">Thread</prop>
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
            </props>
        </property>
        <!--自動掃描(實體類)注解包:實體類位置為:com.spring.mvc.entities.User,不能寫成:com.spring.mvc.entities,而要寫成:com.spring.mvc,packagesToScan要比實際上前一層-->
        <property name="packagesToScan" value="ssh.demo..*"/>
        
        
        
        <!-- 對於annotatedClasses只能一個類一個類的寫,不能用*通配符 。可以用packagesToScan掃描包的方式代替annotatedClasses方式-->
        <!-- <property> <list> <value>ssh.demo.*</value> </list> </property> -->
        <!--上面的方法是錯誤的,下面的方法才是正確的。但是當類很多時,可以用packagesToScan掃描包的方式代替 -->
        <!-- <property name="annotatedClasses"> <list> <value>ssh.demo.domain.User</value> <value>ssh.demo.domain.UserLog</value> <value>ssh.demo.domain.Product</value> </list> </property> -->
    </bean>
    
    <!--hibernate3.1以及以上版本取消了hibernateTemplate,hibernate4需要通過getCurrentSession()獲取session -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" p:sessionFactory-ref="sessionFactory" />

</beans>

 

上面設置數據源時使用了外部參數配置文件:jdbc.properties

driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/sshanno?useUnicode=true&characterEncoding=utf-8 username=root password=root maxActive=50 maxIdle=40 minIdle=10 #driverClassName=net.sourceforge.jtds.jdbc.Driver #url=jdbc:jtds:sqlserver://localhost:1433;databaseName=ssh #username=sa #password=sa #maxActive=50 #maxIdle=40 #minIdle=10 #driverClassName=oracle.jdbc.driver.OracleDriver #url=jdbc:oracle:thin:@localhost:1521:orcl #username=cd #password=cd #maxActive=50 #maxIdle=40 #minIdle=10

 

2.service.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
           
    <!--spring對hibernate的事務管理 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory">
    </bean>
    
    <aop:config>
        <aop:pointcut expression="execution(* ssh.demo.service..*(..))" id="serviceMethod"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
    </aop:config>
    
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--默認: isolation:DEFAULT propagation:REQUIRED timeout:-1 事物超時時間由底層事物系統決定 read-only:false rollback-for:所有允許異常回滾 no-rollback-for:所有檢查異常不回滾 -->
            
            <tx:method name="get*" read-only="true"/>
            <tx:method name="do*"/>
        </tx:attributes>
    </tx:advice>

</beans>

 

第三步:配置struts.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <!-- 自動掃描action包 -->
    <!-- 注解需要的jar包:struts2-convention-plugin -->
    <!-- <constant name="struts.convention.default.parent.package" value="default" /> -->
    <constant name="struts.convention.package.locators" value="action" />
     <constant name="struts.convention.classes.reload" value="true" />
     <!-- <constant name="struts.objectFactory" value="spring"/> -->
    <package name="default" namespace="/" extends="struts-default">
        <!-- <action name="product" class="ssh.demo.action.ProdutAction" method="getProducts"> <result name="success">/product.jsp?preparedProducts=true</result> </action> -->
    </package>
</struts>

 

第四步:配置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</display-name> 
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
    
    
     <context-param>  
        <param-name>log4jConfigLocation</param-name>  
        <!-- <param-value>/WEB-INF/classes/log4j.properties</param-value> --> 
        <param-value>classpath:log4j.properties</param-value> 
    </context-param>  
    <context-param>  
        <param-name>log4jRefreshInterval</param-name>  
        <param-value>3000</param-value>  
    </context-param>  
    <listener>  
        <listener-class> org.springframework.web.util.Log4jConfigListener </listener-class>  
    </listener>  
  
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <!-- <param-value>/WEB-INF/classes/applicationContext.xml</param-value> -->
      <param-value>classpath*:applicationContext.xml</param-value>
  </context-param>
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
   <filter>   
      <filter-name>encodingFilter</filter-name>   
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>   
      <init-param>   
          <param-name>encoding</param-name>   
          <param-value>UTF-8</param-value>   
      </init-param>   
  </filter>  
  <filter-mapping>
      <filter-name>encodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping> 
    
     
    <!-- strut2 dispatcher -->
    <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>
            <!-- 為了頁面能用jsp:forward,否則struts2接管請求,跳不到action去。 -->
        <dispatcher>REQUEST</dispatcher>
          <dispatcher>FORWARD</dispatcher>
          <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    
    <!--為解決lazy=true在jsp頁面上遍歷數據,此時相關類(one2many)再查找,沒有session的情況 -->
    <!--getCurrentSession()事務會自動關閉,所以在所有jsp頁面查詢數據都會關閉session。要想在jsp查詢數據庫需要加入下面這個 -->
    <filter> 
        <filter-name>hibernateFilter</filter-name> 
        <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class> 
    </filter>
    <filter-mapping> 
            <filter-name>hibernateFilter</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 

</web-app>

 

第五步:新建實體類

package ssh.demo.domain; import java.io.Serializable; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import org.hibernate.annotations.BatchSize; /** * 用戶表 * * 一般不要使用catalog屬性, * catalog是對應數據庫名稱,比如:在MySQL中數據庫名稱是ssh * 但在MSSQL中,不使用catalog,使用的是schema * MSSQL默認的schema是dbo * @author fox * */ @Entity @Table(name="tbl_user") public class User implements Serializable { private static final long serialVersionUID = -8992313421496945642L; /** * Oracle 下查看序列命令:select * from user_sequences */ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="user_id") private Long id; @Column(name="user_loginname", unique=true, nullable=false) private String loginName; @Column(name="user_loginpassword", nullable=false) private String loginPassword; @OneToMany(mappedBy="user", fetch=FetchType.LAZY) @BatchSize(size=10) private Set<UserLog> userLogs = new HashSet<UserLog>(); public Set<UserLog> getUserLogs() { return userLogs; } public void setUserLogs(Set<UserLog> userLogs) { this.userLogs = userLogs; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public String getLoginPassword() { return loginPassword; } public void setLoginPassword(String loginPassword) { this.loginPassword = loginPassword; } }

 

package ssh.demo.domain; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; /** * 用戶登錄情況表 * * @author fox * */ @Entity @Table(name="tbl_userlog") public class UserLog implements Serializable { private static final long serialVersionUID = -6520978050619047269L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="userlog_id") private Long id; @Column(name="userlog_date", nullable=false) private Date date; @Column(name="userlog_type") private String type; @ManyToOne @JoinColumn(name="user_id") private User user; public String getType() { return type; } public void setType(String type) { this.type = type; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } }

 

tbl_user表和tbl_userlog表是一對多的關系。

第六步:controller層

package ssh.demo.action; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.ServletResponseAware; import org.springframework.web.context.ServletContextAware; import com.opensymphony.xwork2.ActionSupport; public class BaseAction extends ActionSupport implements ServletContextAware, ServletRequestAware, ServletResponseAware { private static final long serialVersionUID = -2778286744226080905L; protected HttpServletRequest request; protected HttpServletResponse response; protected HttpSession session; protected ServletContext application; @Override public void setServletResponse(HttpServletResponse response) { this.response = response; } @Override public void setServletRequest(HttpServletRequest request) { this.request = request; this.session = this.request.getSession(); } @Override public void setServletContext(ServletContext application) { this.application = application; } }
package ssh.demo.action; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import ssh.demo.domain.User; import ssh.demo.service.UserService; import com.opensymphony.xwork2.ModelDriven; /** * 使用注解的方式配置,struts2的action不再是單例,不需要加@scope("prototype") * 而此時,service和dao默認還是單例 * @author fox * */ @Controller @Results({ @Result(name = "input", location = "/login.jsp", type="redirect" , params={"error", "1"}), @Result(name = "success", location = "/index.jsp", type="redirect")}) public class LoginAction extends BaseAction implements ModelDriven<User> { private static final long serialVersionUID = -6335887400814653355L; public LoginAction(){ System.out.println("---LoginAction 構造函數---"); } @Autowired private UserService userService; private User user = new User(); public User getModel() { return this.user; } @Action("/doLogin") public String doLogin() throws Exception { System.out.println("--Hello--"); System.out.println(this.user.getLoginName()); System.out.println(this.user.getLoginPassword()); System.out.println(this.request.getParameter("loginName")); System.out.println(this.request.getParameter("loginPassword")); System.out.println(this.userService); User u = this.userService.getUserLogin(this.user.getLoginName(), this.user.getLoginPassword()); if(u == null) { System.out.println("--登錄失敗---"); return INPUT; } else { System.out.println("--登錄成功---"); this.userService.doSaveUserLog(u); return SUCCESS; } } }

第七步:service層

package ssh.demo.service; import java.util.Date; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import ssh.demo.dao.UserDao; import ssh.demo.dao.UserLogDao; import ssh.demo.domain.User; import ssh.demo.domain.UserLog; @Service("userService") public class UserServiceImpl implements UserService{ public UserServiceImpl(){ System.out.println("---UserService 構造函數---"); } @Autowired private UserDao userDao; @Autowired private UserLogDao userLogDao; @Override public User getUserLogin(String loginName, String loginPassword) { return this.userDao.getUser(loginName, loginPassword); } }

 

第八步:dao層

package ssh.demo.dao; import java.sql.SQLException; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Session; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.stereotype.Repository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.HibernateTemplate; import ssh.demo.domain.User; @Repository("userDao") public class UserDaoImpl extends BaseDao implements UserDao{ public UserDaoImpl(){ System.out.println("---UserDao 構造函數---"); } @Autowired protected HibernateTemplate hibernateTemplate; @Override public User getUser(final String name, final String password) { System.out.println(this.hibernateTemplate); return (User)this.hibernateTemplate.execute(new HibernateCallback<Object>() { @Override public Object doInHibernate(Session session) throws HibernateException, SQLException { return session .createQuery("from User u where u.loginName=:name and u.loginPassword=:password") .setString("name", name) .setString("password", password) .uniqueResult(); } }); } @Override public void saveUser(User user) { this.hibernateTemplate.save(user); } @Override public List<User> getUsers() { return this.hibernateTemplate.loadAll(User.class); } }

 

最后補充:為了方便在控制台看見后台操作的結果,能夠輸出后台執行情況,再加一個文件log4j.properties

 1 ##OFF->FATAL->ERROR->WARN->INFO->DEBUG->ALL
 2 ##ERROR->WARN->INFO->DEBUG
 3 # define a logger named CONSOLE
 4 log4j.rootLogger=INFO, CONSOLE  
 5 # CONSOLE logger - console
 6 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 
 7 # COSOLE Layout 
 8 log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 
 9 # CONSOLE format Layout
10 log4j.appender.CONSOLE.layout.ConversionPattern=%5p %d{yyyy-MM-dd HH:mm:ss,SSS} %c:(%F:%L) - %m%n 

到這里,再寫好相應的jsp頁面就可以運行一個springmvc的網站了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM