Struts2+spring2+hibernate3整合方案
最近闲来无事可做,于是开始学习struts2。Struts2和struts1、webwork2有什么区别我也不说了,网上有很多这方面的资料。以前在项目中从未使用过struts,一直使用spring+hibernate,现在既然学习了Struts,也不能浪费,于是乎开始琢磨着怎么整合这3个框架。整合原理以spring为容器,管理hibernate的DAO和Struts2的Action。
一、 准备工作
Struts2.06+spring2.5+hibernate3.2+jdk6.0+myeclipse6.0+tomcat5.5+mysql5.0
以上是整合的原料。下面以一个注册登陆的例子来开始我们的整合过程。
这个例子很简单,下面是它的sql脚本内容:
CREATE TABLE `user` (
  `userid` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) NOT NULL,
  `password` varchar(16) NOT NULL,
  `email` varchar(30) NOT NULL,
  PRIMARY KEY (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf-8;
二、 开始行动
包结构可以参考下图
 
图一

 图二

图三
1) Struts部分:建立struts.xml和struts.properties
Struts.xml内容如下:
 
 <?xml version="1.0" encoding="UTF-8"?>
<?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" >
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" >
 <struts>
<struts>
 <package name="user_curd" extends="struts-default" >
    <package name="user_curd" extends="struts-default" >
 <global-results>
        <global-results>
 <!-- 下面定义的结果对所有的Action都有效 -->
            <!-- 下面定义的结果对所有的Action都有效 -->
 <result name="exception">/error.jsp</result>
            <result name="exception">/error.jsp</result>
 </global-results>
        </global-results>

 <global-exception-mappings>
        <global-exception-mappings>
 <!-- 指Action抛出Exception异常时,转入名为exception的结果。 -->
            <!-- 指Action抛出Exception异常时,转入名为exception的结果。 -->
 <exception-mapping exception="java.lang.Exception" result="exception"/>
            <exception-mapping exception="java.lang.Exception" result="exception"/>
 </global-exception-mappings>
        </global-exception-mappings>

 <action name="Login" class="LoginAction">
        <action name="Login" class="LoginAction">
 <result name="success">/success.jsp</result>
            <result name="success">/success.jsp</result>    
 <result name="input">/login.jsp</result>
            <result name="input">/login.jsp</result>
 </action>
        </action>
 <action name="Regist" class="RegistAction">
        <action name="Regist" class="RegistAction">
 <result name="success">/success.jsp</result>
            <result name="success">/success.jsp</result>    
 <result name="input">/regist.jsp</result>
            <result name="input">/regist.jsp</result>
 </action>
        </action>
 </package>
    </package> 
 
            
 </struts>
</struts>

Struts.properties内容如下:
 
struts.devMode=false
struts.enable.DynamicMethodInvocation=true
struts.i18n.reload=true
struts.ui.theme=xhtml
struts.locale=zh_CN
struts.i18n.encoding=UTF-8
struts.objectFactory=spring
struts.objectFactory.spring.autoWire=name
struts.serve.static.browserCache=false
struts.url.includeParams=none
2) 建立User.java和User.hbm.xml、jdbc.properties:
User.java内容如下:
 

 /** *//**
/** *//** 
 *
 * 
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @version 1.0
 * @version 1.0 
 * Creation date: Dec 23, 2007 1:55:28 PM
 * Creation date: Dec 23, 2007 1:55:28 PM
 */
 */
 package com.firstssh.model;
package com.firstssh.model;

 import java.io.Serializable;
import java.io.Serializable;


 public class User implements Serializable
public class User implements Serializable  {
{
 private int id;
    private int id;
 private String username;
    private String username;
 private String password;
    private String password;
 private String email;
    private String email;


 public int getId()
    public int getId()  {
{
 return id;
        return id;
 }
    }


 public void setId(int id)
    public void setId(int id)  {
{
 this.id = id;
        this.id = id;
 }
    }


 public String getUsername()
    public String getUsername()  {
{
 return username;
        return username;
 }
    }


 public void setUsername(String username)
    public void setUsername(String username)  {
{
 this.username = username;
        this.username = username;
 }
    }


 public String getPassword()
    public String getPassword()  {
{
 return password;
        return password;
 }
    }


 public void setPassword(String password)
    public void setPassword(String password)  {
{
 this.password = password;
        this.password = password;
 }
    }


 public String getEmail()
    public String getEmail()  {
{
 return email;
        return email;
 }
    }


 public void setEmail(String email)
    public void setEmail(String email)  {
{
 this.email = email;
        this.email = email;
 }
    }
 }
}

User.hbm.xml内容:
 
 <?xml version="1.0"?>
<?xml version="1.0"?>
 <!DOCTYPE hibernate-mapping PUBLIC
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 <hibernate-mapping
<hibernate-mapping 
 package="com.firstssh.model">
    package="com.firstssh.model">

 <class name="User" table="User">
    <class name="User" table="User">
 <id name="id" column="userid">
        <id name="id" column="userid">
 <generator class="identity" />
            <generator class="identity" />
 </id>
        </id>    
 <property name="username"
        <property name="username"
 column="username"
                  column="username"
 not-null="true"
                  not-null="true"
 length="20"
                  length="20"
 />
        />
 <property name="password"
        <property name="password"
 column="password"
                  column="password"
 not-null="true"
                  not-null="true"
 length="16" />
                  length="16" />
 <property name="email"
        <property name="email"
 column="email"
                  column="email"
 not-null="true"
                  not-null="true"
 length="30"/>
                  length="30"/>
 </class>
    </class>
 
    
 </hibernate-mapping>
</hibernate-mapping>
jdbc.properties内容如下:
 
datasource.type=mysql
datasource.driverClassName=com.mysql.jdbc.Driver
datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
datasource.username=root
datasource.password=123456
datasource.maxActive=10
datasource.maxIdle=2
datasource.maxWait=120000
datasource.whenExhaustedAction=1
datasource.validationQuery=select 1 from dual
datasource.testOnBorrow=true
datasource.testOnReturn=false
c3p0.acquireIncrement=3
c3p0.initialPoolSize=3
c3p0.idleConnectionTestPeriod=900
c3p0.minPoolSize=2
c3p0.maxPoolSize=50
c3p0.maxStatements=100
c3p0.numHelperThreads=10
c3p0.maxIdleTime=600
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect=org.hibernate.dialect.MySQLMyISAMDialect
hibernate.jdbc.batch_size=25
hibernate.jdbc.fetch_size=50
hibernate.show_sql=true
hibernate.connection.release_mode=after_transaction
3) Spirng部分:为了清晰把Spring的配置文件拆分成以下几部分applicationContext-dao.xml、appliationContext-service.xml、applicationContext-hibernate.xml、action-servlet.xml。
applicationContext-hibernate.xml内容:
 
 <?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
 <beans>
<beans>
 <bean id="propertyConfigurer"
<bean id="propertyConfigurer"
 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 <property name="locations">
    <property name="locations">
 <list>
        <list>
 <!--  <value>WEB-INF/mail.properties</value>-->
            <!--  <value>WEB-INF/mail.properties</value>-->
 <value>WEB-INF/jdbc.properties</value>
            <value>WEB-INF/jdbc.properties</value>
 <!--  <value>WEB-INF/oscache.properties</value>-->
            <!--  <value>WEB-INF/oscache.properties</value>-->
 </list>
        </list>
 </property>
    </property>
 </bean>
</bean>
 <!-- MailSender used by EmailAdvice -->
<!-- MailSender used by EmailAdvice -->
 <!--
<!--
 <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
 <property name="host" value="${mail.host}"/>
    <property name="host" value="${mail.host}"/>
 </bean>
    </bean>
 -->
-->
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
 destroy-method="close" dependency-check="none">
    destroy-method="close" dependency-check="none">
 <property name="driverClass">
    <property name="driverClass">
 <value>${datasource.driverClassName}</value>
        <value>${datasource.driverClassName}</value>
 </property>
    </property>
 <property name="jdbcUrl">
    <property name="jdbcUrl">
 <value>${datasource.url}</value>
        <value>${datasource.url}</value>
 </property>
    </property>
 <property name="user">
    <property name="user">
 <value>${datasource.username}</value>
        <value>${datasource.username}</value>
 </property>
    </property>
 <property name="password">
    <property name="password">
 <value>${datasource.password}</value>
        <value>${datasource.password}</value>
 </property>
    </property>
 <property name="acquireIncrement">
    <property name="acquireIncrement">
 <value>${c3p0.acquireIncrement}</value>
        <value>${c3p0.acquireIncrement}</value>
 </property>
    </property>
 <property name="initialPoolSize">
    <property name="initialPoolSize">
 <value>${c3p0.initialPoolSize}</value>
        <value>${c3p0.initialPoolSize}</value>
 </property>
    </property>
 <property name="minPoolSize">
    <property name="minPoolSize">
 <value>${c3p0.minPoolSize}</value>
        <value>${c3p0.minPoolSize}</value>
 </property>
    </property>
 <property name="maxPoolSize">
    <property name="maxPoolSize">
 <value>${c3p0.maxPoolSize}</value>
        <value>${c3p0.maxPoolSize}</value>
 </property>
    </property>
 <property name="maxIdleTime">
    <property name="maxIdleTime">
 <value>${c3p0.maxIdleTime}</value>
        <value>${c3p0.maxIdleTime}</value>
 </property>
    </property>
 <property name="idleConnectionTestPeriod">
    <property name="idleConnectionTestPeriod">
 <value>${c3p0.idleConnectionTestPeriod}</value>
        <value>${c3p0.idleConnectionTestPeriod}</value>
 </property>
    </property>
 <property name="maxStatements">
    <property name="maxStatements">
 <value>${c3p0.maxStatements}</value>
        <value>${c3p0.maxStatements}</value>
 </property>
    </property>
 <property name="numHelperThreads">
    <property name="numHelperThreads">
 <value>${c3p0.numHelperThreads}</value>
        <value>${c3p0.numHelperThreads}</value>
 </property>
    </property>
 </bean>
</bean>
 <bean id="sessionFactory"
<bean id="sessionFactory"
 class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
 <property name="dataSource">
    <property name="dataSource">
 <ref local="dataSource" />
        <ref local="dataSource" />
 </property>
    </property>
 <property name="mappingResources">
    <property name="mappingResources">
 <list>
        <list>
 <value>com/firstssh/model/User.hbm.xml</value>
            <value>com/firstssh/model/User.hbm.xml</value>
 </list>
        </list>
 </property>
    </property>
 <property name="hibernateProperties">
    <property name="hibernateProperties">
 <props>
        <props>
 <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
 <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
 <prop key="hibernate.jdbc.fetch_size">
            <prop key="hibernate.jdbc.fetch_size">
 ${hibernate.jdbc.fetch_size}
                ${hibernate.jdbc.fetch_size}
 </prop>
            </prop>
 <prop key="hibernate.jdbc.batch_size">
            <prop key="hibernate.jdbc.batch_size">
 ${hibernate.jdbc.batch_size}
                ${hibernate.jdbc.batch_size}
 </prop>
            </prop>
 </props>
        </props>
 </property>
    </property>
 </bean>
</bean>
 <!-- 配置事务管理器bean,使用HibernateTransactionManager事务管理器 -->
<!-- 配置事务管理器bean,使用HibernateTransactionManager事务管理器 -->
 <bean id="transactionManager"
<bean id="transactionManager"
 class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
 <!-- 为事务管理器注入sessionFactory" -->
        <!-- 为事务管理器注入sessionFactory" -->
 <property name="sessionFactory" ref="sessionFactory"/>
        <property name="sessionFactory" ref="sessionFactory"/>
 </bean>
</bean>
 <!-- 配置事务拦截器Bean -->
<!-- 配置事务拦截器Bean -->
 <bean id="transactionInterceptor"
<bean id="transactionInterceptor"
 class="org.springframework.transaction.interceptor.TransactionInterceptor">
    class="org.springframework.transaction.interceptor.TransactionInterceptor">
 <!-- 为事务拦截器bean注入一个事物管理器 -->
    <!-- 为事务拦截器bean注入一个事物管理器 -->
 <property name="transactionManager" ref="transactionManager"></property>
    <property name="transactionManager" ref="transactionManager"></property>
 <property name="transactionAttributes">
    <property name="transactionAttributes">
 <!-- 定义事务传播属性 -->
    <!-- 定义事务传播属性 -->
 <props>
        <props>
 <prop key="insert*">PROPAGATION_REQUIRED</prop>
                <prop key="insert*">PROPAGATION_REQUIRED</prop>
 <prop key="update*">PROPAGATION_REQUIRED</prop>
                <prop key="update*">PROPAGATION_REQUIRED</prop>
 <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
 <prop key="add*">PROPAGATION_REQUIRED</prop>
                <prop key="add*">PROPAGATION_REQUIRED</prop>
 <prop key="remove*">PROPAGATION_REQUIRED</prop>
                <prop key="remove*">PROPAGATION_REQUIRED</prop>
 <prop key="delete*">PROPAGATION_REQUIRED</prop>
                <prop key="delete*">PROPAGATION_REQUIRED</prop>
 <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
 <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
 <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
 <prop key="change*">PROPAGATION_REQUIRED</prop>
                <prop key="change*">PROPAGATION_REQUIRED</prop>
 <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
 </props>
        </props>
 </property>
    </property>
 </bean>
</bean>
 <!-- 定义BeanNameAutoProxyCreator -->
<!-- 定义BeanNameAutoProxyCreator -->
 <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
 <!-- 指定满足哪些bean自动生成业务代理 -->
    <!-- 指定满足哪些bean自动生成业务代理 -->
 <property name="beanNames">
    <property name="beanNames">
 <!-- 需要自动创建事务代理的bean -->
    <!-- 需要自动创建事务代理的bean -->
 <list>
        <list>
 <value>userService</value>
            <value>userService</value>
 </list>
        </list>
 <!-- 其它需要自动创建事务代理的bean -->
        <!-- 其它需要自动创建事务代理的bean -->
 </property>
    </property>
 <property name="interceptorNames">
    <property name="interceptorNames">
 <list>
        <list>
 <value>transactionInterceptor</value>
            <value>transactionInterceptor</value>
 <!-- 可增加其它的interceptor -->
            <!-- 可增加其它的interceptor -->
 </list>
        </list>
 </property>
    </property>
 </bean>
</bean>
 </beans>
</beans>

applicationContext-dao.xml内容:
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<!-- 根DAO -->
<bean id="genericDao" class="com.firstssh.common.dao.GenericDao">
    <property name="sessionFactory">
        <ref bean="sessionFactory" />
    </property>
</bean>
<bean id="userDao" class="com.firstssh.dao.impl.UserDao" parent="genericDao" />
</beans>
applicationContext-service.xml内容:
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="userService" class="com.firstssh.service.impl.UserService">
    <property name="userDao">
        <ref bean="userDao"/>
    </property>
</bean>
<bean id="validateName" class="com.firstssh.common.Bean.ValidateName">
    <property name="userService">
        <ref local="userService"/>
    </property>
</bean>
</beans>
action-servlet.xml内容:
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
    <bean id="LoginAction" class="com.firstssh.action.LoginAction"
        scope="prototype">
        <property name="userService" ref="userService" />
    </bean>
    <bean id="RegistAction" class="com.firstssh.action.RegistAction"
        scope="prototype">
        <property name="userService" ref="userService" />
    </bean>
</beans>
以上几个xml文件的内容暂且不要理会,继续往下看,你就自动明白的,不用我解释。
4)日志部分:log4j.properties 、commons-logging.properties
log4j.properties内容:
 
# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
log4j.rootLogger=INFO, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=${firstssh.root}/WEB-INF/logs/firstssh.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files.
log4j.appender.logfile.MaxBackupIndex=3
# Pattern to output: date priority [category] - message
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
# OpenSymphony Stuff
log4j.logger.com.opensymphony=INFO
log4j.logger.org.apache.struts2=INFO
# Spring Stuff
log4j.logger.org.springframework=INFO
# Hibernate Stuff
log4j.logger.org.hiberante=INFO
commons-logging.properties
内容:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
5)web.xml
 
 <?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
 <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
 version="2.4">
 version="2.4">
 <display-name>firstssh</display-name>
 <display-name>firstssh</display-name>
 <description>this is a simple example</description>
 <description>this is a simple example</description>
 <context-param>
 <context-param>
 <param-name>webAppRootKey</param-name>
  <param-name>webAppRootKey</param-name>
 <param-value>firstssh.root</param-value>
  <param-value>firstssh.root</param-value>
 </context-param>
 </context-param>
 
 
 <context-param>
 <context-param>
 <param-name>contextConfigLocation</param-name>
  <param-name>contextConfigLocation</param-name>
 <param-value>/WEB-INF/applicationContext-*.xml,/WEB-INF/action-servlet.xml</param-value>
  <param-value>/WEB-INF/applicationContext-*.xml,/WEB-INF/action-servlet.xml</param-value>
 </context-param>
 </context-param>
 <context-param>
 <context-param>
 <param-name>log4jConfigLocation</param-name>
  <param-name>log4jConfigLocation</param-name>
 <param-value>/WEB-INF/log4j.properties</param-value>
  <param-value>/WEB-INF/log4j.properties</param-value>
 </context-param>
 </context-param>
 <listener>
 <listener>
 <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
 </listener>
 </listener>
 <!-- 用于初始化Spring容器的Listener -->
 <!-- 用于初始化Spring容器的Listener -->
 <listener>
    <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
    </listener>
 
 
 
 
 <!-- 定义整合SiteMesh必须的ActionContextCleanUp Filter
 <!-- 定义整合SiteMesh必须的ActionContextCleanUp Filter 
 <filter>
 <filter>
 <filter-name>struts-cleanup</filter-name>
  <filter-name>struts-cleanup</filter-name>
 <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
  <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
 </filter>-->
 </filter>-->
 <!-- 定义Struts2的FilterDispathcer的Filter -->
 <!-- 定义Struts2的FilterDispathcer的Filter -->
 <filter>
    <filter>
 <filter-name>struts2</filter-name>
        <filter-name>struts2</filter-name>
 <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
 </filter>
    </filter>

 <!--   <filter-mapping>
   <!--   <filter-mapping>
 <filter-name>struts-cleanup</filter-name>
        <filter-name>struts-cleanup</filter-name>
 <url-pattern>/*</url-pattern>
        <url-pattern>/*</url-pattern>
 </filter-mapping>-->
    </filter-mapping>-->
 <!-- FilterDispatcher用来初始化struts2并且处理所有的WEB请求。 -->
 <!-- FilterDispatcher用来初始化struts2并且处理所有的WEB请求。 -->
 <filter-mapping>
    <filter-mapping>
 <filter-name>struts2</filter-name>
        <filter-name>struts2</filter-name>
 <url-pattern>/*</url-pattern>
        <url-pattern>/*</url-pattern>
 </filter-mapping>
    </filter-mapping>
 
    
 <!-- 这是一个产生验证码的servlet -->
   <!-- 这是一个产生验证码的servlet -->
 <servlet>
    <servlet>
 <servlet-name>img</servlet-name>
        <servlet-name>img</servlet-name>
 <servlet-class>com.firstssh.servlet.AuthImg</servlet-class>
        <servlet-class>com.firstssh.servlet.AuthImg</servlet-class>
 </servlet>
    </servlet>
 
  
 <servlet-mapping>
    <servlet-mapping>
 <servlet-name>img</servlet-name>
        <servlet-name>img</servlet-name>
 <url-pattern>/authImg</url-pattern>
     <url-pattern>/authImg</url-pattern>
 </servlet-mapping>
    </servlet-mapping>
 <filter>
    <filter>   
 <filter-name>encodingFilter</filter-name>
        <filter-name>encodingFilter</filter-name>   
 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>   
 <init-param>
        <init-param>   
 <param-name>encoding</param-name>
            <param-name>encoding</param-name>   
 <param-value>utf-8</param-value>
            <param-value>utf-8</param-value>   
 </init-param>
        </init-param>   
 </filter>
    </filter>   
 <filter-mapping>
    <filter-mapping>   
 <filter-name>encodingFilter</filter-name>
        <filter-name>encodingFilter</filter-name>   
 <url-pattern>*.action</url-pattern>
        <url-pattern>*.action</url-pattern>   
 </filter-mapping>
    </filter-mapping>   
 <filter-mapping>
    <filter-mapping>   
 <filter-name>encodingFilter</filter-name>
        <filter-name>encodingFilter</filter-name>   
 <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jsp</url-pattern>   
 </filter-mapping>
    </filter-mapping>
 <filter>
    <filter>   
 <filter-name>hibernateFilter</filter-name>
        <filter-name>hibernateFilter</filter-name>   
 <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>   
 </filter>
    </filter> 
 <filter-mapping>
    <filter-mapping>   
 <filter-name>hibernateFilter</filter-name>
        <filter-name>hibernateFilter</filter-name>   
 <url-pattern>*.action</url-pattern>
        <url-pattern>*.action</url-pattern>   
 </filter-mapping>
    </filter-mapping> 
 
    
 <!-- DWR Servlet-->
    <!-- DWR Servlet-->
 <servlet>
  <servlet>
 <servlet-name>dwr-invoker</servlet-name>
    <servlet-name>dwr-invoker</servlet-name>
 <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
    <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
 <init-param>
    <init-param>
 <param-name>debug</param-name>
      <param-name>debug</param-name>
 <param-value>true</param-value>
      <param-value>true</param-value>
 </init-param>
    </init-param>
 </servlet>
  </servlet>

 <servlet-mapping>
  <servlet-mapping>
 <servlet-name>dwr-invoker</servlet-name>
    <servlet-name>dwr-invoker</servlet-name>
 <url-pattern>/dwr/*</url-pattern>
    <url-pattern>/dwr/*</url-pattern>
 </servlet-mapping>
  </servlet-mapping>
 
  
 <session-config>
    <session-config>   
 <session-timeout>10</session-timeout>
        <session-timeout>10</session-timeout>   
 </session-config>
    </session-config> 
 
    
 <welcome-file-list>
  <welcome-file-list>
 <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
  </welcome-file-list>
 <error-page>
  <error-page>
 <error-code>401</error-code>
    <error-code>401</error-code>
 <location>/401.htm</location>
    <location>/401.htm</location>
 </error-page>
  </error-page>
 <error-page>
  <error-page>
 <error-code>403</error-code>
    <error-code>403</error-code>
 <location>/403.htm</location>
    <location>/403.htm</location>
 </error-page>
  </error-page>
 <error-page>
  <error-page>
 <error-code>404</error-code>
    <error-code>404</error-code>
 <location>/404.htm</location>
    <location>/404.htm</location>
 </error-page>
  </error-page>
 <error-page>
  <error-page>
 <error-code>500</error-code>
    <error-code>500</error-code>
 <location>/500.htm</location>
    <location>/500.htm</location>
 </error-page>
  </error-page>
 </web-app>
</web-app>

 
6)dwr.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
<dwr>
    <!-- 检查用户名是否存在 ValidateName的映射文件-->
    <allow>
      <create  creator="spring" javascript="ValidateName" >
          <param name="beanName" value="validateName"/>
          <include method="valid"/>
      </create>
     </allow>
</dwr>
三、 开始编码:
以下是DAO部分的核心代码:
IGenericDao.java内容如下:
 

 /** *//**
/** *//** 
 *
 *
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @version 1.0
 * @version 1.0 
 * Creation date: Dec 23, 2007 6:19:21 PM
 * Creation date: Dec 23, 2007 6:19:21 PM
 */
 */
 package com.firstssh.common.dao;
