SSH入门Spring篇(1)——struts2+hibernate5+spring5整合

1.写在前面

spring的作用

传统设计举例:
一个类Person,另一个类Car,如果Person的某个方法比如说drive,需要引用Car,则称Person类依赖于 Car类。
延伸到对象,比如Person类的对象boy依赖于Car类的对象toyota,这种依赖关系依然成立。
而在控制反转(IoC)模式下:
创建被调用者的工作不再由调用者来完成,两者之间的依赖关系由Spring管理,使得两者解耦;
也即不希望以上面例子中的person类去new一个car类的实例,而是添加一个set方法

对控制反转的理解

控制反转其实是从依赖一个实体类转为依赖接口。这样做的好处在于可以装配接口的不同具体实现。

2.一个非常简单的spring例子(由依赖类到依赖接口)

导入spring的4个基础jar包以及common-logging-1.2.jar

spring包下载地址
找到对应版本点击之后下载spring-framework-x.x.x.RELEASE-dist.zip就可以了
在这里我也附一个自己的网盘下载链接,5.1.2版本的:网盘链接 提取码lwmp

在这里需要导入的四个基础jar包:
在这里插入图片描述
不要忘了导入common-logging-1.2.jar噢

抽象接口 ICustomerDao.java

package com.test.dao;

public interface ICustomerDao {
	public void save();
}

实现类 CustomerDao.java

package com.test.dao;

public class CustomerDao implements ICustomerDao {

	public CustomerDao() {
		// TODO Auto-generated constructor stub
		System.out.println("create CustomerDao.");
	}

	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("execute --save()-- method.");
	}

}

配置文件 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-4.0.xsd"> 
		<bean id="userDAO" class="cn.edu.zjut.dao.CustomerDao" />
</beans> 

测试代码

spring是非侵入式框架,也就是说除了测试代码之外的所有程序代码中都不会有spring组件。
在这里我们可以看到它使用了getBean("userDAO")获取实例,这里双引号中的内容是userDao是参考applicationContext.xml中的bean id的内容。

package com.test.app;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.edu.zjut.dao.ICustomerDao;

public class SpringEnvTest {

	public static void main(String[] args) {
		//创建Spring容器 
		ApplicationContext ctx = new ClassPathXmlApplicationContext( "applicationContext.xml"); 
		//获取CustomerDAO实例 
		ICustomerDao userDao = (ICustomerDao) ctx.getBean("userDAO");
		userDao.save();
 
	}

}

3.ssh框架整合

a. 将需要的包导入到web-inf的lib目录中

【hibernate相关】
导入hibernate5-required中的包:网盘链接
提取码:a7dw
在这里插入图片描述

【struts相关】
之前写struts时用到的包:
在这里插入图片描述
除此之外还需要用到一个新的包:struts2-spring-plugin-x.x.x
若是没有这个包会报错的!!

【spring相关】
基础包:比上面的简单例子多了一个spring-web
在这里插入图片描述
还有三个与数据库相关的jar包:
在这里插入图片描述

b. spring整合hibernate

①po下的文件无变化(Customer.java和Customer.hbm.xml)

Customer.java

package cn.edu.zjut.po;

import java.io.Serializable;
import java.util.Date;

public class Customer implements Serializable {

	public Customer() {
		// TODO Auto-generated constructor stub
	}

	private int customerId; 
	private String account; 
	private String password; 
	private String name; 
	private Boolean sex; 
	private Date birthday; 
	private String phone; 
	private String email; 
	private String address; 
	private String zipcode; 
	private String fax;
	
	public Customer(int customerId, String account, String password, String name, Boolean sex, Date birthday,
			String phone, String email, String address, String zipcode, String fax) {
		super();
		this.customerId = customerId;
		this.account = account;
		this.password = password;
		this.name = name;
		this.sex = sex;
		this.birthday = birthday;
		this.phone = phone;
		this.email = email;
		this.address = address;
		this.zipcode = zipcode;
		this.fax = fax;
	}

	public Customer(int customerId) {
		super();
		this.customerId = customerId;
	}

	public int getCustomerId() {
		return customerId;
	}

	public void setCustomerId(int customerId) {
		this.customerId = customerId;
	}

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getName() {
		return name;
	}

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

	public Boolean getSex() {
		return sex;
	}

	public void setSex(Boolean sex) {
		this.sex = sex;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String getPhone() {
		return phone;
	}

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

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getAddress() {
		return address;
	}

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

	public String getZipcode() {
		return zipcode;
	}

	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}

	public String getFax() {
		return fax;
	}

	public void setFax(String fax) {
		this.fax = fax;
	}
	

}

Customer.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="cn.edu.zjut.po.Customer" table="customer" schema="dbo">
		<id name="customerId" type="java.lang.Integer">
			<column name="customerID" />
			<generator class="increment" />
		</id>
		<property name="account" type="java.lang.String">
			<column name="account" length="20" unique="true" />
		</property>
		<property name="password" type="java.lang.String">
			<column name="password" length="20" />
		</property>
		<property name="name" type="java.lang.String">
			<column name="name" length="20"></column>
		</property>
		<property name="sex" type="java.lang.Boolean">
			<column name="sex" />
		</property>
		<property name="birthday" type="date">
			<column name="birthday" length="10" />
		</property>
		<property name="phone" type="java.lang.String">
			<column name="phone" length="20" />
		</property>
		<property name="email" type="java.lang.String">
			<column name="email" length="100" />
		</property>
		<property name="address" type="java.lang.String">
			<column name="address" length="200" />
		</property>
		<property name="zipcode" type="java.lang.String">
			<column name="zipcode" length="10" />
		</property>
		<property name="fax" type="java.lang.String">
			<column name="fax" length="20" />
		</property>
	</class>
</hibernate-mapping>
②BaseHibernateDao.java
package cn.edu.zjut.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class BaseHibernateDao {

	private SessionFactory sessionFactory;


	public Session getSession() {
		return sessionFactory.openSession();
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

}

③抽象出来的接口ICustomerDao.java
package cn.edu.zjut.dao;

import cn.edu.zjut.po.Customer;

public interface ICustomerDao {
	public void save(Customer aCus);
}
④CustomerDao.java-实现ICustomerDao接口并继承 BaseHibernateDao
package cn.edu.zjut.dao;

import org.hibernate.Session;
import org.hibernate.Transaction;

import cn.edu.zjut.po.Customer;

public class CustomerDao extends BaseHibernateDao implements ICustomerDao {

	public CustomerDao() {
		// TODO Auto-generated constructor stub
		System.out.println("create CustomerDao.");
	}

	@Override
	public void save(Customer aCus) {
		// TODO Auto-generated method stub
		Transaction tran = null; 
		Session session = null; 
		try { 
			session = getSession(); 
			tran = session.beginTransaction(); 
			session.save(aCus); 
			tran.commit(); 
		} catch (RuntimeException re) {
			if(tran != null) 
				tran.rollback();
			throw re; 
		} finally { 
			session.close(); 
		}

	}

}

⑤UserService.java及其抽象出来的接口IUserService.java

IUserService.java:

package cn.edu.zjut.service;

import cn.edu.zjut.po.Customer;

public interface IUserService {
	public void register(Customer aCus);
}

UserService.java:
这里依赖CustomerDao,但是并没有去new它,而是提供了一个set方法。
为什么不用提供Customer的私有属性和set方法?因为它是由上一层传参进来的,原来也并不需要在这里new

package cn.edu.zjut.service;

import cn.edu.zjut.dao.ICustomerDao;
import cn.edu.zjut.po.Customer;

public class UserService implements IUserService {
	
	private ICustomerDao customerDao = null;

	public UserService() {
		// TODO Auto-generated constructor stub
		System.out.println("create UserService.");

	}
	
	public void setCustomerDao(ICustomerDao customerDao) {
		System.out.println("--setCustomerDAO--");
		this.customerDao = customerDao;
	}

	@Override
	public void register(Customer aCus) {
		// TODO Auto-generated method stub
		System.out.println("execute --register()-- method."); 
		customerDao.save(aCus);

	}

}

⑥spring配置文件applicationContext.xml

理一下上面这些类的依赖关系:UserService依赖CustomerDao,CustomerDao依赖Customer。
由于CustomerDao没有和Customer有关的属性,因此不需要在<bean></bean>中间写property。

<?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.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd">
	
		<!-- 配置数据源 -->
		<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
			<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
			<property name="url" value="jdbc:sqlserver://localhost:1433;DatabaseName=hibernatedb"/>
			<property name="username" value="sa"/>
			<property name="password" value="123456"/>
		</bean>
		
		<!-- 把数据源注入给session工厂 -->
		<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
			<property name="dataSource" ref="dataSource" />
			
			<!-- 配置映射文件 -->
			<property name="mappingResources">
				<list>
					<value>cn/edu/zjut/po/Customer.hbm.xml</value>
				</list>
			</property>
		</bean> 
		
		<!-- 把dao注册给session工厂 -->
		<bean id="baseDao" class="cn.edu.zjut.dao.BaseHibernateDao">
			<property name="sessionFactory" ref="sessionFactory" />
		</bean>
		 
		<bean id="userDAO" class="cn.edu.zjut.dao.CustomerDao" parent="baseDao"/>
		<bean id="userService" class="cn.edu.zjut.service.UserService">
			<property name="customerDao" ref="userDAO" />
		</bean>
</beans> 

注意这里在把数据源注入给session工厂的时候class是org.springframework.orm.hibernate5.LocalSessionFactoryBean,是因为这里是spring5,如果用的是spring4,那么这里要改成hibernate4。另外不要尝试用hibernate4搭配spring5这样…因为spring5用的是hibernate5,而hibernate4和5中有些jar包中类的位置是不一样的,很容易就classNotFound.

c. spring整合Struts

①UserAction.java——不再new它的依赖类

依赖UserService.java和Customer.java.同样的这里也并没有去直接new一个UserService对象或者Customer对象,而是提供了set方法。

package cn.edu.zjut.action;

import cn.edu.zjut.po.Customer;
import cn.edu.zjut.service.IUserService;

public class UserAction {

	private Customer loginUser;
	private IUserService userService = null;
	
	public Customer getLoginUser() {
		return loginUser;
	}
	public void setLoginUser(Customer loginUser) {
		this.loginUser = loginUser;
	}
	
	public void setUserService(IUserService userService) {
		this.userService = userService;
	}
	
	public String execute() {
		userService.register(loginUser);
		return "success";
	}
	

}

②为UserAction增加applicationContext.xml中的内容

增加内容:
注意action的scope必须是prototype(这个在后面的博客中会解释)
那么为什么对于UserAction来说,它不仅依赖UserService,也依赖Customer,这里却没有customer的property呢?
因为action里的customer并不是由spring装配的,而是由struts装配的,因为它是从表单传过来的呀!

<bean id="userAction" class="cn.edu.zjut.action.UserAction" scope="prototype"> 
	<property name="userService" ref="userService" />
</bean> 
③src下的struts.xml,一点点小变化

struts.xml:
变化在于class这里,不再是完整的包名.类名,而是使用了userAction,而这个userAction是在applicationContext.xml中规定的bean的id

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> 
<struts>
	<package name="strutsBean" extends="struts-default" namespace="/">
		<action name="register" class="userAction">
			<result name="success">/regSuccess.jsp</result>
			<result name="fail">/regFail.jsp</result>
		</action>
	</package>
</struts>
④web.xml——需要添加对spring监听器的配置

在这里配置监听器的作用:在启动Web容器时,自动装配spring applicationContext.xml的配置信息。
因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。在ContextLoaderListener中关联了ContextLoader这个类,所以整个加载配置过程由ContextLoader来完成。
如果不配置监听器这里会报错:userAction not found

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

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<!-- 让Struts2的核心Filter拦截所有请求 -->
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<!-- 这个在这里可以不写 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>WEB-INF/applicationContext.xml</param-value>
	</context-param>
	
	<!-- 配置监听器 -->
	<listener>
		<listener-class> org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener> 

</web-app>
⑤register.jsp和regSuccess.jsp——无变化

register.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<s:head theme="xhtml"/>
	<sx:head parseContent="true" extraLocales="UTF-8"/>
</head>
<body>
	<s:form action="register" method="post">
		<s:textfield name="loginUser.account" label="请输入用户名" />
		<s:password name="loginUser.password" label="请输入密码" />
		<s:textfield name="loginUser.name" label="请输入真实姓名" />
		<s:radio name="loginUser.sex" list="#{true:'',false:''}" label="请输入性别" />
		<sx:datetimepicker name="loginUser.birthday" displayFormat="yyyy-MM-dd" label="请输入生日" />
		<s:textfield name="loginUser.address" label="请输入联系地址" />
		<s:textfield name="loginUser.phone" label="请输入联系电话" />
		<s:textfield name="loginUser.email" label="请输入电子邮箱" />
		<s:textfield name="loginUser.zipcode" label="请输入邮编" />
		<s:textfield name="loginUser.fax" label="请输入传真" />
		<s:submit value="注册" />
		<s:reset value="重置"/>
	</s:form>
</body>
</html>

regSuccess.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>登录成功页面</title>
</head>
<body>
	<s:property value="loginUser.name" />
	<s:if test="%{loginUser.sex==true}">
		<s:text name="先生,"/>
	</s:if>
	<s:else>
		<s:text name="女士,"/>
	</s:else>
	您注册成功了!
	<s:set name="user" value="loginUser" scope="session" />
</body>
</html>

d.关于applicationContext文件的放置位置

spring的配置文件applicationContext.xml的默认地址在WEB-INF下,这时是不用特地在web.xml中标记的。当然如果要标记也可以,就像这样:

<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>WEB-INF/applicationContext.xml</param-value>
	</context-param>

但在实际的开发过程中,我们可能需要调整applicationContext.xml的位置,以使程序结构更加的清晰。在web.xml中,配置Spring配置文件的代码如下:

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>路径</param-value>
</context-param>

例如我们在最前面写简单的例子的时候,就是把它直接放在src下的,当然这时候不牵涉到struts和hibernate是没有问题的。但是如果我们ssh时想把它放在src下呢?

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:applicationContext.xml</param-value>
</context-param>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值