前言:此次项目仅仅只是我学习SSH框架时的一个入门实例,本身没有太复杂的东西。同时这篇文章也算是对所学知识的一个总结和梳理,当然能够帮到一些初学Java的ssh框架的童鞋就更好了。大神轻喷,文中有误的话可以在下方留言。(PS:文末有整个项目的源代码和相关sql文件的下载链接


这个项目很简单,只是做一个简单的用户登录即可。由于我没有使用Myeclipse开发,而是使用了eclipse for Java EE来开发,因此所做的步骤相对要多一点O(∩_∩)O~

一 Spring整合Hibernate并测试

1 在MySQL5中创建数据库bookshop,并运行bookshop.sql,导入相关的表和数据

2 创建一个Dynamic Web Project –> “ssh2test1”,导入jar包(所有jar包均存放在WebContent/WEB-INF/lib),接下来创建一个包“com.ssh2test1.entity”,用于存放相关实体类以及配置文件。有关实体类的介绍可自行参考Hibernate相关内容。由于是用户登录,因为我们需要用到数据库中的 users这个表。所以接下来就是在com.ssh2test1.entity里创建一个Users.java和它的配置文件Users.hbm.xml

Users.java:

package com.ssh2test1.entity;

import java.io.Serializable;

public class Users implements Serializable {
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String loginName;
	private String loginPwd;
	private String name;
	private String address;
	private String phone;
	private String mail;
	private Integer userRoleId;
	private Integer userStateId;
	
	public Users(){
		
	}

	public Users(Integer id, String loginName, String loginPwd, String name, String address, String phone, String mail,
			Integer userRoleId, Integer userStateId) {
		super();
		this.id = id;
		this.loginName = loginName;
		this.loginPwd = loginPwd;
		this.name = name;
		this.address = address;
		this.phone = phone;
		this.mail = mail;
		this.userRoleId = userRoleId;
		this.userStateId = userStateId;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getLoginPwd() {
		return loginPwd;
	}

	public void setLoginPwd(String loginPwd) {
		this.loginPwd = loginPwd;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getMail() {
		return mail;
	}

	public void setMail(String mail) {
		this.mail = mail;
	}

	public Integer getUserRoleId() {
		return userRoleId;
	}

	public void setUserRoleId(Integer userRoleId) {
		this.userRoleId = userRoleId;
	}

	public Integer getUserStateId() {
		return userStateId;
	}

	public void setUserStateId(Integer userStateId) {
		this.userStateId = userStateId;
	}
	
}

Users.hbm.xml:

<?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>
	<class name="com.ssh2test1.entity.Users" table="users" catalog="bookshop">
		<id name="id" type="java.lang.Integer">
			<column name="Id" />
			<generator class="native" />
		</id>
		<property name="loginName" type="java.lang.String">
			<column name="LoginName" length="50" />
		</property>
		<property name="loginPwd" type="java.lang.String">
            <column name="LoginPwd" length="16" />
        </property>
        <property name="name" type="java.lang.String">
            <column name="Name" length="16" />
        </property>
        <property name="address" type="java.lang.String">
            <column name="Address" length="16" />
        </property>
        <property name="phone" type="java.lang.String">
            <column name="Phone" length="16" />
        </property>
        <property name="mail" type="java.lang.String">
            <column name="Mail" length="16" />
        </property>
        <property name="userRoleId" type="java.lang.Integer">
            <column name="UserRoleId" />
        </property>
        <property name="userStateId" type="java.lang.Integer">
            <column name="UserStateId" />
        </property>
		
	</class>
</hibernate-mapping>

3 配置proxool数据库连接池


(1) 在src根目录下创建一个proxool.xml,用于配置数据库连接情况,下面附上代码,里面有详细注释

proxool.xml:

<?xml version="1.0" encoding="UTF-8"?>
<something-else-entirely>
  <proxool>
    <alias>ProxoolPool</alias>
    <driver-url>jdbc:mysql://127.0.0.1:3306/bookshop?useUnicode=true&amp;characterEncoding=utf-8</driver-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <driver-properties>
      <property name="user" value="root"/>
      <property name="password" value="root"/>
    </driver-properties>
    
    <!--最大连接数(默认5个),超过了这个连接数,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定 --> 
    <maximum-connection-count>100</maximum-connection-count>
    <!--最小连接数(默认2个)-->   
	<minimum-connection-count>10</minimum-connection-count>
	 <!--proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁默认30秒-->  
	<house-keeping-sleep-time>90000</house-keeping-sleep-time>
	<!--没有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受-->  
	<maximum-new-connections>10</maximum-new-connections>
	<!--最少保持的空闲连接数(默认2个)-->   
	<prototype-count>5</prototype-count>
	<!--在使用之前测试-->   
	<test-before-use>true</test-before-use>
	<!--用于保持连接的测试语句 -->  
	<house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>
	
  </proxool>

</something-else-entirely>

(2) 配置web.xml,注意:在Spring中配置proxool连接池和在Hibernate中配置有很大的不同,一般情况下proxool再web.xml中是这样配置的:

  <servlet>
    <servlet-name>proxoolServletConfigurator</servlet-name>
	<servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
    <init-param>
      	<param-name>xmlFile</param-name>
      	<param-value>WEB-INF/classes/proxool.xml</param-value><!--这里对应刚才建立的xml配置文件名-->
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

但是又因为Spring通过Listener方式启动,这就导致了Spring比proxool先加载,然后程序运行时将会报错:


(7073 ms) [ERROR] [11:40:40] org.logicalcobwebs.proxool.ProxoolDriver – Problem
org.logicalcobwebs.proxool.ProxoolException: Attempt to refer to a unregistered pool by its alias ‘ProxoolPool’
at org.logicalcobwebs.proxool.ConnectionPoolDefinition.doChange(ConnectionPoolDefinition.java:246)
at org.logicalcobwebs.proxool.ConnectionPoolDefinition.<init>(ConnectionPoolDefinition.java:143)
at org.logicalcobwebs.proxool.ProxoolFacade.registerConnectionPool(ProxoolFacade.java:96)
at org.logicalcobwebs.proxool.ProxoolDriver.connect(ProxoolDriver.java:77)
at java.sql.DriverManager.getConnection(DriverManager.java:664)


因此在这里我们需要proxool也以listener启动,并且还比Spring先启动即可。有大神写了个补丁,我把它命名为ProxoolListener.jar放在lib下了,下面附上现在的web.xml配置情况

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" version="3.1">

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>    
      
<!-- proxool改成了以listener方式启动,加载了一个自定义的 ProxoolListener.jar -->
<context-param>  
    <param-name>proxoolConfigLocation</param-name>  
    <param-value>WEB-INF/classes/proxool.xml</param-value>  
</context-param>  
<listener>  
    <listener-class>org.logicalcobwebs.proxool.configuration.ListenerConfigurator</listener-class>  
</listener>  
<listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
</listener>
  
<!-- spring -->
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>WEB-INF/classes/applicationContext.xml</param-value>
  </context-param>  
  <!-- 指定以Listener方式启动 -->
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>    

<!-- 以下3项参数与log4j的配置相关 -->    
  <context-param>  
        <param-name>log4jConfigLocation</param-name>  
        <param-value>WEB-INF/classes/log4j.properties</param-value>  
    </context-param>  
    <!--Spring默认刷新Log4j配置文件的间隔,单位为millisecond-->  
    <context-param>  
        <param-name>log4jRefreshInterval</param-name>  
        <param-value>60000</param-value>  
    </context-param>  
    <!-- Web 项目 Spring 加载 Log4j 的监听 -->
    <listener>  
        <listener-class>  
            org.springframework.web.util.Log4jConfigListener  
        </listener-class>  
    </listener>   

<!-- 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>    
 
</web-app>

(3) 在src根目录下新建applicationContext.xml,用于配置相关数据源和实例对象,以实现依赖关系的注入。在这里先配置proxool数据源和sessionFactory


applicationContext.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"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
	
<!-- 配置数据源,proxool数据库连接池 -->
    <bean id="dataSource" 
        class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        <property name="driverClassName" value="org.logicalcobwebs.proxool.ProxoolDriver" />
        <!-- proxool配置文件中的别名要一致 -->
        <property name="url" value="proxool.ProxoolPool" />
    </bean>
        
    <!-- 配置sessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
       <property name="dataSource" ref="dataSource"></property>
       <property name="hibernateProperties">
           <props>
              <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
              <prop key="hibernate.show_sql">true</prop>
           </props>
       </property>
       
       <property name="mappingResources">
			<list>
<!-- 加载实体配置文件 -->			<value>com/ssh2test1/entity/Users.hbm.xml</value>
			</list>
		</property>
    </bean>
	
</beans>

4 创建一个包“com.ssh2test1.dao”,封装的是数据库操作。里面有一个接口UserDAO.java和它的实现类UserDAOImpl.java

UserDAO.java:

package com.ssh2test1.dao;

import java.util.List;

import com.ssh2test1.entity.Users;

public interface UserDAO {
	public List<Users> search(Users user);
}

UserDAOImpl.java:

package com.ssh2test1.dao;

import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.ssh2test1.entity.Users;

public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {

	public List<Users> search(Users user) {
		Object execute = super.getHibernateTemplate().execute(new HibernateCallback<Object>() {
			public Object doInHibernate(Session session) throws HibernateException{
				Query query = null;
				if(user != null){
					if(user.getLoginName() != null && !user.getLoginName().equals("") && user.getLoginPwd() != null && !user.getLoginPwd().equals("")){
						String hql = "from Users user where user.loginName = :loginName and user.loginPwd = :loginPwd";
						query = session.createQuery(hql);
						query.setString("loginName", user.getLoginName());
						query.setString("loginPwd", user.getLoginPwd());
						
					}
					
				}
				
				return query.list();
			}
			
		});
		return (List)execute;
	}

}

5 创建一个包“com.ssh2test1.biz”,这是业务逻辑层,里面有一个接口“UserBiz.java”和它的实现类“UserBizImpl.java”,封装了登录操作


UserBiz.java:

package com.ssh2test1.biz;

import java.util.List;

import com.ssh2test1.entity.Users;

public interface UserBiz {
	public List<Users> login(Users user);
}

UserBizImpl.java

package com.ssh2test1.biz;

import java.util.List;

import com.ssh2test1.dao.UserDAO;
import com.ssh2test1.entity.Users;

public class UserBizImpl implements UserBiz {
	//依赖注入
	UserDAO userDAO;
	
	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	public List<Users> login(Users user) {	
		return userDAO.search(user);
	}

}

6 在applicationContext.xml里面添加UserDAO和UserBiz的实例,在上面的配置后面添加节点:

<!-- UserDAO实例 -->
	<bean id="userDAO" class="com.ssh2test1.dao.UserDAOImpl">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	
	<!-- UserBiz实例 -->
	<bean id="userBiz" class="com.ssh2test1.biz.UserBizImpl">
		<property name="userDAO" ref="userDAO"/>
	</bean>

7 Spring和Hibernate的整合到这里差不多就可以了,接下来在WebContent里新建testHibernateSpring.jsp,对前面的配置进行测试:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="org.springframework.context.ApplicationContext"%>    
<%@page import="org.springframework.context.support.ClassPathXmlApplicationContext"%>  
<%@page import="com.ssh2test1.biz.UserBiz"%>  
<%@page import="com.ssh2test1.entity.Users"%>  
<%@page import="java.util.List"%>  

<%
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	UserBiz userBiz = (UserBiz) context.getBean("userBiz");
	Users user = new Users();
	user.setLoginName("admin");
	user.setLoginPwd("admin");
	List list = userBiz.login(user);
	
	if(list.size() > 0)
		System.out.println("登录成功");
	else
		System.out.println("登录失败");
	
	
	%>

wKiom1ZX8CewOBHHAABQ1d3QCnk820.png

如果启动项目后运行testHibernateSpring.jsp文件显示上图这样的提示,则说明我们上面的Spring+Hibernate整合配置已经成功了


二 Spring整合Struts2并测试

1 编写视图页面login.jsplogin_success.jsp

login.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>    
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<base href="<%=basePath%>">
	<title>用户登录</title>
</head>
<body>
	<div align="right">
		<s:a href="">
			<h5><font color="blue">还未注册?点击注册</font></h5>
		</s:a>
	</div><br><br>
	<div align="center" style="color:#6DA500">
		<s:form action="login" method="post">
			<s:textfield name="username" label="账号"></s:textfield>
			<s:textfield name="password" label="密码"></s:textfield>
			<s:submit value="登录"></s:submit>
		</s:form>
	</div>

</body>
</html>

login_success.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>    
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<base href="<%=basePath%>">
	<title>我的主页</title>
</head>
<body>
	<h4 align="right"><font color="blue">欢迎您,${user }</font></h4>
</body>
</html>

2 web.xml里添加Struts2过滤器

<!-- 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>

3 在applicationContext.xml中添加Struts2的Action的实例

<!-- UserManagerAction实例 -->
	<bean id="umAction" class="com.ssh2test1.action.UserManagerAction">
		<property name="userBiz" ref="userBiz" />
	</bean>

4 在src根目录下新建struts.xml,并配置。注意的是,在这里class属性不再使用类的全名,而是使用applicationContext.xml中定义的Action的Bean实例名称


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.action.extension" value="do,action"></constant>
	<constant name="struts.i18n.encoding" value="utf-8"></constant>
	
	<package name="default" extends="struts-default">
		<action name="login" class="umAction">
			<result name="error">login.jsp</result>
			<result name="success" type="redirect">login_success.jsp</result>
		</action>
		
	</package>
</struts>

5 新建包“com.ssh2test1.action”,并创建一个Action类“UserManagerAction.java”,调用userBiz里的login()方法进行登录判断


UserManagerAction.java:

package com.ssh2test1.action;

import java.util.List;
import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.ssh2test1.biz.UserBiz;
import com.ssh2test1.entity.Users;

public class UserManagerAction extends ActionSupport {
	private static final long serialVersionUID = 1L;
	private String username,password;
	UserBiz userBiz;
	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 void setUserBiz(UserBiz userBiz) {
		this.userBiz = userBiz;
	}
	
	public String execute()throws Exception{
		Users user = new Users();
		user.setLoginName(username);
		user.setLoginPwd(password);
		
		List<Users> list = userBiz.login(user);
		
		if(list.size() > 0){
			ActionContext context = ActionContext.getContext();
			Map<String, Object> session = context.getSession();
			session.put("user", username);
			
			return SUCCESS;
		}
		else
			return ERROR;
	}
	
}

6 整个项目的配置步骤到此结束,现在启动项目后运行login.jsp进行测试,用户名:admin,密码:admin。如果登录成功后显示下图这样的页面,则表示全部配置已经成功了

wKioL1ZX8VuQ1vpPAAAuxESeN6I081.png

wKiom1ZX8PzjZvVvAAAupmCryCg412.png


附:源代码和SQL文件下载链接:http://down.51cto.com/data/2122558

(PS:如果没有下载豆的话,可以看我个人博客上的这篇文章,里面有百度云盘的链接。传送门:最新版使用ssh框架(struts2-x-spring4-x-hibernate5-x)搭建javaweb开发环境实例