package com.firstssh.common.dao;

 import java.io.Serializable;
import java.io.Serializable;
 import java.util.Collection;
import java.util.Collection;
 import java.util.List;
import java.util.List;

 import org.hibernate.LockMode;
import org.hibernate.LockMode;
 import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.DetachedCriteria;
 import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessException;
 import com.firstssh.common.util.PaginationSupport;
import com.firstssh.common.util.PaginationSupport;


 public interface IGenericDao<T, ID extends Serializable>
public interface IGenericDao<T, ID extends Serializable>  {
{
 public T load(ID id) throws DataAccessException;
    public T load(ID id) throws DataAccessException;

 public T get(ID id)throws DataAccessException;
    public T get(ID id)throws DataAccessException;

 public boolean contains(T t) throws DataAccessException;
    public boolean contains(T t) throws DataAccessException;

 public void refresh(T t, LockMode lockMode) throws DataAccessException;
    public void refresh(T t, LockMode lockMode) throws DataAccessException;

 public void refresh(T t) throws DataAccessException;
    public void refresh(T t) throws DataAccessException;

 public Serializable save(T t) throws DataAccessException;
    public Serializable save(T t) throws DataAccessException;

 public void saveOrUpdate(T t) throws DataAccessException;
    public void saveOrUpdate(T t) throws DataAccessException;

 public void saveOrUpdateAll(Collection<T> entities)
    public void saveOrUpdateAll(Collection<T> entities)
 throws DataAccessException;
            throws DataAccessException;

 public void update(T t, LockMode lockMode) throws DataAccessException;
    public void update(T t, LockMode lockMode) throws DataAccessException;

 public void update(T t) throws DataAccessException;
    public void update(T t) throws DataAccessException;

 public void delete(T t, LockMode lockMode) throws DataAccessException;
    public void delete(T t, LockMode lockMode) throws DataAccessException;

 public void delete(T t) throws DataAccessException;
    public void delete(T t) throws DataAccessException;

 public void deleteAll(Collection<T> entities) throws DataAccessException;
    public void deleteAll(Collection<T> entities) throws DataAccessException;

 public List<T> find(String queryString, Object value)
    public List<T> find(String queryString, Object value)
 throws DataAccessException;
            throws DataAccessException;

 public List<T> find(String queryString, Object[] values)
    public List<T> find(String queryString, Object[] values)
 throws DataAccessException;
            throws DataAccessException;

