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>
<!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>
<!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>
<!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
# 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"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
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"
version="2.4">
<display-name>firstssh</display-name>
<description>this is a simple example</description>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>firstssh.root</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-*.xml,/WEB-INF/action-servlet.xml</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- 用于初始化Spring容器的Listener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 定义整合SiteMesh必须的ActionContextCleanUp Filter
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
</filter>-->
<!-- 定义Struts2的FilterDispathcer的Filter -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<!-- <filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>-->
<!-- FilterDispatcher用来初始化struts2并且处理所有的WEB请求。 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 这是一个产生验证码的servlet -->
<servlet>
<servlet-name>img</servlet-name>
<servlet-class>com.firstssh.servlet.AuthImg</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>img</servlet-name>
<url-pattern>/authImg</url-pattern>
</servlet-mapping>
<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>*.action</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<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>*.action</url-pattern>
</filter-mapping>
<!-- DWR Servlet-->
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>10</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<error-code>401</error-code>
<location>/401.htm</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/403.htm</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.htm</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.htm</location>
</error-page>
</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>
<!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>
* @version 1.0
* Creation date: Dec 23, 2007 6:19:21 PM
*/
package com.firstssh.common.dao;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.dao.DataAccessException;
import com.firstssh.common.util.PaginationSupport;

public interface IGenericDao<T, ID extends Serializable>
{
public void saveOrUpdate(T t);
public T load(Serializable ID);
public T get(Serializable ID) ;
public boolean contains(T t) throws DataAccessException ;
public void delete(T t, LockMode lockMode) throws DataAccessException;
public void delete(T t) throws DataAccessException;
public void deleteAll(Collection<T> entities) throws DataAccessException;
public List<T> find(String queryString, Object value)
throws DataAccessException;
public List<T> find(String queryString, Object[] values)
throws DataAccessException;
public List<T> find(String queryString) throws DataAccessException;
public List<T> findByExample(Object exampleEntity, int firstResult,
int maxResults) throws DataAccessException;
public List<T> findByExample(Object exampleEntity) throws DataAccessException;
public List<T> findByNamedParam(String queryString, String paramName,
Object value) throws DataAccessException ;
public List<T> findByNamedParam(String queryString, String[] paramNames,
Object[] values) throws DataAccessException;
public Object load(Class TClass, Serializable ID, LockMode lockMode)
throws DataAccessException;
public void load(T t, Serializable ID) throws DataAccessException;
public Object load(String TName, Serializable ID, LockMode lockMode)
throws DataAccessException;
public Object load(String TName, Serializable ID)
throws DataAccessException;
public void refresh(T t, LockMode lockMode) throws DataAccessException;
public void refresh(T t) throws DataAccessException;
public Serializable save(T t) throws DataAccessException;
public void saveOrUpdate(String TName, T t) throws DataAccessException;
public void saveOrUpdateAll(Collection<T> entities)
throws DataAccessException;
public void update(T t, LockMode lockMode) throws DataAccessException;
public void update(T t) throws DataAccessException;
public void update(String TName, T t, LockMode lockMode)
throws DataAccessException;
public void update(String TName, T t) throws DataAccessException;
public List<T> loadAll();
public List<T> list();
public PaginationSupport findPageByCriteria(
final DetachedCriteria detachedCriteria, final int pageSize,
final int startIndex);
public PaginationSupport findPageByQuery( final String hsql, final int pageSize,final int startIndex);
}
GenericDao.java内容如下:

