您的位置:首页 > 编程语言 > Java开发

Spring2+struts2+ibatis整合

2013-01-15 17:59 525 查看
前几天因为需要,将spring2、struts2和ibatis进行了整合,整合过程涉及到很多技巧,因此作为日志保存在此,以便今后查询。

各个框架在本项目内的作用:

spring2:主要利用ioc,以及对事物的管理,减少硬性编码和脱离手动事务控制。

struts2:主要用于MVC以及数据校验。struts2摆脱了struts1性能上的瓶颈,达到了新的高度,配置更灵活,全面支持ajax,freemark等等,采用ognl动态语言使得输出也更加灵活。

iBatis:主要用于作orm。开发效率不如hibernate,但是由于是半自动映射,因此更加灵活,并且效率更好,维护更方便。

整合过程(eclipse导包过程省略)

主要配置如下:

配置web.xml

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

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<welcome-file-list>

<welcome-file>index.jsp</welcome-file>

</welcome-file-list>

<!-- struts2模块 -->

<filter>

<filter-name>struts2</filter-name>

<!-- 这个就是struts2的核心过滤器 -->

<filter-class>

org.apache.struts2.dispatcher.FilterDispatcher

</filter-class>

</filter>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<!-- 项目中的字符编码处理,与整合无关 -->

<filter>

<filter-name>CharacterFilter</filter-name>

<filter-class>

com.afl.system.filter.CharacterFilter

</filter-class>

</filter>

<filter-mapping>

<filter-name>CharacterFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<!-- spring listener -->

<listener>

<!-- 这个就是今后用到的WebApplicationUtilContent -->

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<!-- springframework config files -->

<context-param>

<param-name>contextConfigLocation</param-name>

<!-- 把spring的配置文件放到了/WEB-INF/下的springframework包里,方便统一管理,命名规则是以applicationContent-开头的xml文件,初始化时会自动搜索所有符合规则的配置文件 -->

<param-value>

/WEB-INF/springframework/applicationContext-*.xml

</param-value>

</context-param>

<!-- config servlet -->

<!-- 这个是dwr的配置文件,与整合无关 -->

<servlet>

<servlet-name>dwr</servlet-name>

<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>

<init-param>

<param-name>debug</param-name>

<param-value>true</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>dwr</servlet-name>