 public List<T> find(String queryString) throws DataAccessException;
    public List<T> find(String queryString) throws DataAccessException;

 public List<T> list()throws DataAccessException;
    public List<T> list()throws DataAccessException;
 
    
 public List<T> findByNamedQuery(String queryName)throws DataAccessException ;
    public List<T> findByNamedQuery(String queryName)throws DataAccessException ;
 
    
 public List<T> findByNamedQuery(String queryName, Object value)throws DataAccessException ;
        public List<T> findByNamedQuery(String queryName, Object value)throws DataAccessException ;
 
    
 public List<T> findByNamedQuery(String queryName, Object[] values)throws DataAccessException ;
        public List<T> findByNamedQuery(String queryName, Object[] values)throws DataAccessException ;
 
    

 public PaginationSupport findPageByCriteria(
    public PaginationSupport findPageByCriteria(
 final DetachedCriteria detachedCriteria, final int pageSize,
            final DetachedCriteria detachedCriteria, final int pageSize,
 final int startIndex);
            final int startIndex);

 public PaginationSupport findPageByQuery(final String hql,
    public PaginationSupport findPageByQuery(final String hql,
 final String countHql, final int pageSize, final int startIndex);
            final String countHql, final int pageSize, final int startIndex);

 }
}
GenericDao.java内容如下:

 /** *//**
/** *//** 
 *
 *
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @version 1.0
 * @version 1.0 
 * Creation date: Dec 23, 2007 11:23:56 PM
 * Creation date: Dec 23, 2007 11:23:56 PM
 */
 */
 package com.firstssh.common.dao;
package com.firstssh.common.dao;

 import java.io.Serializable;
import java.io.Serializable;
 import java.lang.reflect.ParameterizedType;
import java.lang.reflect.ParameterizedType;
 import java.sql.SQLException;
import java.sql.SQLException;
 import java.util.Collection;
import java.util.Collection;
 import java.util.List;
import java.util.List;

 import org.apache.commons.logging.Log;
import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.LogFactory;
 import org.hibernate.Criteria;
import org.hibernate.Criteria;
 import org.hibernate.HibernateException;
import org.hibernate.HibernateException;
 import org.hibernate.LockMode;
import org.hibernate.LockMode;
 import org.hibernate.Query;
import org.hibernate.Query;
 import org.hibernate.Session;
import org.hibernate.Session;
 import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.DetachedCriteria;
 import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Projections;
 import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessException;
 import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateCallback;
 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 import com.firstssh.common.util.PaginationSupport;
import com.firstssh.common.util.PaginationSupport;

 @SuppressWarnings("unchecked")
@SuppressWarnings("unchecked")
 public class GenericDao<T, ID extends Serializable> extends HibernateDaoSupport
