SSH三个框架的知识点
1. Hibernate的核心配置文件
1.1 数据库信息、连接池配置
1.2 Hibernate信息
1.3 映射配置
1.4 Hibernate核心配置文件
如果单纯使用Hibernate框架,核心配置文件名称hibernate.cfg.xml并且一定要放在src下面,而hibernate和spring整合的时候,hibernate核心配置文件名称和位置没有固定要求的(因为到时候会有一个参数指定其位置)。
2. Hibernate映射配置文件
2.1 实体类和数据库表映射关系:使用的是ORM思想
3. hibernate操作的步骤
3.1 在Spring框架对hibernate框架进行封装,使用HibernateTemplate类
1. Action相关的操作
1.1 action创建三种方式:
写一个POJO,并在其中写上 public String execute();方法
创建一个类并实现Action接口
使用的最多的方法是集成类ActionSupport
1.2 配置action访问路径
创建struts.xml配置文件,这个文件名称和位置固定src下面
1.3 配置访问action的多个方法
使用通配符的方式配置比较常见
1.4 在action获取表单提交数据
获取request对象,Struts2提供的API有ActionContext和ServletActionContext
属性封装
模型驱动,要实现ModelDriven接口
1.5 在action中操作域对象
使用ServletActionContext获取域对象
1.6 在web.xml中配置Struts提供的过滤器
2. 值栈
值栈在开发中用得不多,掌握两点:
2.1 向值栈中放数据
set方法
push方法
定义变量生成get方法
2.2 从值栈中获取数据
在jsp中使用struts2标签+ognl获取
1 <s:property> 2 3 <s:iterator>
3. 拦截器
3.1 AOP和责任链
3.2 自定义拦截器
自定义拦截器可以通过继承MethodFilerInterceptor创建
1. Spring框架核心配置文件
1.1 名称和位置没有固定要求,官方推荐使用applicationContext.xml作为配置文件名
1.2 在Spring核心配置文件中引入Schema约束
2. 创建对象
2.1 xml配置方式:
2.2 注解方式:四个注解,Component,Service,Controller,Repository
3. 注入属性
3.1 xml配置方式
3.2 注解方式:两个直接,Resource,Autowired
4. 使用ServletContext对象和监听器实现
4.1 在服务器启动的时候,加载Spring,监听器的配置在web.xml中
4.2 配置Spring的监听器
4.3 指定Spring配置文件的位置
4.4 要导入一个Spring整合web项目的jar包
5. AOP的思想以及JdbcTemplate的使用
1. web应用的三层为:
1.1 web层,(struts2),Struts2框架用的最多的是action
1.2 service层(spring),spring中用的最多的是IoC和AOP,把对象的创建交给Spring进行管理
1.3 dao层(hibernate),hibernate则是用来操作数据库,进行CRUD
2. 哪么这三个框架应该是如何整合呢?
思想是两两整合:
2.1 struts2和Spring进行整合
2.1.1 在struts中action的创建交给Spring进行创建,但是要注意action是多实例的。
2.1.2 要注意导入spring整合Struts2的jar包
2.2 hibernate和Spring进行整合
2.2.1 hibernate中的核心类是SessionFactory,这里要把SessionFactory的创建交给Spring进行管理
2.2.2 Hibernate的核心文件中进行了数据库信息的配置,这里也要交给Spring进行处理
2.2.3 为Dao对象配置持久层的Spring提供的Template
2.2.4 注意导入Spring整合DAO层的ORM包
1. 把Struts2的action交给Spring进行管理
2. 实现过程
2.1 导入用于整合的jar包
图5-1 Spring单独使用需要导入的jar包
2.2 Spring为了整合Struts还需要额外再导入一个jar包:
图5-2 Spring整合Struts2所需的jar包
2.3 导入Struts2的jar包(struts2版本为2.3.24):
图5-3 Struts2中所需的最少jar包
其实图5-3中的jar包就是在Struts2项目解压之后的apps中有一个blank项目,将其中的jar包导入进来。
3. 创建Action
1 package com.ssh.domain; 2 3 import com.opensymphony.xwork2.ActionSupport; 4 5 public class UserAction extends ActionSupport { 6 7 @Override 8 public String execute() throws Exception { 9 10 return NONE; // 表示不返回到任何页面中去 11 } 12 13 }
4. 创建Strut2的核心配置文件
1 xml version="1.0" encoding="UTF-8"?> 2 3 <!DOCTYPE struts PUBLIC 4 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 5 "http://struts.apache.org/dtds/struts-2.3.dtd"> 6 7 <struts> 8 9 <package name="demo1" extends="struts-default" namespace="/"> 10 11 <action name="userAction" class="com.ssh.domain.UserAction"> 12 13 action> 14 15 package> 16 17 struts>
位置在src下面,名称是struts.xml
5. 在web.xml中配置struts2的过滤器
1 xml version="1.0" encoding="UTF-8"?> 2 <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_2_5.xsd" id="WebApp_ID" version="2.5"> 3 <display-name>spring_struts2display-name> 4 <welcome-file-list> 5 <welcome-file>index.htmlwelcome-file> 6 <welcome-file>index.htmwelcome-file> 7 <welcome-file>index.jspwelcome-file> 8 <welcome-file>default.htmlwelcome-file> 9 <welcome-file>default.htmwelcome-file> 10 <welcome-file>default.jspwelcome-file> 11 welcome-file-list> 12 13 <filter> 14 <filter-name>struts2filter-name> 15 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class> 16 filter> 17 18 <filter-mapping> 19 <filter-name>struts2filter-name> 20 <url-pattern>/*url-pattern> 21 filter-mapping> 22 web-app>
至此,上面四步已经将Struts2的环境配置好了,然后就是来配置Spring了。
6. 导入Spring整合Web项目的jar包,也就是监控项目启动的监听器所在的jar包。
图5-4 Spring整合web项目需要的jar包
7. 创建Spring的核心配置文件并在其中引入约束
这个约束配置的比较多,可以直接拿过来使用的。
1 xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/context 10 http://www.springframework.org/schema/context/spring-context.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx/spring-tx.xsd"> 15 16 beans>
8. 把action交给Spring进行配置
1 2 3 <bean id="userAction" class="com.ssh.domain.UserAction" scope="prototype">bean>
但是如果Struts2和Spring像这样分别配置了Action的话,这样就不起作用了,这里的做法就是不在Struts2的配置文件struts.xml中写全路径,因为这样就不是从Spring中取出来的,这里将Struts2中Action的配置改为:
图5-4 Struts2从Spring中取出Action的配置
之所以这可以这样写的原因是我们导入了一个Spring整合Struts2的一个jar包,也就是图5-2所示。
9. Spring监听器的配置
接下来还要在web.xml中配置Spring的监听器,以及加入对应的参数,如果不配置的话,那么项目启动的时候会报错,这两个要配全,不要配错了。
1 <context-param> 2 <param-name>contextConfigLocationparam-name> 3 4 <param-value>classpath:bean.xmlparam-value> 5 context-param> 6 7 8 <listener> 9 <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class> 10 listener>
图5-5 在web.xml中加入Spring的监听器报错
10. 测试准备
10.1 所需的为Struts2的核心配置文件:struts.xml
10.2 Spring的配置文件:bean.xml
10.3 项目的配置文件:web.xml
10.4 Struts2的UserAction类
10.5 在UserAction中对UserService的调用
10.6 UserService中对UserDao的调用
10.7 UserDao类的编写
struts.xml
1 xml version="1.0" encoding="UTF-8"?> 2 3 <!DOCTYPE struts PUBLIC 4 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 5 "http://struts.apache.org/dtds/struts-2.3.dtd"> 6 7 <struts> 8 9 <package name="demo1" extends="struts-default" namespace="/"> 10 11 12 <action name="userAction" class="userAction"> 13 14 action> 15 16 package> 17 18 struts>
bean.xml
1 xml version="1.0" encoding="UTF-8"?> 2 3 4 <beans xmlns="http://www.springframework.org/schema/beans" 5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xmlns:aop="http://www.springframework.org/schema/aop" 8 xmlns:tx="http://www.springframework.org/schema/tx" 9 xsi:schemaLocation="http://www.springframework.org/schema/beans 10 http://www.springframework.org/schema/beans/spring-beans.xsd 11 http://www.springframework.org/schema/context 12 http://www.springframework.org/schema/context/spring-context.xsd 13 http://www.springframework.org/schema/aop 14 http://www.springframework.org/schema/aop/spring-aop.xsd 15 http://www.springframework.org/schema/tx 16 http://www.springframework.org/schema/tx/spring-tx.xsd"> 17 18 19 20 <bean id="userAction" class="com.ssh.domain.UserAction" scope="prototype"> 21 <property name="userService" ref="userService">property> 22 bean> 23 24 25 <bean id="userDao" class="com.ssh.dao.UserDao">bean> 26 27 28 <bean id="userService" class="com.ssh.service.UserService"> 29 <property name="userDao" ref="userDao">property> 30 bean> 31 32 beans>
web.xml
1 xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://java.sun.com/xml/ns/javaee" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 5 id="WebApp_ID" version="2.5"> 6 <display-name>spring_struts2display-name> 7 <welcome-file-list> 8 <welcome-file>index.htmlwelcome-file> 9 <welcome-file>index.htmwelcome-file> 10 <welcome-file>index.jspwelcome-file> 11 <welcome-file>default.htmlwelcome-file> 12 <welcome-file>default.htmwelcome-file> 13 <welcome-file>default.jspwelcome-file> 14 welcome-file-list> 15 16 17 <context-param> 18 <param-name>contextConfigLocationparam-name> 19 20 <param-value>classpath:bean.xmlparam-value> 21 context-param> 22 23 24 <listener> 25 <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class> 26 listener> 27 28 29 <filter> 30 <filter-name>struts2filter-name> 31 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class> 32 filter> 33 34 <filter-mapping> 35 <filter-name>struts2filter-name> 36 <url-pattern>/*url-pattern> 37 filter-mapping> 38 39 web-app>
UserAction.java
1 package com.ssh.domain; 2 3 import com.opensymphony.xwork2.ActionSupport; 4 import com.ssh.service.UserService; 5 6 public class UserAction extends ActionSupport { 7 8 private UserService userService; 9 10 public UserService getUserService() { 11 return userService; 12 } 13 14 public void setUserService(UserService userService) { 15 this.userService = userService; 16 } 17 18 @Override 19 public String execute() throws Exception { 20 21 System.out.println("userAction ......."); 22 // 调用userService中方法发 23 userService.add(); 24 25 return NONE; // 表示返回到任何页面中去 26 } 27 28 }
UserService.java
1 package com.ssh.service; 2 3 import com.ssh.dao.UserDao; 4 5 public class UserService { 6 7 private UserDao userDao; 8 9 public UserDao getUserDao() { 10 return userDao; 11 } 12 13 public void setUserDao(UserDao userDao) { 14 this.userDao = userDao; 15 } 16 17 public void add() { 18 System.out.println("userService ......"); 19 userDao.add(); 20 } 21 22 }
UserDao.java
1 package com.ssh.dao; 2 3 public class UserDao { 4 5 public void add() { 6 System.out.println("userDao ......"); 7 } 8 9 } 10
11. 测试结果:
访问链接:http://localhost:8080/spring_struts2/userAction
可以在后台观察到如下测试结果:
图5-6测试结果
至此,Spring和Struts2的整合已经完毕,然后是Spring对Hibernate的整合了。
这里也要解决两个问题:
1. 把Hibernate中的核心配置文件中数据据库的配置交给Spring来管理
2. 把Hibernate中SessionFactory的创建也是交给Spring来管理的
3. 下面来看看具体的步骤:
3.1 导入Hibernate的jar包
图6-1 Hibernate中必须的jar包
图6-2 mysql的JDBC驱动包
图6-3 c3p0连接池的驱动包
导完了之后会发现有一个问题,在WEB-INF/lib中出现了这样的两个jar包:
图6-4 lib文件中的冲突包
其中javassist-3.11.0.GA.jar是Struts2中带的,而javassist-3.18.1-GA.jar是Hibernate中带的,但是这样会导致jar包冲突,这样的话我们应该只能用过其中的一个,但是我们应该用哪个呢,这里用的是高版本的那个,因为可以向下兼容,因此我们从lib中删除低版本的那个。
3.2 Spring和ORM相关jar包的导入
Spring整合Hibernate也不是简简单单的那种整合,也是需要导入jar包滴:
图6-5 Spring整合持久化层的jar包
3.3 搭建Hibernate环境
3.3.1 创建一个实体类:User.java
1 package com.ssh.domain; 2 3 public class User { 4 5 private String uid; 6 7 private String username; 8 9 private String password; 10 11 public String getUid() { 12 return uid; 13 } 14 public void setUid(String uid) { 15 this.uid = uid; 16 } 17 public String getUsername() { 18 return username; 19 } 20 public void setUsername(String username) { 21 this.username = username; 22 } 23 public String getPassword() { 24 return password; 25 } 26 public void setPassword(String password) { 27 this.password = password; 28 } 29 30 } 31
3.3.2 创建User.java的hibernate映射文件user.hbm.xml
1 xml version="1.0" encoding="UTF-8"?> 2 3 4 <!DOCTYPE hibernate-mapping PUBLIC 5 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 6 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 7 8 <hibernate-mapping> 9 10 11 <class name="com.ssh.domain.User" table="t_user" > 12 13 14 <id name="id" type="java.lang.String" column="uid" > 15 <generator class="native" /> 16 id> 17 18 19 <property name="username" type="java.lang.String"> 20 <column name="username" not-null="true" /> 21 property> 22 23 <property name="password" type="java.lang.String"> 24 <column name="password" not-null="true" /> 25 property> 26 27 class> 28 29 hibernate-mapping>
3.3.3 创建hibernate的核心配置文件hibernate.cfg.xml
1 xml version="1.0" encoding="UTF-8"?> 2 3 <!DOCTYPE hibernate-configuration PUBLIC 4 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 5 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 6 7 <hibernate-configuration> 8 <session-factory> 9 10 11 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty> 12 <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/spring_struts2property> 13 <property name="hibernate.connection.username">rootproperty> 14 <property name="hibernate.connection.password">123456property> 15 16 17 18 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialectproperty> 19 20 <property name="hibernate.show_sql">trueproperty> 21 22 <property name="hibernate.format_sql">trueproperty> 23 24 <property name="hibernate.hbm2ddl.auto">createproperty> 25 26 27 28 <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProviderproperty> 29 30 <property name="c3p0.min_size">5property> 31 32 <property name="c3p0.max_size">20property> 33 34 <property name="c3p0.timeout">120property> 35 36 <property name="c3p0.idle_test_period">3000property> 37 38 39 <property name="hibernate.connection.isolation">4property> 40 41 42 <mapping resource="com/ssh/domain/user.hbm.xml" /> 43 44 session-factory> 45 hibernate-configuration>
3.3.4把Hibernate核心配置文件中的数据库配置部分放到Spring中
下面这样写是错的,最好看看c3p0中的包,来看看ComboPooledDataSource.java中的属性是如何注入的:
1 2 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 3 4 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty> 5 <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/spring_struts2property> 6 <property name="hibernate.connection.username">rootproperty> 7 <property name="hibernate.connection.password">123456property> 8 bean>
注意,以上配置有误,有误,有误!!!
这一部分放到Spring中配置之后就可以不用在Hibernate中配置了。
3.3.5 Hibernate中的SessionFactory也交给Spring进行配置
1 // 首先在静态代码块中生成出sessionFactory 2 static { 3 try { 4 configuration.configure(configFile); 5 sessionFactory = configuration.buildSessionFactory(); 6 } catch(Exception e) { 7 System.err.println("%%%% Error Creating SessionFactory %%%%"); 8 e.printStackTrace(); 9 } 10 }
在这里的话SessionFactory的创建需要这么几行代码,SessionFactory要是交给Spring来管理,应该如何配置呢?
看如下的代码:
1 2 <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 3 4 <property name="dataSource" ref="dataSource">property> 5 6 <property name="configLocations" value="classpath:hibernate.cfg.xml">property> 7 bean>
以上配置要注意使用的Hibernate的版本,可以看出这里用的是5。
3.3.6 为UserDao.java中注入HibernateTemplate模板注入对象
1 2 <bean id="userDao" class="com.ssh.dao.UserDao"> 3 4 <property name="hibernateTemplate" ref="hibernateTemplate">property> 5 bean> 6 7 8 <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate"> 9 10 <property name="sessionFactory" ref="sessionFactory">property> 11 bean>
这样就可以在UserDao.java中使用HibernateTemplate了。
3.3.7 配置事务
利用注解的方式配置事务。
1 2 3 <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> 4 <property name="sessionFactory" ref="sessionFactory">property> 5 bean> 6 7 8 <tx:annotation-driven transaction-manager="transactionManager" />
Spring为不同的持久层框架配置了不同的事务管理的类,这里要注意选择不同的类。此外在Service类上要加上注解@Transactional,不加注解如果又在Dao中使用了HibernateTemplate的方法,就会报错的,下面就是血淋淋的错误。
3.3.8 测试准备:
UserDao类中:
1 package com.ssh.dao; 2 3 import org.springframework.orm.hibernate5.HibernateTemplate; 4 5 import com.ssh.domain.User; 6 7 public class UserDao { 8 9 private HibernateTemplate hibernateTemplate; 10 11 public HibernateTemplate getHibernateTemplate() { 12 return hibernateTemplate; 13 } 14 15 public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { 16 this.hibernateTemplate = hibernateTemplate; 17 } 18 19 public void add() { 20 21 System.out.println("userDao ......"); 22 23 // 用户添加的功能 24 User user = new User(); 25 user.setUsername("露西"); 26 user.setPassword("123224"); 27 28 hibernateTemplate.save(user); 29 } 30 31 }
然后开启项目,各种bug出来了!
总的来说有以下:
3.3.8.1 Hibernate的中HibernateTemplate和Hibernate事务管理的类的版本写成了3版本的,导致配置文件中和代码中的不一致
3.3.8.2 在Spring中配置数据库的选项和在Hibernate中配置数据库的是不一样的,之前照搬了hibernate中的
3.3.8.3 sessionFactory的创建也一直报异常
3.3.8.4 log4j.properties没加也出错,感觉不是这个的问题
3.3.8.5 在User类中的uid原来是String类型的,然后generator的方案为native的然后就出错了
3.3.8.6 配置文件能复制就不要手敲,不然很容易出错的
3.3.8.7 Service的类上没有加上@Transactional,但是Dao中又使用了HibernateTemplate中的方法
总而言之:测试结果
图6-6 测试UserAction异常
后来检查发现是没有在UserService的类上加事务注解@Transactional
最后测试:
访问:http://localhost:8080/spring_struts2/userAction
图6-7 控制台显示的测试结果
图6-8 数据库中数据已经插入
1. 导入jar包
2. 搭建struts2环境
2.1 创建Action,创建struts.xml配置文件
2.2 在web.xml中配置struts2的过滤器
3. 搭建Hibernate环境
3.1 创建实体类
3.2 配置实体类和数据库表的映射关系
3.3 创建hibernate核心配置文件,并引入映射配置文件
4. 搭建Spring环境
4.1 创建Spring的核心配置文件
4.2 让spring配置文件在服务器启动的时候加载,其中需要配置监听器和指定Spring配置文件的路径
5. struts2和spirng整合
5.1 把action在spring配置(action多实例的)
5.2 在struts.xml中action标签class属性里面写bean的id值
6. spring和hibernate整合
6.1 把hibernate核心配置文件中数据库的配置放到spring里面配置
6.2 把hibernate的sessionFactory在Spring中配置
7. 在dao中使用HibernateTemplate的对象
7.1 在dao中注入hibernateTemplate对象
7.2 在hibernate对象中注入sessionFactory
8. 配置事务
1. 能不new就不new出来
整个项目配置下来发现基本上是Spring掌控一切了,你要什么从我这里来拿行了,别自己(这里指的是Struts2和Hibernate)折腾。小项目这样感觉没有问题,但是模块变多的时候,岂不是显得Spring很臃肿?还是Spring可以通过引入其他的bean配置文件来分担配置。
2. 配置集中化
这里配置的集中化主要是体现在将Struts2和Hibernate中的核心配置往Spring中转移,比如最明显的就是Action和SessionFactory的配置。
3. 动别人的核心配置就要加jar包
比如Struts2中对Action的配置是要找到Action的全路径的,但是,在整合之后只用加入一个Spring中国配置的id就可以了,试想如果不搞事情,Strut2一读Action的class中的值,绝逼报找不到类,所以我们在这里加入了一个Spring整合Spring的jar包;另外,Hibernate中Sessionfaction的创建是要读取Hibernate的核心配置文件的,直接在Spring中配置SessionFactory实例也做不到,因此也导入了Spring整合ORM持久层的jar包,并配置了相关的参数。
4. 通过IoC解耦
像Spring这样一整合,确实有利于解耦合。
5. 对数据库的配置思路是,先获取其连接池对象,再指定SessionFactory的时候,只需要给它注入连接池就可以了