SSH整合之路


SSH整合之路

前言

对于Java Web开发的初学者来说,搭建一个SSH框架的项目一直是入门的拦路虎。主要原因:
1、struts2、spring和hibernate各自的版本众多。它们之间的兼容性问题增加了整合的难度。
2、对于较新版本之间的整合资料太少。老版本之间的整合方法不一定适用。
3、官方的参考文档自身存在的问题,经常让人摸不着头脑。
经过三天苦逼的生活 大哭 ,终于整合成功。就想着立马写下来,与大家一起分享。不过仍存在一些小问题和不明白的地方,还希望大家帮忙指正。

环境说明
系统:win7 32位
版本选择:
struts-2.3.16.1
spring-framework-4.0.4.RELEASE-dist
hibernate-release-4.3.5.Final
Mysql 5.6
jdk 1.7
apache-tomcat-7.0.52-windows-x86

整合过程

1、建库创表

create database project;
create table user(  
userId int auto_increment,  
userName varchar(16) not null,  
password varchar(16) not null,  
gender int not null,  
primary key(userId)  
); 

2创建Struts项目

2.1 创建项目
2.1.1  在Eclipse中创建一个Dynamic Web Project,本文项目名称为SSH3。

注:事先得安装好Tomcat服务器,并在Target runtime配置项选中它。其他配置如上图所示。

注:选中生成web.xml,这样可生成其模版。

2.2 导入struts2的相关jar包

把Struts内apps文件夹下的struts2-blank war包用压缩工具解压,然后把WEB-INF/lib内的jar包复制到SSH项目下的WEB-INF/lib下。

2.3 在src目录下创建相应package,结构如下图所示。


 
RegisterAction.java
package com.ssh.action;

import com.opensymphony.xwork2.ActionSupport;
import com.ssh.forms.UserForm;
import com.ssh.service.UserManager;

public class RegisterAction extends ActionSupport {

	private static final long serialVersionUID = 1L;

	private UserForm user;
	private String tip;
	private UserManager userManager;
	
	public UserForm getUser() {
		return user;
	}

	public void setUser(UserForm user) {
		this.user = user;
	}

	public String getTip() {
		return tip;
	}

	public void setTip(String tip) {
		this.tip = tip;
	}

	 public UserManager getUserManager() {
	 return userManager;
	 }
	
	 public void setUserManager(UserManager userManager) {
	 this.userManager = userManager;
	 }

	public String execute() {
        try {   
            userManager.regUser(user);  
            return SUCCESS;  
  
        } catch (Exception e) {  
            e.printStackTrace();  
            return ERROR;  
        }
	}
}
相应的RegisterAction-validation.xml
这部分可以参考Struts 2的官方文档
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
	<!-- Action中user的username属性 -->
	<field name="user.username">
		<field-validator type="requiredstring">
			<param name="trim">true</param>
			<message>用户名不能为空</message>
		</field-validator>
		<!-- 指定username属性必须匹配的正则表达式 -->
		<field-validator type="regex">
			<param name="regex"><![CDATA[(\w{6,16})]]></param>
			<message>用户名输入不合法,必须为长度在6-16中间数字或字母</message>
		</field-validator>
	</field>
	<!-- user.password属性 -->
	<field name="user.password">
		<field-validator type="regex">
			<param name="regex"><![CDATA[(\w{6,16})]]></param>
			<message>密码输入不合法,必须长度在6-16之间的数字或字母</message>
		</field-validator>
	</field>
</validators>
UserForm.java、UserManager.java和UserManagerImpl.java
package com.ssh.forms;

public class UserForm {
	private String username;
	private String password;
	private int gender;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public int getGender() {
		return gender;
	}
	public void setGender(int gender) {
		this.gender = gender;
	}
}
</pre><pre name="code" class="html">
</pre><pre name="code" class="html">package com.ssh.service;

import com.ssh.forms.UserForm;

public interface UserManager {  
  
    public void regUser(UserForm user);  
  
} 
package com.ssh.serviceImpl;

import com.ssh.forms.UserForm;
import com.ssh.service.UserManager;


public class UserManagerImpl implements UserManager {

	public void regUser(UserForm userForm){

	}

}
struts.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<span style="background-color: rgb(255, 204, 102);"><constant name="struts.devMode" value="true"/></span>
	<package name="lee" extends="struts-default">
		<action name="registerAction" class="com.ssh.action.RegisterAction">
			<result name="input">/register.jsp</result>
			<result name="success">/success.jsp</result>
			<result name="error">/fail.jsp</result>
		</action>
		<action name="">
			<result>.</result>		
		</action>
	</package>

</struts>
注:<constant name="struts.devMode" value="true"/> 设置为开放模式,否则输入不合法的提示信息可能看不到。

register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>User Register Page</title>
</head>
<body>
	<s:fielderror></s:fielderror>
	<s:form action="registerAction">
		<s:textfield name="user.username" label="用户名"></s:textfield>
		<s:password name="user.password" label="密码"></s:password>
		<s:select list="#{'1':'男','0':'女'}" listKey="key" listValue="value"
			name="user.gender" label="性别" value="1"></s:select>
		<s:submit value="注册"></s:submit>
	</s:form>
</html>

success.jsp和fail.jsp仅仅只是一句提示注册成功和失败的话,在此不再列出。

2.4 将项目部署到Tomcat服务器


2.5 测试结果



3、整合Hibernate和spring

3.1 导入相关jar包 

   1、将Hibernate内的lib/required下的jar包复制到SSH3项目的lib目录下;复制lib\optional\c3p0下的c3p0-0.9.2.1.jar、mchange-commons-java-0.2.3.4.jar;

2、导入Mysql数据库的jar包;mysql-connector-java-5.1.7-bin.jar

3、将Spring内libs目录下包含所有的jar包(不需要复制结尾为sources和javadoc的jar包)到SSH3项目的lib目录下


3.2 添加并修改相应类



User.java和User.hbm.xml,配置可以参考Hibernate的官方文档
package com.ssh.beans;

public class User {
	private int userId;
	private String username;
	private String password;
	private int gender;
	public int getUserId() {
		return userId;
	}
	public void setUserId(int userId) {
		this.userId = userId;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public int getGender() {
		return gender;
	}
	public void setGender(int gender) {
		this.gender = gender;
	}
	
}
<?xml version="1.0" encoding='UTF-8'?>  
<!DOCTYPE hibernate-mapping PUBLIC  
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
  
<hibernate-mapping package="com.ssh.beans">  
    <class name="User" table="user">  
        <id name="userId" column="userId">  
            <generator class="native"></generator>  
        </id>  
        <property name="username" column="userName" type="java.lang.String"  
            not-null="true" length="16"></property>  
        <property name="password" column="password" type="java.lang.String"  
            not-null="true" length="16" />  
        <property name="gender" column="gender" type="java.lang.Integer" length="1" />  
    </class>  
</hibernate-mapping> 

BaseDao和UserDao
package com.ssh.dao;

import org.hibernate.HibernateException;


public interface BaseDao {
	public void saveObject(Object obj) throws HibernateException;

}
package com.ssh.daoImpl;

import org.hibernate.HibernateException;
import <span style="color:#ff0000;">org.springframework.orm.hibernate4.support.HibernateDaoSupport;</span>
import com.ssh.dao.BaseDao;

public class UserDao extends HibernateDaoSupport implements BaseDao {

	@Override
	public void saveObject(Object obj) throws HibernateException {
		getHibernateTemplate().save(obj); 

	}

}
修改UserManagerImpl
package com.ssh.serviceImpl;

import org.hibernate.HibernateException;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import com.ssh.beans.User;
import com.ssh.dao.BaseDao;
import com.ssh.forms.UserForm;
import com.ssh.service.UserManager;

public class UserManagerImpl implements UserManager {

	private BaseDao dao;

	public void setDao(BaseDao dao) {
		this.dao = dao;
	}