/** *//**
*
* @author <a href="mailto:flustar2008@163.com">flustar</a>
* @version 1.0
* Creation date: Dec 23, 2007 11:23:56 PM
*/
package com.firstssh.common.dao;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.firstssh.common.util.PaginationSupport;
@SuppressWarnings("unchecked")
public class GenericDao<T, ID extends Serializable, DAOImpl extends IGenericDao<T, ID>> extends HibernateDaoSupport implements IGenericDao<T, ID>
{
protected Log logger = LogFactory.getLog(getClass());
protected Class<T> entityClass;

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

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

public T load(Serializable ID)
{
T load = (T) getHibernateTemplate().load(getEntityClass(), ID);
return load;
}

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

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

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

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

public void deleteAll(Collection<T> entities) throws DataAccessException
{
getHibernateTemplate().deleteAll(entities);
}
public List<T> find(String queryString, Object value)
throws DataAccessException
{
List<T> find = (List<T>) getHibernateTemplate().find(queryString,
value);
return find;
}
public List<T> find(String queryString, Object[] values)
throws DataAccessException
{
List<T> find = (List<T>) getHibernateTemplate().find(queryString,
values);
return find;
}

public List<T> find(String queryString) throws DataAccessException
{
return (List<T>) getHibernateTemplate().find(queryString);
}
public List<T> findByExample(Object exampleEntity, int firstResult,
int maxResults) throws DataAccessException
{
return getHibernateTemplate().findByExample(exampleEntity, firstResult,
maxResults);
}

public List<T> findByExample(Object exampleEntity) throws DataAccessException
{
return getHibernateTemplate().findByExample(exampleEntity);
}
public List<T> findByNamedParam(String queryString, String paramName,
Object value) throws DataAccessException
{
return getHibernateTemplate().findByNamedParam(queryString, paramName,
value);
}
public List<T> findByNamedParam(String queryString, String[] paramNames,
Object[] values) throws DataAccessException
{
return getHibernateTemplate().findByNamedParam(queryString, paramNames,
values);
}
public Object load(Class TClass, Serializable ID, LockMode lockMode)
throws DataAccessException
{
return getHibernateTemplate().load(TClass, ID, lockMode);
}

public void load(T t, Serializable ID) throws DataAccessException
{
getHibernateTemplate().load(t, ID);
}
public Object load(String TName, Serializable ID, LockMode lockMode)
throws DataAccessException
{
return getHibernateTemplate().load(TName, ID, lockMode);
}
public Object load(String TName, Serializable ID)
throws DataAccessException
{
return getHibernateTemplate().load(TName, ID);
}

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

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

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

public void saveOrUpdate(String TName, T t) throws DataAccessException
{
getHibernateTemplate().saveOrUpdate(TName, t);
}
public void saveOrUpdateAll(Collection<T> entities)
throws DataAccessException
{
getHibernateTemplate().saveOrUpdateAll(entities);
}

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

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

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

public List<T> loadAll()
{
return getHibernateTemplate().loadAll(getEntityClass());
}

public List<T> list()
{
Criteria criteria = getSession().createCriteria(getEntityClass());
return criteria.list();
}
public PaginationSupport findPageByCriteria(
final DetachedCriteria detachedCriteria, final int pageSize,
final int startIndex)
{
return (PaginationSupport) getHibernateTemplate().execute(
new HibernateCallback()
{
public Object doInHibernate(Session session)
throws HibernateException
{
Criteria criteria = detachedCriteria
.getExecutableCriteria(session);
int totalCount = ((Integer) criteria.setProjection(
Projections.rowCount()).uniqueResult())
.intValue();
criteria.setProjection(null);
List items = criteria.setFirstResult(startIndex)
.setMaxResults(pageSize).list();
PaginationSupport ps = new PaginationSupport(items,
totalCount, pageSize, startIndex);
return ps;
}
}, true);
}
public PaginationSupport findPageByQuery( final String hsql, final int pageSize,final int startIndex)
{
return (PaginationSupport)getHibernateTemplate().execute( 
new HibernateCallback()
{ 
public Object doInHibernate(Session session) throws HibernateException, SQLException
{
Query query = session.createQuery(hsql);
int totalCount=query.list().size();
query.setFirstResult(startIndex);
query.setMaxResults(pageSize);
List items = query.list();
PaginationSupport ps = new PaginationSupport(items,
totalCount, pageSize, startIndex);
return ps;
}
},true);
}
}
呵呵,使用了泛型,以后每建立一个Dao都要建立相应的dao接口和实现类,如本例中的IUserDao和UserDao。

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

public interface IUserDao extends IGenericDao<User, Long>
{
public User getUserByName(String username);
public List<User> findAllUser();
public User findUserByNameAndPass(String username, String password);
}

/** *//**
*
* @author <a href="mailto:flustar2008@163.com">flustar</a>
* @version 1.0
* Creation date: Dec 24, 2007 12:38:48 AM
*/
package com.firstssh.dao.impl;
import java.util.List;
import com.firstssh.common.dao.GenericDao;
import com.firstssh.dao.IUserDao;
import com.firstssh.model.User;

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

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

public User findUserByNameAndPass(String username, String password)
{
Object[] params=new Object[]
{username,password};
List<User> userList=find("from User as user where user.username=? and user.password=? ",params);
if(userList!=null&&userList.size()>=1)
{
return userList.get(0);
}
return null;
}


public User getUserByName(String username)
{
List<User> userList=find("from User as user where user.username=?",username);
if(userList!=null&&userList.size()>=1)
{
return userList.get(0);
}
return null;
}
}