SSH是目前进行JavaWeb应用比较广泛的开发框架之一。采用MVC模式开发软件,在SSH结构中的表现为
- Model层----Hibernate+Spring
- View层----JSP、HTML、CSS、JS等
- Controller层----Struts+Spring
下面我们针对一个例子来搭建SSH框架。我们通过用户登录操作,记录用户的登录信息。首先,在设计时我们需要考虑到以下几个问题:
- 用户通过输入用户名、密码、验证码之后点击登录按钮,登录本系统。
- 登录后,系统通过struts的action请求,调用service层的方法记录用户登录信息。
- service层通过调用dao层的方法对数据表进行操作,记录用户登录信息。
- 用户点击退出按钮时,系统通过struts的action请求,调用service层的方法记录用户登出信息。
- service层通过调用dao层的方法对数据表进行操作,记录用户的登出信息。
我们新建一个web工程,并将需要用到的jar包放置在/WEB-INF/lib/目录下。采用ssh目录结构(开发package结构)如下:
- com.log.loginout.action----Struts层的Action类
- com.log.loginout.service----Service层的接口
- com.log.loginout.service.impl----ServiceImpl层的实现类,实现Service层接口
- com.log.loginout.dao----Dao层的接口
- com.log.loginout.dao.imp----DaoImpl层的实现类,实现Dao层接口
下面我们开始建立相应的接口和实体类:首先,建立一个名为Loginoutinfo.java的JavaBean用来映射数据库中相应的数据表,代码如下(以下所有类中的get、set方法省略):
public class Loginoutinfo implements java.io. Serializable
{
//序列化ID
private static final long serialVersionUID = 1L;
//表的主键ID
private Integer loginoutID;
//用户名
private String UserName;
//登录、登出时间
private Date infotime;
//登录方式0:登录;1登出
private Integer logtype;
//备注
private String Notes;
}
在action包中建立Struts的LoginoutAction.java类,代码如下:
public class LoginoutAction extends ActionSupport
{
//定义一个Service对象,有Spring注入
private LoginoutService loginoutService = null ;
//定义一个实体Bean即Hiernate映射
private Loginoutinfo loginoutinfo = null ;
//保存用户登录、登出信息
public String save()
{
//调用Service层的Save方法保存用户登录、登出信息
this .loginoutService.save( this .loginoutinfo);
//struts返回值
return "save" ;
}
}
在Service包中建立一个LoginoutService.java接口,代码如下:
public interface LoginoutService
{
//保存用户登录、登出信息的方法
public void save(Loginoutinfo loginoutinfo);
}
在service.impl包中建立实现LoginoutService接口的类LoginoutServiceImpl.java,代码如下:
public class LoginoutServiceImpl implements LoginoutService
{
//定义一个Dao层的对象,由Spring注入
private LoginoutDao loginoutDao = null ;
//保存用户登录、登出信息到数据表
public synchronized void save(Loginoutinfo loginoutinfo)
{
//通过调用Dao层的对象保存信息
this .loginoutDao.save(loginoutinfo);
}
}
在dao包中建立一个LoginoutDao.java接口,代码如下:
public interface LoginoutDao
{
//保存用户登录、登出信息到数据的方法
public void save(Loginoutinfo loginoutinfo);
}
在dao.impl包中建立实现LoginoutDao接口的类LoginoutDaoImpl.java,代码如下:
public class LoginoutDaoImpl extends HibernateDaoSupport implements LoginoutDao
{
//保存用户登录、登出信息到数据表
public void save(Loginoutinfo loginoutinfo)
{
//使用HibernateDaoSupport类中的HibernateTemplate的save方法保存Bean
this .getHibernateTemplate().save(loginoutinfo);
}
}
到此为止,我们需要用到的所有的Java接口和类都已经完成,但是我们注意到在Action和Service实现类中的loginoutService、loginoutDao对象都没有被初始化。所以我们需要通过Spring的依赖注入机制对这些需要初始化的对象进行注入。首先我们需要建立一个Oracle的数据源,applicationContext.xml配置信息如下:
<bean id ="dataSource" class ="com.mchange.v2.c3p0.ComboPooledDataSource" >
<!-- 设定DriverClass为oracle.jdbc.driver.OracleDriver -->
<property name ="driverClass" value ="oracle.jdbc.driver.OracleDriver" />
<!-- 设定连接URL串 -->
<property name ="jdbcUrl" value ="jdbc:oracle:thin:@127.0.0.1:1521:OracleTest" />
<property name ="properties" >
<props >
<!-- 设定登录用户名 -->
<prop key ="user" > username </prop >
<!-- 设定登录密码 -->
<prop key ="password" > passwd </prop >
</props >
</property >
</bean >
有了Oracle数据库的数据源,下一步我们就可以通过此数据源配置Hibernate的SessionFactory了,具体代码如下:
<bean id ="sessionFactory" class ="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
<property name ="dataSource" ref ="dataSource" />
<!-- 自动载入此目录下的所有hibernate.hbm.xml映射配置文件 -->
<!--
<property name="mappingDirectoryLocations">
<list>
<value>classpath:com/log/common/entity</value>
</list>
</property>
-->
<!-- 手动指定载入hibernate.hbm.xml映射配置文件 -->
<property name ="mappingResources" >
<list >
<value > com/log/loginout/entity/Loginoutinfo.hbm.xml </value >
</list >
</property >
</bean >
可以看到,在配置Hibernate的SessionFactory时,需要配置hibernate的mapping内容,即:载入数据表与JavaBean之间的映射Loginoutinfo.hbm.xml文件,此配置文件的配置内容如下:
<hibernate-mapping >
<!-- 指定JavaBean和数据表的对应关系 -->
<class name ="com.log.loginout.entity.Loginoutinfo" table ="Loginoutinfo" >
<!-- 设定JavaBean中的属性名称和数据库对应的字段名称 -->
<id name ="loginoutID" column ="loginoutID" type ="java.lang.Integer" >
<!-- 设定主键自增方式 -->
<generator class ="increment" />
</id >
<property name ="infotime" column ="infotime" type ="java.util.Date" />
<property name ="PoliceNumber" column ="PoliceNumber" type ="java.lang.String" />
<property name ="logtype" column ="logtype" type ="java.lang.Integer" />
<property name ="Notes" column ="Notes" type ="java.lang.String" />
</class >
</hibernate-mapping >
如果我们需要数据库的事务处理,那么可以在Spring的配置文件applicationContext.xml中加入事务处理的配置项:
<bean id ="transactionManager" class ="org.springframework.orm.hibernate3.HibernateTransactionManager" >
<property name ="sessionFactory" >
<ref local ="sessionFactory" />
</property >
</bean >
<!-- 自动创建事务代理 -->
<bean id ="transactionInterceptor" class ="org.springframework.transaction.interceptor.TransactionInterceptor" >
<property name ="transactionManager" ref ="transactionManager" />
<property name ="transactionAttributes" >
<props >
<prop key ="delete*" > PROPAGATION_REQUIRED </prop >
<prop key ="add*" > PROPAGATION_REQUIRED </prop >
<prop key ="update*" > PROPAGATION_REQUIRED </prop >
<prop key ="save*" > PROPAGATION_REQUIRED </prop >
<prop key ="find*" > PROPAGATION_REQUIRED,readOnly </prop >
<prop key ="*" > PROPAGATION_REQUIRED </prop >
</props >
</property >
</bean >
<!-- 自动代理 -->
<bean id ="autoproxy" class ="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" >
<!-- 可以是Service或DAO层(最好是针对业务层*Service) -->
<property name ="beanNames" >
<list >
<value > *Service </value >
</list >
</property >
<property name ="interceptorNames" >
<list >
<value > transactionInterceptor </value >
</list >
</property >
</bean >
配置好applicationContext.xml文件之后,开始配置记录登录、登出信息业务的Dao层配置文件,daoContext-loginout.xml配置信息如下:
<!-- 定义Dao的实现类 -->
<bean id ="loginoutDao" class ="com.log.loginout.dao.impl.LoginoutDaoImpl" >
<!-- 定义此类的SessionFactory对象 -->
<property name ="sessionFactory" >
<!-- 此对象的初始化bean来源于sessionFactory -->
<ref bean ="sessionFactory" />
</property >
</bean >
</beans >
配置Service层的businessContext-loginout.xml内容如下:
<!-- 定义Service的实现类 -->
<bean id ="loginoutService" class ="com.log.loginout.service.impl.LoginoutServiceImpl" >
<!-- 定义此类中存在一个名为loginoutDao的对象,通过get、set方法取得 -->
<property name ="loginoutDao" >
<!-- 此对象的初始化bean来源于loginoutDao -->
<ref bean ="loginoutDao" />
</property >
</bean >
</beans >
配置Struts层的actionContext-loginout.xml内容如下:
<!-- 定义Struts的Action类 -->
<bean id ="loginoutAction" class ="com.log.loginout.action.LoginoutAction" scope ="prototype" >
<!-- 定义此类中存在一个名为loginoutService的对象,通过get、set方法取得 -->
<property name ="loginoutService" >
<!-- 此对象的初始化bean来源于loginoutService -->
<ref bean ="loginoutService" />
</property >
</bean >
</beans >
配置好Hibernate和Spring的配置文件之后,我们还需要配置Struts.xml文件:
<package name ="systemlog-default" extends ="struts-default" >
</package >
<!-- struts.xml文件系统改变后,系统是否重新加载该文件 -->
<constant name ="struts.configuration.xml.reload" value ="true" > </constant >
<!-- struts.xml中文乱码过滤器 -->
<constant name ="struts.i18n.encoding" value ="UTF-8" />
<constant name ="struts.multipart.maxSize" value ="20000000" />
<constant name ="struts.objectFactory" value ="spring" />
<constant name ="struts.action.extension" value ="do" />
<constant name ="struts.devMode" value ="false" />
<constant name ="struts.enable.DynamicMethodInvocation" value ="false" />
<constant name ="struts.multipart.maxSize" value ="5000000000" />
<constant name ="struts.i18n.encoding" value ="UTF-8" />
<constant name ="struts.locale" value ="zh_CN" />
<constant name ="struts.multipart.saveDir" value ="tmp" />
<constant name ="struts.custom.i18n.resources" value ="messageResouces_zh_CN" />
<!-- 载入记录用户登录登出信息的struts配置文件 -->
<include file ="conf/struts/struts-loginout-config.xml" />
</struts >
对于struts-loginout-config.xml的配置内容如下:
<!-- 配置包名和命名空间 -->
<package name ="loginout" namespace ="/loginout" extends ="systemlog-default" >
<!-- 匹配在此命名空间内所有请求名称(*)到loginoutAction此出由spring指定
匹配第二个内容为调用Action内的方法 -->
<action name ="*" class ="loginoutAction" method ="{1}" >
<!-- 指定action返回内容跳转到相应的jsp画面 -->
<result name ="save" > /index.jsp </result >
</action >
</package >
</struts >
以上内容,我们将Hibernate、Struts、Spring的配置文件全部配置完成,下面还需要配置/WEB-INF/web.xml来使服务器载入web.xml时同时载入Hibernate、Struts、Spring配置文件以及Struts过滤器等等,配置信息如下:
<!-- 其他配置信息与传统web开发一样,此处略 -->
<context-param >
<param-name > contextConfigLocation </param-name >
<param-value >
<!-- 载入指定目录下的配置文件 -->
classpath:conf/spring/applicationContext.xml
,classpath:conf/spring/actionContext-*.xml
,classpath:conf/spring/businessContext-*.xml
,classpath:conf/spring/daoContext-*.xml
</param-value >
</context-param >
<!-- 定义Struts2的FilterDispathcer的Filter -->
<filter >
<filter-name > struts2 </filter-name >
<filter-class >
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class >
</filter >
<!-- FilterDispatcher用来初始化struts2并且处理所有的WEB请求。 -->
<filter-mapping >
<filter-name > struts2 </filter-name >
<url-pattern > /* </url-pattern >
</filter-mapping >
<!-- 其他配置信息与传统web开发一样,此处略 -->
</web-app >
到此为止所有的配置工作结束,但是我们的项目还不能运行。我们还需要新建一个index.jsp页面来提供给用户登录或退出。具体实现与传统的web开发一致,可以用Struts2的标签库或老式的form表单元素来实现用,代码略。