	<span style="color: rgb(255, 0, 0);">@Transactional(readOnly = false)</span>
	public void regUser(UserForm userForm) throws HibernateException {

		// 构造User对象
		User user = new User();
        BeanUtils.copyProperties(userForm, user); 
        dao.saveObject(user);  
	}
}
修改struts.xml
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<constant name="struts.devMode" value="true"/>
	<package name="lee" extends="struts-default">
		<action name="registerAction" <span style="color:#ff0000;">class="regAction"></span>
			<result name="input">/register.jsp</result>
			<result name="success">/success.jsp</result>
			<result name="error">/fail.jsp</result>
		</action>
		<action name="">
			<result>.</result>		
		</action>
	</package>

</struts>
applicationContext.xml配置

参考:spring官方文档spring-framework-reference的14.3 Hibernate


<?xml version="1.0" encoding="UTF-8"?>
<span style="color:#ff0000;"><beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"></span>

	<!-- 定义数据源的信息 -->
	<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/project" />
		<!-- 指定连接数据库的用户名 -->
		<property name="user" value="root" />
		<property name="password" value="123456" />
		<!-- 指定连接数据库连接池的最大连接数 -->
		<property name="maxPoolSize" value="40" />
		<!-- 指定连接数据库连接池的最小连接数 -->
		<property name="minPoolSize" value="1" />
		<!-- 指定连接数据库连接池的初始化连接数 -->
		<property name="initialPoolSize" value="1" />
		<!-- 指定连接数据库连接池的连接的最大空闲时间 -->
		<property name="maxIdleTime" value="20" />
	</bean>

	<!--定义Hibernate的SessionFactory -->
	<!-- SessionFactory使用的数据源为上面的数据源 -->
	<!-- 指定了Hibernate的映射文件和配置信息 -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource">
		</property>
		<property name="mappingResources">
			<list>
				<span style="color:#ff0000;"><value>com/ssh/beans/User.hbm.xml</value></span>
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="show_sql">true</prop>
				<prop key="hibernate.jdbc.batch_size">20</prop>
			</props>
		</property>
	</bean>

	<bean id="baseDao" class="com.ssh.daoImpl.UserDao">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
	</bean>

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
<span style="color:#3333ff;">	<!--  	
	<aop:config>
		<aop:pointcut id="productServiceMethods"
			expression="execution(com.ynwi.ssh.service.UserManager.(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods" />
	</aop:config>

	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="*" read-only="false" />
		</tx:attributes>
	</tx:advice>
	-->
</span>
	<!-- 配置事务的传播特性  -->
	
	<span style="color:#ff0000;"><tx:annotation-driven /></span>

	<!--用户注册业务逻辑类 -->
	<bean id="userManager" class="com.ssh.serviceImpl.UserManagerImpl">
		<property name="dao">
			<ref bean="baseDao" />
		</property>
	</bean>

	<!-- 用户注册的Action -->
	<bean id="regAction" class="com.ssh.action.RegisterAction">
		<property name="userManager">
			<ref bean="userManager" />
		</property>
	</bean>

	<!-- more bean definitions go here -->

</beans>

修改web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>SSH3</display-name>
	<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>

<span style="color:#ff0000;">	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener></span>

	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
</web-app>

4、部分异常

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

配置事务的传播特性,并设置为可写。有两种方法 
  1、在applicationContext中配置;
 2、采用annotation方式 

  本文采用的是第二种。因为参考官方文档提供的示例,第一种配置总是不能生效,原因还没找到,希望大家给与指正。

下面这两个异常为缺少相应的jar包,其特点已标注出来。可以通过在包含struts、hibernate和spring解压文件的目录下,通过搜索蓝色的jar包名快速得到。

org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception isjava.lang.NoClassDefFoundError: org/ aopalliance /intercept/MethodInterceptor
aopalliance-1.0.jar
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: com/ mchange /v2/ser/Indirector
mchange-commons-java-0.2.3.4.jar

5、测试结果






参考:
[1]  http://blog.csdn.net/yeohcooller/article/details/9316923 
[2] struts 2、hibernate和spring相关官方文档

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值