public class GenericDao<T, ID extends Serializable> extends HibernateDaoSupport

 implements IGenericDao<T, ID>
        implements IGenericDao<T, ID>  {
{
 private Log logger = LogFactory.getLog(getClass());
    private Log logger = LogFactory.getLog(getClass());

 protected Class<T> entityClass;
    protected Class<T> entityClass;


 public GenericDao()
    public GenericDao()  {
{

 }
    }


 protected Class getEntityClass()
    protected Class getEntityClass()  {
{

 if (entityClass == null)
        if (entityClass == null)  {
{
 entityClass = (Class<T>) ((ParameterizedType) getClass()
            entityClass = (Class<T>) ((ParameterizedType) getClass()
 .getGenericSuperclass()).getActualTypeArguments()[0];
                    .getGenericSuperclass()).getActualTypeArguments()[0];
 logger.debug("T class = " + entityClass.getName());
            logger.debug("T class = " + entityClass.getName());
 }
        }
 return entityClass;
        return entityClass;
 }
    }


 public void saveOrUpdate(T t) throws DataAccessException
    public void saveOrUpdate(T t) throws DataAccessException  {
{
 this.getHibernateTemplate().saveOrUpdate(t);
        this.getHibernateTemplate().saveOrUpdate(t);
 }
    }


 public T load(ID id) throws DataAccessException
    public T load(ID id) throws DataAccessException  {
{
 T load = (T) getHibernateTemplate().load(getEntityClass(), id);
        T load = (T) getHibernateTemplate().load(getEntityClass(), id);
 return load;
        return load;
 }
    }


 public T get(ID id) throws DataAccessException
    public T get(ID id) throws DataAccessException  {
{
 T load = (T) getHibernateTemplate().get(getEntityClass(), id);
        T load = (T) getHibernateTemplate().get(getEntityClass(), id);
 return load;
        return load;
 }
    }


 public boolean contains(T t) throws DataAccessException
    public boolean contains(T t) throws DataAccessException  {
{
 return getHibernateTemplate().contains(t);
        return getHibernateTemplate().contains(t);
 }
    }


 public void delete(T t, LockMode lockMode) throws DataAccessException
    public void delete(T t, LockMode lockMode) throws DataAccessException  {
{
 getHibernateTemplate().delete(t, lockMode);
        getHibernateTemplate().delete(t, lockMode);
 }
    }


 public void delete(T t) throws DataAccessException
    public void delete(T t) throws DataAccessException  {
{
 getHibernateTemplate().delete(t);
        getHibernateTemplate().delete(t);
 }
    }


 public void deleteAll(Collection<T> entities) throws DataAccessException
    public void deleteAll(Collection<T> entities) throws DataAccessException  {
{
 getHibernateTemplate().deleteAll(entities);
        getHibernateTemplate().deleteAll(entities);
 }
    }

 public List<T> find(String queryString, Object value)
    public List<T> find(String queryString, Object value)

 throws DataAccessException
            throws DataAccessException  {
{
 List<T> find = (List<T>) getHibernateTemplate()
        List<T> find = (List<T>) getHibernateTemplate()
 .find(queryString, value);
                .find(queryString, value);
 return find;
        return find;
 }
    }

 public List<T> find(String queryString, Object[] values)
    public List<T> find(String queryString, Object[] values)

 throws DataAccessException
            throws DataAccessException  {
{
 List<T> find = (List<T>) getHibernateTemplate().find(queryString,
        List<T> find = (List<T>) getHibernateTemplate().find(queryString,
 values);
                values);
 return find;
        return find;
 }
    }


 public List<T> find(String queryString) throws DataAccessException
    public List<T> find(String queryString) throws DataAccessException  {
{
 return (List<T>) getHibernateTemplate().find(queryString);
        return (List<T>) getHibernateTemplate().find(queryString);
 }
    }


 public void refresh(T t, LockMode lockMode) throws DataAccessException
    public void refresh(T t, LockMode lockMode) throws DataAccessException  {
{
 getHibernateTemplate().refresh(t, lockMode);
        getHibernateTemplate().refresh(t, lockMode);
 }
    }


 public void refresh(T t) throws DataAccessException
    public void refresh(T t) throws DataAccessException  {
{
 getHibernateTemplate().refresh(t);
        getHibernateTemplate().refresh(t);
 }
    }


 public Serializable save(T t) throws DataAccessException
    public Serializable save(T t) throws DataAccessException  {
{
 return getHibernateTemplate().save(t);
        return getHibernateTemplate().save(t);
 }
    }

 public void saveOrUpdateAll(Collection<T> entities)
    public void saveOrUpdateAll(Collection<T> entities)

 throws DataAccessException
            throws DataAccessException  {
{
 getHibernateTemplate().saveOrUpdateAll(entities);
        getHibernateTemplate().saveOrUpdateAll(entities);
 }
    }


 public void update(T t, LockMode lockMode) throws DataAccessException
    public void update(T t, LockMode lockMode) throws DataAccessException  {
{
 getHibernateTemplate().update(t, lockMode);
        getHibernateTemplate().update(t, lockMode);
 }
    }


 public void update(T t) throws DataAccessException
    public void update(T t) throws DataAccessException  {
{
 getHibernateTemplate().update(t);
        getHibernateTemplate().update(t);
 }
    }



 public List<T> list() throws DataAccessException
    public List<T> list() throws DataAccessException  {
{
 return getHibernateTemplate().loadAll(getEntityClass());
        return getHibernateTemplate().loadAll(getEntityClass());

 }
    }

 public List<T> findByNamedQuery(String queryName)
    public List<T> findByNamedQuery(String queryName)

 throws DataAccessException
            throws DataAccessException  {
{
 return getHibernateTemplate().findByNamedQuery(queryName);
        return getHibernateTemplate().findByNamedQuery(queryName);
 }
    }

 public List<T> findByNamedQuery(String queryName, Object value)
    public List<T> findByNamedQuery(String queryName, Object value)

 throws DataAccessException
            throws DataAccessException  {
{
 return getHibernateTemplate().findByNamedQuery(queryName, value);
        return getHibernateTemplate().findByNamedQuery(queryName, value);
 }
    }

 public List<T> findByNamedQuery(String queryName, Object[] values)
    public List<T> findByNamedQuery(String queryName, Object[] values)

 throws DataAccessException
            throws DataAccessException  {
{
 return getHibernateTemplate().findByNamedQuery(queryName, values);
        return getHibernateTemplate().findByNamedQuery(queryName, values);
 }
    }

 public PaginationSupport findPageByCriteria(
    public PaginationSupport findPageByCriteria(
 final DetachedCriteria detachedCriteria, final int pageSize,
            final DetachedCriteria detachedCriteria, final int pageSize,

 final int startIndex)
            final int startIndex)  {
{
 return (PaginationSupport) getHibernateTemplate().execute(
        return (PaginationSupport) getHibernateTemplate().execute(

 new HibernateCallback()
                new HibernateCallback()  {
{
 public Object doInHibernate(Session session)
                    public Object doInHibernate(Session session)

 throws HibernateException
                            throws HibernateException  {
{
 Criteria criteria = detachedCriteria
                        Criteria criteria = detachedCriteria
 .getExecutableCriteria(session);
                                .getExecutableCriteria(session);
 int totalCount = ((Integer) criteria.setProjection(
                        int totalCount = ((Integer) criteria.setProjection(
 Projections.rowCount()).uniqueResult())
                                Projections.rowCount()).uniqueResult())
 .intValue();
                                .intValue();
 criteria.setProjection(null);
                        criteria.setProjection(null);
 List items = criteria.setFirstResult(startIndex)
                        List items = criteria.setFirstResult(startIndex)
 .setMaxResults(pageSize).list();
                                .setMaxResults(pageSize).list();
 PaginationSupport ps = new PaginationSupport(items,
                        PaginationSupport ps = new PaginationSupport(items,
 totalCount, pageSize, startIndex);
                                totalCount, pageSize, startIndex);
 return ps;
                        return ps;
 }
                    }
 }, true);
                }, true);
 }
    }


 public  PaginationSupport findPageByQuery( final  String hql, final String countHql,final int pageSize,final int startIndex)
    public  PaginationSupport findPageByQuery( final  String hql, final String countHql,final int pageSize,final int startIndex) {
{ 
 return (PaginationSupport)getHibernateTemplate().execute(
         return (PaginationSupport)getHibernateTemplate().execute( 

 new  HibernateCallback()
         new  HibernateCallback()  {
{ 

 public  Object doInHibernate(Session session)  throws  HibernateException, SQLException
           public  Object doInHibernate(Session session)  throws  HibernateException, SQLException  {
{ 
 int totalCount=((Integer) session.createQuery(countHql).iterate().next()).intValue();
               int totalCount=((Integer) session.createQuery(countHql).iterate().next()).intValue(); 
 Query query  =  session.createQuery(hql);
               Query query  =  session.createQuery(hql);
 query.setFirstResult(startIndex);
                 query.setFirstResult(startIndex); 
 query.setMaxResults(pageSize);
                 query.setMaxResults(pageSize); 
 List items  = query.list();
                 List items  = query.list();
 PaginationSupport ps = new PaginationSupport(items,
              PaginationSupport ps = new PaginationSupport(items,
 totalCount, pageSize, startIndex);
           totalCount, pageSize, startIndex);
 return ps;
              return ps;
 
                 
 }
                 } 
 },true);
           },true); 
 }
      }

 }
}