<url-pattern>/dwr/*</url-pattern>

</servlet-mapping>

</web-app>

配置Spring

applicationContext-iBatis.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"

xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- 配置数据源,连接池采用的是c3p0,具体各参数代表意义参看c3p0自带的doc,非常详细。 -->

<bean id="dataSource"

class="com.mchange.v2.c3p0.ComboPooledDataSource"

destroy-method="close">

<property name="driverClass" value="${jdbc.driverClass}" />

<property name="jdbcUrl" value="${jdbc.url}" />

<property name="user" value="${jdbc.user}" />

<property name="password" value="${jdbc.password}" />

<property name="minPoolSize" value="${jdbc.minPoolSize}" />

<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />

<property name="maxIdleTime" value="${jdbc.maxIdleTime}" />

<property name="acquireIncrement"

value="${jdbc.acquireIncrement}" />

<property name="maxStatements" value="${jdbc.maxStatements}" />

<property name="initialPoolSize"

value="${jdbc.initialPoolSize}" />

<property name="idleConnectionTestPeriod"

value="${jdbc.idleConnectionTestPeriod}" />

<property name="acquireRetryAttempts"

value="${jdbc.acquireRetryAttempts}" />

</bean>

<!-- 配置iBatis的sqlMapClient,这里当然是交给了spring去处理,其中,将SqlMapConfig文件放到了WEB-INF的iBatis目录下,也是便于管理 -->

<bean id="sqlMapClient"

class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

<property name="configLocation">

<value>/WEB-INF/iBatis/SqlMapConfig.xml</value>

</property>

<!-- 这里使用的数据源就是上面配置的数据源 -->

<property name="dataSource">

<ref bean="dataSource" />

</property>

</bean>

<!-- 上面的数据源的value值用的是表达式,原因就在这里,这将配置文件放到了iBatis目录下,也就是jdbc.properties,设置了c3p0的各项参数 -->

<bean id="propertyConfig"

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="location">

<value>/WEB-INF/iBatis/jdbc.properties</value>

</property>

</bean>

<!-- 这个就是spring的事务管理了,采用的DataSource事务管理,要管理的DataSource当然也是上面配置的DataSource -->

<bean id="transactionManager"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource">

<ref bean="dataSource" />

</property>

</bean>

<!-- 事务管理的代理类,将其抽象化abstruct=true,以后需要进行事务管理直接继承此类就行了,非常方便 -->

<bean id="transactionProxy"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">

<!-- 这个就是刚才配置的事务管理器 -->

<property name="transactionManager">

<ref bean="transactionManager"/>

</property>

<!-- 下面是spring事务管理的策略,可以看到,凡是涉及数据库插入、修改的操作都应当以add、insert、edit、update、delete开头,这样才能由spring进行事务管理 -->

<property name="transactionAttributes">

<props>

<prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop>

<prop key="add*">PROPAGATION_REQUIRED,-Exception</prop>

<prop key="update*">PROPAGATION_REQUIRED,-Exception</prop>

<prop key="edit*">PROPAGATION_REQUIRED,-Exception</prop>

<prop key="delete*">PROPAGATION_REQUIRED,-Exception</prop>

<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="*">PROPAGATION_REQUIRED</prop>

</props>

</property>

</bean>

<!-- 这是项目中注册类,使用的sqlMapClient由spring去注入 -->

<bean id="registerDAO"

class="com.afl.register.service.dao.impl.RegisterDAOImpl">

<property name="sqlMapClient">

<ref bean="sqlMapClient" />

</property>

<property name="dataSource">

<ref bean="dataSource" />

</property>

</bean>

<!-- 项目中,我将事务管理放到了service层上,因为dao只负责与数据库基本交互,在此项目中一般只操作一个表,无需事务。而service层上根据业务需要处理多表,因此将事务放在了service层上,其中的parent就是上面配置并abstract的代理 -->

<bean id="registerService" parent="transactionProxy">

<property name="target">

<bean class="com.afl.register.service.impl.RegisterServiceImpl">

<property name="registerDAO">

<ref bean="registerDAO"/>

</property>

</bean>

</property>

</bean>

</beans>

jdbc.properties

这个就是spring里面c3p0对应的值

jdbc.driverClass=com.microsoft.sqlserver.jdbc.SQLServerDriver

jdbc.url=jdbc:sqlserver://localhost:1433;DatabaseName=数据库名

jdbc.user=sa

jdbc.password=密码

jdbc.minPoolSize=5

jdbc.maxPoolSize=20

jdbc.maxIdleTime=1800

jdbc.acquireIncrement=5

jdbc.maxStatements=50

jdbc.initialPoolSize=10

jdbc.idleConnectionTestPeriod=1800

jdbc.acquireRetryAttempts=30

接下来继续iBatis和spring的整合

根据上面的配置,在WEB-INF/iBatis中应该还有SqlMapConfig.xml文件,内容如下

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

<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<!-- 就像hibernate的hbm.xml文件一样,一个实体对应一个xml -->

<!-- 用户信息表 -->

<sqlMap resource="com/afl/system/entity/User.xml" />

</sqlMapConfig>

接着就是User.java和User.xml的内容

User.java

public class User {

// 主键 id

private Long id;

// 用户名

private String username;

// 密码

private String password;

....... 以下省略 ......

}

User.xml

<!-- 没啥多说的,参看iBatis文档 -->

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

<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap>

<typeAlias alias="User" type="com.afl.system.entity.User" />

<!-- 保存注册信息 -->

<insert id="insertUser" parameterClass="User">

insert into

AFL_User(username,password)values(#username#,#password#)

</insert>

</sqlMap>

至此,iBatis与Spring的整合完成。接着是整合struts2

由于从spring配置文件中读取bean会经常用到WebApplicationContext,并且struts2采用了vs机制,因此想要像struts1那样操作request,response,session需要做一些处理,所以建立了一个基类,以后的action由此派生

BaseAction.java

下面红色的就是需要的基类,可以集成后获得request,response,session以为web上下文,从此除了按struts2方式处理外,遇到难题仍然可以像struts1那样处理问题了

/**

* 所有Action的基类,继承自BaseAction的action都可以直接使用HttpServletRequest,HttpServletResponse和Session

*/

