最近笔者在做一个纵向项目,需要一个网站支持,想到之前学习的J2EE的知识,于是决定使用SSH框架快速搭建一个网站框架,但是事与愿违,搭建过程中出现了很多的小错误,在这里把最终正确的做法记录下来给大家做参考。(在这里以登陆逻辑为例)。
基本的项目结构
登陆逻辑的基本代码结构如下所示:
- src
- action
- LoginAction.java
- service
- IUserManageService.java(接口)
- UserManageServiceImpl.java
- dataAccess
- dao
- IUserDao.java(接口)
- UserDaoImpl.java
- dto
- User.java
- User.hbm.xml
- struts.xml
- webContent
- WEB-INF
- beans.xml
- web.xml
- WebPages
- Login.jsp
- LoginSuccess.jsp
当JSP页面向后台发送请求时,LoginAction将调用UserManageService的Login方法,在Login方法里,具体的数据库读取则依靠DAO文件实现。PS:按常理说Struts.xml文件应该放在WEB-INF目录下,但是这里笔者使用的Struts 2.3不允许这么做,只能放在src目录下面(疑问)。
整合Hibernate和Spring
在beans.xml中配置Hibernate
这个环节比较简单,有一个固定的模式可以遵循,首先对于项目中的POJO对象User应建立基本的映射文件user.hbm.xml,原先写在Hibernate.cfg.xml中的数据源配置和属性配置则需要转移到Spring的配置文件中(如beans.xml),一般配置如下:
beans.xml
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<!-- 指定连接数据库的驱动 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<!-- 指定连接数据库的URL -->
<property name="jdbcUrl" value="jdbc:mysql://localhost/hibernate"/>
<!-- 指定连接数据库的用户名 -->
<property name="user" value="root"/>
<!-- 指定连接数据库的密码 -->
<property name="password" value="123456"/>
<!-- 指定连接数据库连接池的最大连接数 -->
<property name="maxPoolSize" value="20"/>
<!-- 指定连接数据库连接池的最小连接数 -->
<property name="minPoolSize" value="1"/>
<!-- 指定连接数据库连接池的初始化连接数 -->
<property name="initialPoolSize" value="1"/>
<!-- 指定连接数据库连接池的连接的最大空闲时间 -->
<property name="maxIdleTime" value="20"/>
</bean>
<!--配置hibernate -->
<!-- p:dataSource-ref为SessionFactory注入数据源引用 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:dataSource-ref="dataSource">
<!-- 加载hibernate的映射文件*.hbm.xml -->
<property name="mappingResources">
<list>
<value>dataAccess/dto/User.hbm.xml</value>
</list>
</property>
<!--设置hibernate属性 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLInnoDBDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
此时Hibernate的基本配置已经做好了,接下来需要对Dao类进行改造,以充分利用Hibernate对数据库操作的便利
利用Spring类库改造DAO
Spring框架中提供了类org.springframework.orm.hibernate3.support.HibernateDaoSupport
对hibernate的数据库访问操作进行了进一步的封装和简化,只要我们项目中的类继承了该类,便可以使用其中的数据库操作模版hibernateTemplate
来进行基本的CRUD操作,当然也能够使用自己编写的HQL语句对数据操作进行深度定制。UserDaoImpl部分示例代码如下:
package dataAccess.dao;
import dataAccess.dto.User;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import java.util.List;
public class UserDaoImpl extends HibernateDaoSupport implements IUserDao {
@Override
public UserDao getById(Long id) {
return getHibernateTemplate().get(ProgramDto.class,id);
}
@Override
public void deleteById(Long id) {
getHibernateTemplate().delete(getById(id));
}
...
}
在Spring配置文件中配置DAO
写好DAO文件后,需要将DAO在Spring容器中声明以供上层服务类调用,并且需要将Hibenate的SessionFactory
注入到Dao中。在Spring的org.springframework.orm.hibernate3.support.HibernateDaoSupport
已经实现了注入的代码,所以在自己编写的DAO文件里不需要再添加相应的代码,只需在beans.xml文件中配置即可,如下:
<!-- put sessionFactory into Dao -->
<bean id = "UserDao" class = "dataAccess.dao.UserDaoImpl"
p:sessionFactory-ref="sessionFactory"/>
值得注意的一点是,若是在这里想简单地测试一下配置的DAO是否可用,在获取DAO实例时需要显示地从Spring容器中获取,而不是自己New 一个,如下:
public class DaoTest {
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext("WEB-INF/beans.xml");
UserDaoImpl userDao = (UserDaoImpl)ac.getBean("UserDao");
System.out.println(userDao.getAll());
}
整合Spring和Struts
配置Spring容器”开机启动”
Spring容器一般随着应用在服务器中运行而启动,这样当我们需要从容器中取的时候,不用每次都手动加载(如上例)。具体的配置需要写入web.xml文件中
web.xml
<!-- configure Struts2 -->
<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>
</filter-mapping>
<!-- configure Spring start-on-load -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
在Spring中配置Action
我们在这里把Action配置在beans.xml里,利用Spring初始化Action的bean:
将Struts的业务逻辑控制器类配置在Spring的配置文件中,Action中引用的业务类一并注入。
(这样的处理,必须将action类的scope配置成property),配置如下:
beans.xml
<!-- put Dao into Service -->
<bean id="ProgramManageServiceImpl" class="org.sklse.mr.bussinessService.ProgramManageServiceImpl"
p:UserDao-ref="UserDao"/>
<!-- put Service into Action -->
<bean id="LoginAction" class="actions.LoginAction">
<property name="UserManageService" ref="UserManageServiceImpl"/>
</bean>
接着,在struts.xml或者等效的Struts2配置文件中配置Action时,指定<action>
的class属性为Spring配置文件中相应bean的id或者name值。同时需要注意的是,若想让Spring容器接管Action的生成,需要在Struts中配置相应属性,另外在项目中添加包 struts2-spring-plugin.jar,示例如下:
Struts.xml
<constant name="struts.objectFactory"
value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<action name=”LoginAction” class=”LoginAction”>
<result name=”success”>/WebPages/loginSuccess.jsp</result>
</action>
小结
本文简要介绍了SSH整合的基本要点,读者读完后能够自己搭建起一个SSH应用。