呵呵,使用了泛型,以后每建立一个Dao都要建立相应的dao接口和实现类,如本例中的IUserDao和UserDao。
 

 /** *//**
/** *//** 
 *
 *
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @version 1.0
 * @version 1.0 
 * Creation date: Dec 24, 2007 12:47:57 AM
 * Creation date: Dec 24, 2007 12:47:57 AM
 */
 */
 package com.firstssh.dao;
package com.firstssh.dao;

 import java.util.List;
import java.util.List;

 import com.firstssh.common.dao.IGenericDao;
import com.firstssh.common.dao.IGenericDao;
 import com.firstssh.model.User;
import com.firstssh.model.User;


 public interface IUserDao extends IGenericDao<User, Integer>
public interface IUserDao extends IGenericDao<User, Integer>  {
{
 
    
 public User getUserByName(String username);
    public User getUserByName(String username);

 public List<User> findAllUser();
    public List<User> findAllUser();

 public User findUserByNameAndPass(String username, String password);
    public User findUserByNameAndPass(String username, String password);
 }
}  
 

 /** *//**
/** *//** 
 *
 *
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @author <a href="mailto:flustar2008@163.com">flustar</a>
 * @version 1.0
 * @version 1.0 
 * Creation date: Dec 24, 2007 12:38:48 AM
 * Creation date: Dec 24, 2007 12:38:48 AM
 */
 */
 package com.firstssh.dao.impl;
package com.firstssh.dao.impl;

 import java.util.List;
import java.util.List;

 import com.firstssh.common.dao.GenericDao;
import com.firstssh.common.dao.GenericDao;
 import com.firstssh.dao.IUserDao;
import com.firstssh.dao.IUserDao;
 import com.firstssh.model.User;
import com.firstssh.model.User;


 public class UserDao extends GenericDao<User,Integer> implements IUserDao
public class UserDao extends GenericDao<User,Integer> implements IUserDao {
{


 public List<User> findAllUser()
    public List<User> findAllUser()  {
{
 
        
 return (List<User>)find("from User");
        return (List<User>)find("from User");
 }
    }


 public User findUserByNameAndPass(String username, String password)
    public User findUserByNameAndPass(String username, String password)  {
{

 Object[] params=new Object[]
        Object[] params=new Object[] {username,password};
{username,password};
 List<User> userList=find("from User as user where user.username=? and user.password=? ",params);
        List<User> userList=find("from User as user where user.username=? and user.password=? ",params);

 if(userList!=null&&userList.size()>=1)
        if(userList!=null&&userList.size()>=1) {
{
 return userList.get(0);
            return userList.get(0);
 }
        }
 return null;
        return null;
 }
    }



 public User getUserByName(String username)
    public User getUserByName(String username)  {
{
 List<User> userList=find("from User as user where user.username=?",username);
        List<User> userList=find("from User as user where user.username=?",username);

 if(userList!=null&&userList.size()>=1)
        if(userList!=null&&userList.size()>=1) {
{
 return userList.get(0);
            return userList.get(0);
 }
        }
 return null;
        return null;
 }
    }

 }
}

还有好多文件的代码没有贴出来,我实在不忍心再复制、粘贴下去了(浪费大家那么多时间),有兴趣的可以下载这个例子的源代码(由于这个例子牵涉的jar包比较大我就不把它们放进去了),我想以上这些文件的内容我就不用解释了,因为大家都学过SSH。本人初次整合它们,并没有使用这个整合方案做过项目,一定还有某些方面考虑的还不是太成熟,哪位大侠看了,还请多多批评指正,也希望谁有更好的整合方案,也共享一下,大家共同进步,共同提高!~^_^