package com.afl.system.struts2.action;

import java.util.Map;

import javax.servlet.ServletContext;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;

import org.apache.struts2.interceptor.ServletResponseAware;

import org.apache.struts2.interceptor.SessionAware;

import org.apache.struts2.util.ServletContextAware;

import org.springframework.context.ApplicationContext;

import org.springframework.web.context.support.WebApplicationContextUtils;

import com.opensymphony.xwork2.ActionSupport;

/**

* @author zcpeng

*

*/

public class BaseAction extends ActionSupport implements SessionAware,

ServletRequestAware, ServletResponseAware, ServletContextAware {

protected Map session;

protected HttpServletRequest request;

protected HttpServletResponse response;

protected ServletContext context;

/*

* (non-Javadoc)

*

* @see org.apache.struts2.util.ServletContextAware#setServletContext(javax.servlet.ServletContext)

*/

public void setServletContext(ServletContext context) {

// TODO Auto-generated method stub

this.context = context;

}

/*

* (non-Javadoc)

*

* @see org.apache.struts2.interceptor.ServletResponseAware#setServletResponse(javax.servlet.http.HttpServletResponse)

*/

public void setServletResponse(HttpServletResponse response) {

// TODO Auto-generated method stub

this.response = response;

}

/*

* (non-Javadoc)

*

* @see org.apache.struts2.interceptor.ServletRequestAware#setServletRequest(javax.servlet.http.HttpServletRequest)

*/

public void setServletRequest(HttpServletRequest request) {

// TODO Auto-generated method stub

this.request = request;

}

/*

* (non-Javadoc)

*

* @see org.apache.struts2.interceptor.SessionAware#setSession(java.util.Map)

*/

public void setSession(Map session) {

// TODO Auto-generated method stub

this.session = session;

}

<!-- 这个就是获得设备上下文的方法,和struts1一样吧^-^ -->

public ApplicationContext getApplicationContext() {

return WebApplicationContextUtils.getWebApplicationContext(context);

}

<!-- 作了个处理,以后需要调用spring的bean,直接调用此方法就可以了 -->

public Object getObject(String beanName) {

return getApplicationContext().getBean(beanName);

}

}

接下来在/web-inf/springframework目录下建立applicationContext-action.xml,这里全是struts2的action,并且交给spring产生

生成方式采用的是prototype,至于为什么,参阅spring文档

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

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- struts2's Action Mapping -->

<!-- 基础Action -->

<bean name="baseAction"

class="com.afl.system.struts2.action.BaseAction" scope="prototype">

</bean>

<!-- 用户注册action -->

<bean name="registerAction"

class="com.afl.register.action.RegisterAction" scope="prototype">

</bean>

</beans>

最后,也是最重要的一个配置文件struts.xml,这个文件是在classes目录下

<?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">

<struts>

<!-- 这是一个重要的地方,很多人在使用<s:include>子页面后,发现子页面乱码,怎么改都不行,原因就在次,struts2的默认编码为UTF-8,乱码的同志请看看你的jsp页面上的编码是不是和这个不一致呢。只要把这里和jsp编码改一致就行了 -->

<constant name="struts.i18n.encoding" value="UTF-8" />

<!-- 告诉struts2,我要用spring装配工厂,其实默认就是这个了-_-!!! -->

<constant name="struts.objectFactory" value="spring" />

<!-- struts2的扩展名,比如struts1的时候,用的.do,struts2默认为.action,可以改成其它的,比如.dxd -->

<constant name="struts.action.extension" value="action" />

<!-- 资源文件 -->

<constant name="struts.custom.i18n.resources"

value="messageResource">

</constant>

<!-- 用户注册类 -->

<!-- abstract属性就说明了该action继承自自己定义的基础action,而class采用的registerAction是由spring产生的 -->

<package name="register" extends="struts-default"

abstract="baseAction">

<action name="addUser" class="registerAction"

method="addUser">

<!-- 注册成功 -->

<result name="success">

/register/register_success.jsp

</result>

<!-- 注册失败 -->

<result name="input">/register/register.jsp</result>

</action>

</package>

</struts>

至此,spring2+struts2+ibatis整合完毕,代码省略……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: