第一次用Markdown编写,排版还是比较舒服的
SSH框架搭建
1 项目环境
- Win7 x64环境,eclipse mars2,jdk1.8,tomcat8.0
Mysql 5.0.45 - Struts2.5.2
http://struts.apache.org/download.cgi
新版本刚出不久,Structs2.5.中没strut-blank.war,也就没有struts.xml,没办法,只structs2.3.8.1中找的
struts2.3.8.1下载地址:http://mirrors.cnnic.cn/apache/struts/2.3.28.1/struts-2.3.28.1-apps.zip - Spring Framework 4.3.3
http://repo.springsource.org/libs-release-local/org/springframework/spring/ - Hibernate 5.2.3
[http://hibernate.org/orm/downloads/Hibernate 5.2.3](
http://hibernate.org/orm/downloads/) - mysql-connector-java-5.1.40(数据库驱动)
我这里用的是mysql mysq-jdbc的驱动下载地址http://dev.mysql.com/downloads/connector/j/
2 创建Structs工程
1 操作步骤
- 在Eclipse中创建一个
Dynamic Web Project
,本文项目名称为SSHProject
。 - 把Struts内apps文件夹下的
struts2-blank war
包用压缩工具解压,然后把WEB-INF/lib
内的jar包和WEB-INF
下的web.xml
文件分别复制到SSHProject
项目下的WEB-INF/lib
内和WEB-INF
下。 - 在src目录下创建相应package。
- 在
WebContent
下创建Register.jsp
文件,并分别创建注册成功和注册失败的Success.jsp
和Fail.jsp
。
2 操作完成后项目结构如图
3 编写代码
web.xml
的内容
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SSHProgect</display-name>
<filter>
<filter-name>SSH</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SSH</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
struts.xml
的内容
<?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>
<include file="struts-default.xml" />
<package name="default" namespace="/" extends="struts-default">
<action name="register" class="com.ssh.action.RegisterAction">
<result name="input">/Register.jsp</result>
<result name="success">/Success.jsp</result>
<result name="error">/Fail.jsp</result>
</action>
</package>
</struts>
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:form action="register">
<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>
</body>
</html>
Success.jsp
的内容
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>success!</h1>
</body>
</html>
Fail.jsp
的内容
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>failure!</h1>
</body>
</html>
- 用户表单类
UserForm.java
的内容。
package com.ssh.beans;
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;
}
}
- 注册Action类
RegisterAction.java
的内容。
package com.ssh.action;
import com.opensymphony.xwork2.ActionSupport;
import com.ssh.beans.UserForm;
import com.ssh.service.UserManager;
import com.ssh.serviceImpl.UserManagerImpl;
public class RegisterAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private UserForm user;
private UserManager userManager;
public UserForm getUser() {
return user;
}
public void setUser(UserForm user) {
this.user = user;
}
public UserManager getUserManager() {
return userManager;
}
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
public String execute() {
try {
this.setUserManager(new UserManagerImpl());
userManager.regUser(user);
System.out.println("success");
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ERROR;
}
}
}
- 业务逻辑接口
UserManager.java
的内容
package com.ssh.service;
import com.ssh.beans.UserForm;
public interface UserManager {
public void regUser(UserForm user);
}
- 业务逻辑实现类
UserManagerImpl.java
的内容
package com.ssh.serviceImpl;
import com.ssh.beans.UserForm;
import com.ssh.service.UserManager;
public class UserManagerImpl implements UserManager {
@Override
public void regUser(UserForm user) {
}
}
4 运行效果
- 浏览器地址中输入
http://localhost:8080/SSHProgect/Register.jsp
后
- 注册成功后
-
3 在Struts基础上整合Hibernate整合Hibernate
1 操作步骤
- 将
Hibernate
内的lib/required
下的jar包和lib/jpa
下的jar包复制到SSHProject
项目的lib
目录下。 - 在上面Struts项目的基础上添加
com.ssh.dao
和com.ssh.daoImpl
包。分别创建BaseDao
接口和UserDao
类。 - 在数据库中创建对应的表user来写入要注册的用户。创建表的
SQL
脚本如下所示。
create table user(
userId int auto_increment,
userName varchar(16) not null,
password varchar(16) not null,
gender int not null,
primary key(userId)
);
- 创建user表的
Hibernate
映射文件。因为这里要创建user表
对应的POJO类
,所以我这里把之前com.ssh.beans
包改成com.ssh.forms
包,用来存放页面传过来的表单数据,新创建com.ssh.beans
包,用来创建POJO对象
来对应数据库中的表。路径:POJO类同目录
。 - 建立Hibernate配置文件。路径:
src目录下
。 - 编写
Session工厂类
。整合Spring
后,数据源的创建和SessionFactory
的创建都交给Spring
去管理,就无需这个工厂类了,临时创建在daoImpl
包里面。 - 修改业务逻辑实现类。
2 修改完成后如下所示
3 编写代码
BaseDao.java
的内容
package com.ssh.dao;
import org.hibernate.HibernateException;
import org.hibernate.Session;
public interface BaseDao {
public Session getSession();
public void setSession(Session session);
public void saveObject(Object obj)throws HibernateException;
}
- 实体类
User.java
的内容。
package com.ssh.beans;
public class User {
private String username;
private String password;
private String gender;
private int userId;
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
- POJO类
UserDao.java
的内容
package com.ssh.daoimpl;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import com.ssh.dao.BaseDao;
public class UserDao implements BaseDao {
private Session session;
@Override
public Session getSession() {
// TODO Auto-generated method stub
return session;
}
@Override
public void setSession(Session session) {
// TODO Auto-generated method stub
this.session=session;
}
@Override
public void saveObject(Object obj) throws HibernateException {
// TODO Auto-generated method stub
session.save(obj);
}
}
- POJO类
User.java
的Hibernate
映射文件User.hbm.xml
的内容
代码
<generator class="native"></generator>
说明将根据本地数据库的设置来创建userId
,如MySQL中将表user
的userId
设置为自动增长,则在保存记录是,userId
将自动增长。对于需要在程序中指定主键的值,则将generator
的class属性设置为assigned
。
<?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>
Hibernate
的配置文件hibernate.cfg.xml
的内容
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping class="com.ssh.beans.User"/>
</session-factory>
</hibernate-configuration>
- 工厂类
SessionFactory
的内容。
不同的hibernate版本编写有些不同,这里我用hibernate5.2.5配置的时候按照hibernate配置的出了经典的问题 unknown entity 请看这篇文章-传送门,下面附上正确的代码
package com.ssh.daoimpl;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateSessionFactory {
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<>();
//加载默认的src下的hibernate.cfg.xml
private static final Configuration cfg = new Configuration().configure();
private static SessionFactory sessionFaction;
public static Session currentSession()throws HibernateException{
// 创建Session
Session session = threadLocal.get();
if (session == null||session.isOpen()==false) {
if (sessionFaction==null) {
try {
sessionFaction = cfg.buildSessionFactory();
//System.out.println("HibernateSessionFactory---sessionfactory:"+sessionFaction);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
session=sessionFaction.openSession();
//System.out.println("HibernateSessionFactory--session:"+session);
threadLocal.set(session);
}
return session;
}
public static void closeSession()throws HibernateException{
Session session= threadLocal.get();
threadLocal.set(null);
if (session!=null) {
session.close();
}
}
//public static void main(String []args){
// Session session = currentSession();
// System.out.println("session:"+session);
//}
}
- 修改后的业务逻辑实现类
UserManagerImpl
的内容。
package com.ssh.serviceImpl;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.ssh.beans.User;
import com.ssh.dao.BaseDao;
import com.ssh.daoimpl.HibernateSessionFactory;
import com.ssh.daoimpl.UserDao;
import com.ssh.forms.UserForm;
import com.ssh.service.UserManager;
public class UserManagerImpl implements UserManager {
private BaseDao dao;
private Session session;
public UserManagerImpl() {
// TODO Auto-generated constructor stub
dao = new UserDao();
}
@Override
public void regUser(UserForm userForm) {
session = HibernateSessionFactory.currentSession();
System.out.println("UserManegerImpl---session:" + session);
dao.setSession(session);
// 获取事务
Transaction transaction = session.beginTransaction();
// 构造uer对象
User user = new User();
user.setUsername(userForm.getUsername());
user.setPassword(userForm.getPassword());
user.setGender(userForm.getGender());
// 保存对象
dao.saveObject(user);
// 提交事务
transaction.commit();
HibernateSessionFactory.closeSession();
}
public static void main(String[] args) {
User userForm = new User();
userForm.setGender("male");
userForm.setPassword("12121212");
userForm.setUsername("zjz");
HibernateSessionFactory.currentSession().save(userForm);
// new UserManagerImpl().regUser(userForm);
}
}
4 运行效果
查看数据
4 在Struts + Hibernate项目中整合Spring整合Spring
1 操作步骤
将Spring内
libs目录
下包含所有的jar包(不需要复制结尾为sources
和javadoc
的jar包)到SSHProject
项目的lib目录
下。编写
Spring
的配置文件applicationContext.xml
。路径:src目录下
,需要在web.xml
配置context-param
指定路径,或者把该文件放在WEB-INF下,跟web.xml
同目录。这里由于Spring配置数据源的需要,需要把Hibernate内lib/optional/c3p0下的c3p0-0.9.1.jar
复制到lib目录
下。修改
BaseDao
和UserDao
。在引入Spring后,需要用Spring进行统一的事务管理,数据源和sessionFactory都交给Spring去生成,因此接口类和实现类BaseDao和UserDao都需要做相应的修改。Spring提供了HibernateDaoSupport类来完成对数据的操作,因此UserDao在实现BaseDao的同时还需要继承HibernateDaoSupport类。并将先前session的操作修改成HibernateTemplate(可通过getHibernateTemplate()方法来获得)的操作。
修改业务逻辑实现类。在没有加入
Spring
之前,业务逻辑实现类的Session
的获得,dao
的实例化,以及事务的管理都是该类执行管理的。加入Spring
后,这些都交给Spring
去管理。该类的dao
的实例化由Spring
注入。- 修改用户注册的
RegisterAction
类。同样,RegisterAction
类中的userManager
的实例化也由Spring注入。 - 删除
Hibernate
的配置文件Hibernate.cfg.xml
和工厂类HibernateSesseionFactory
类。他们的工作已经交给Spring
去做,已经不再有用。 - 修改
web.xml
,加载Spring
。要想启动时加载Spring
的配置文件,需要在web.xml
中配置对应的监听器listenser
,并制定Spring
的配置文件。 - 修改
Struts
的配置文件struts.xml
。把原来指定的名为register
的action
的class由原来的路径变为applicationContext.xml
文件中该Action的id
。