# Spring 4 + Struts 2 + Hibernate 集成教程 > 原文: [https://howtodoinjava.com/struts2/spring-4-struts-2-hibernate-integration-tutorial/](https://howtodoinjava.com/struts2/spring-4-struts-2-hibernate-integration-tutorial/) 以前,我已经介绍了 [**Spring3 +休眠集成**](//howtodoinjava.com/spring/spring-orm/spring-3-and-hibernate-integration-tutorial-with-example/ "Spring3 and hibernate integration tutorial with example") 示例和 [**struts 2 hello world**](//howtodoinjava.com/struts-2/struts-2-hello-world-example-application/ "Struts 2 hello world example application") 示例。 在本教程中,我将讨论将 spring 框架与 Struts 和 Hibernate 结合使用时要记住的所有重要点。 另外,请注意,本教程使用了其他次要但很重要的概念,例如日志记录,TLD 的使用和事​​务以及已集成到本教程中。 因此,请记住还要检查其详细信息。 在本教程中,我将使用简单的功能(例如全部获取,添加和删除)来构建员工管理屏幕。 它看起来像这样: ![home screen for spring struts hibernate integration](img/6ee1537649c1d220ab78f8c9bbe88881.png) 我将按照以下步骤讨论集成过程: ```java 1) Integration Overview 2) Spring + Struts Integration 3) Spring + Hibernate Integration 4) Other Integrated Functionalities a) Log4j b) TLDs c) Transactions 5) Important Points to Keep Remember 6) Database Schema Used in Tutorial 7) Download Sourcecode ``` ## 1)整合概述 在进入集成细节之前,让我们先确定一下 ***为什么我们需要此集成*** 本身。 像 Struts 一样,Spring 也可以充当 MVC 实现。 两种框架都有其优缺点,仍然有很多人会同意 **Spring 更好**,并且提供了更广泛的功能。 对我来说,只有两种情况,您需要本教程中提供的信息: **i)**您有一个用 Struts 编写的旧应用,并且想要使用 spring 来提高应用的功能很多倍。 **ii)**您确实想根据自己的原因来学习它。 否则,我不知道为什么有人会在春季选择支柱。 如果您知道其他一些好的理由,请与我们所有人分享。 那挺棒的。 继续,在本教程中,我将**委托从 Struts 到 Spring** 进行动作管理。 进行委派的原因是,通过 Spring 上下文实例化 Action 类时,它可以使用 spring 在其自己的 MVC 实现中为其提供的 Controller 类的所有其他功能。 因此,您将获得所有 spring 功能以及 struts Action 类,以具有包括 ActionForm 概念在内的控制器逻辑。 ## 2)Spring + Struts 集成 这是核心逻辑,从在 web.xml 中注册`ContextLoaderListener`和`StrutsPrepareAndExecuteFilter`开始。 `ContextLoaderListener`带有初始化参数 ***contextConfigLocation*** ,并负责设置和启动 Spring `WebApplicationContext`。 现在,struts 将在与 Spring 相关的服务中特别是在[依赖项注入](//howtodoinjava.com/spring/spring-core/inversion-of-control-ioc-and-dependency-injection-di-patterns-in-spring-framework-and-related-interview-questions/ "Inversion of control (IoC) and dependency injection (DI) patterns in spring framework and related interview questions")中利用此上下文。 `StrutsPrepareAndExecuteFilter`在类路径中查找 ***struts.xml*** 文件,并配置 strut 的特定内容,例如动作映射,全局转发和其他在 struts.xml 文件中定义的内容。 **web.xml** ```java Spring+Struts+Hibernate Integration Example /WEB-INF/index.jsp contextConfigLocation classpath:beans.xml org.springframework.web.context.ContextLoaderListener struts2 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter debug 0 detail 0 struts2 /* /tags/struts-bean /WEB-INF/struts-bean.tld /tags/struts-html /WEB-INF/struts-html.tld /tags/struts-logic /WEB-INF/struts-logic.tld /tags/struts-nested /WEB-INF/struts-nested.tld ``` 第二步,将在 **struts.xml** 文件中创建操作映射,如下所示: **struts.xml** ```java /view/editEmployeeList.jsp /list {1} /list /view/editEmployeeList.jsp ``` In strut’s alone application we would have full Action Class with it’s package information in “class” attribute. Here we have given the class name as editEmployeeAction. Where is it defined? We will ask Spring to lookup for us. Spring 上下文文件 **beans.xml** 是典型的 Spring 单独上下文文件,具有 Web 应用运行所需的所有内容,其中包括 struts 正在寻找的 bean 定义`editEmployeeAction`。 **beans.xml** ```java classpath:hibernate.cfg.xml org.hibernate.cfg.AnnotationConfiguration ${jdbc.dialect} true ``` 这是我们要做的**将支撑架与 spring** 框架集成在一起的所有步骤。 现在,您的动作类如下所示: **EditEmployeeAction.java** ```java package com.howtodoinjava.controller; import java.util.List; import org.apache.log4j.Logger; import com.howtodoinjava.entity.EmployeeEntity; import com.howtodoinjava.service.EmployeeManager; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.Preparable; public class EditEmployeeAction extends ActionSupport implements Preparable { private static final long serialVersionUID = 1L; //Logger configured using log4j private static final Logger logger = Logger.getLogger(EditEmployeeAction.class); //List of employees; Setter and Getter are below private List employees; //Employee object to be added; Setter and Getter are below private EmployeeEntity employee; //Employee manager injected by spring context; This is cool !! private EmployeeManager employeeManager; //This method return list of employees in database public String listEmployees() { logger.info("listEmployees method called"); employees = employeeManager.getAllEmployees(); return SUCCESS; } //This method will be called when a employee object is added public String addEmployee() { logger.info("addEmployee method called"); employeeManager.addEmployee(employee); return SUCCESS; } //Deletes a employee by it's id passed in path parameter public String deleteEmployee() { logger.info("deleteEmployee method called"); employeeManager.deleteEmployee(employee.getId()); return SUCCESS; } //This method will be called before any of Action method is invoked; //So some pre-processing if required. @Override public void prepare() throws Exception { employee = null; } //Getters and Setters hidden } ``` Spring 还将 DAO 引用注入到 Manager 类。 **EmployeeManagerImpl.java** ```java package com.howtodoinjava.service; import java.util.List; import org.springframework.transaction.annotation.Transactional; import com.howtodoinjava.dao.EmployeeDAO; import com.howtodoinjava.entity.EmployeeEntity; public class EmployeeManagerImpl implements EmployeeManager { //Employee dao injected by Spring context private EmployeeDAO employeeDAO; //This method will be called when a employee object is added @Override @Transactional public void addEmployee(EmployeeEntity employee) { employeeDAO.addEmployee(employee); } //This method return list of employees in database @Override @Transactional public List getAllEmployees() { return employeeDAO.getAllEmployees(); } //Deletes a employee by it's id @Override @Transactional public void deleteEmployee(Integer employeeId) { employeeDAO.deleteEmployee(employeeId); } //This setter will be used by Spring context to inject the dao's instance public void setEmployeeDAO(EmployeeDAO employeeDAO) { this.employeeDAO = employeeDAO; } } ``` ## 3)Spring + Hibernate 集成 现在我们必须将休眠集成到应用中。 最好的地方是利用 Spring 的强大功能进行集成,以充分利用依赖注入来与不同的 ORM 一起使用。 上面 **beans.xml** 文件中已经给出了 Spring 所需的休眠依赖关系。 您将需要的其他文件是: **hibernate.cfg.xml** ```java ``` **jdbc.properties** ```java jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.dialect=org.hibernate.dialect.MySQLDialect jdbc.databaseurl=jdbc:mysql://127.0.0.1:3306/test jdbc.username=root jdbc.password=password ``` **EmployeeDaoImpl.java** ```java package com.howtodoinjava.dao; import java.util.List; import org.hibernate.SessionFactory; import org.springframework.stereotype.Repository; import com.howtodoinjava.entity.EmployeeEntity; @Repository public class EmployeeDaoImpl implements EmployeeDAO { //Session factory injected by spring context private SessionFactory sessionFactory; //This method will be called when a employee object is added @Override public void addEmployee(EmployeeEntity employee) { this.sessionFactory.getCurrentSession().save(employee); } //This method return list of employees in database @SuppressWarnings("unchecked") @Override public List getAllEmployees() { return this.sessionFactory.getCurrentSession().createQuery("from EmployeeEntity").list(); } //Deletes a employee by it's id @Override public void deleteEmployee(Integer employeeId) { EmployeeEntity employee = (EmployeeEntity) sessionFactory.getCurrentSession() .load(EmployeeEntity.class, employeeId); if (null != employee) { this.sessionFactory.getCurrentSession().delete(employee); } } //This setter will be used by Spring context to inject the sessionFactory instance public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } } ``` 供您参考,EmployeeEntity 类如下所示: **EmployeeEntity.java** ```java package com.howtodoinjava.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="EMPLOYEE") public class EmployeeEntity { @Id @Column(name="ID") @GeneratedValue private Integer id; @Column(name="FIRSTNAME") private String firstname; @Column(name="LASTNAME") private String lastname; @Column(name="EMAIL") private String email; @Column(name="TELEPHONE") private String telephone; //Setters and Getters } ``` ## 4)其他集成功能 除了 struts + spring + hibernate,我们还使用以下组件来构建应用。 #### a)Log4j Spring 通过扫描类路径中的`log4j`自动配置日志记录。 我们使用`pom.xml`文件添加了 log4j 依赖项。 现在,您只需要在类路径中放置一个 log4j.xml 或 log4j.properties 文件。 **log4j.properties** ```java log4j.rootLogger=info, stdout, R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=c:/log/demo.log log4j.appender.R.MaxFileSize=100KB log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ``` #### b)顶级域名 如果您查看`web.xml`文件,我们在其中包含了一些 TLD。 我们可以随时在视图层中使用它们,如下所示: **editEmployeeList.jsp** ```java <%@ taglib prefix="s" uri="/struts-tags"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> Spring-4 + Struts-3 + Hibernate Integration Demo

Spring-4 + Struts-3 + Hibernate Integration Demo

Employees

Name Email Telephone Actions
${emp.lastname}, ${emp.firstname} ${emp.email} ${emp.telephone} delete
``` #### c)交易 EmployeeManagerImpl.java 在诸如 getAllEmployees()和 deleteEmployee()之类的方法中使用注解@Transactional。 这实际上是在单个事务中运行在此方法下执行的所有数据库查询。 像这样在`beans.xml`上下文文件中声明了事务依赖项。 ```java ``` ## 5)要记住的要点 **a)** **如果运行时无法找到 lib 文件夹中存在的类,则将来自项目依赖项的 jar 文件添加到项目部署程序集**中。 **b)**使 bean.xml 中定义的 Action 类的**作用域为“原型”** 。 Spring 提供的 bean 的默认范围是单例,并且必须为每个请求创建新的 Struts Action 类,因为它包含特定于用户会话的数据。 为了容纳两者,请将 Action 类 bean 标记为原型。 **c)**在运行此应用之前,请不要忘记**设置数据库**。 如果安装不正确,将导致您出现一些异常。 **d)**另外,请**在项目运行时依赖项中也包括** `struts2-spring-plugin`。 ## 6)教程中使用的数据库架构 下表已在 MySQL 中的名为“ test”的数据库中创建。 ```java CREATE TABLE EMPLOYEE ( ID INT PRIMARY KEY AUTO_INCREMENT, FIRSTNAME VARCHAR(30), LASTNAME VARCHAR(30), TELEPHONE VARCHAR(15), EMAIL VARCHAR(30), CREATED TIMESTAMP DEFAULT NOW() ); ``` 如果您打算自己构建应用,则在下面给定的**直接在此应用中使用的结构**将为您提供帮助。 ![directory structure for spring struts hibernate integration](img/72fb9341ae56b76bae73c5c72b7d7b06.png) Directory structure for spring struts hibernate integration 此项目中使用的`pom.xml`文件具有所有项目相关性(有些额外),如下所示: **pom.xml** ```java 4.0.0 com.howtodoinjava.app Spring4Struts2HibernateIntegration war 1.0-SNAPSHOT Spring4Struts2HibernateIntegration Maven Webapp http://maven.apache.org JBoss repository http://repository.jboss.org/nexus/content/groups/public/ 4.0.3.RELEASE junit junit 4.11 test org.apache.struts struts2-core 2.3.16.2 org.apache.struts struts2-spring-plugin 2.3.16.2 org.springframework spring-core ${org.springframework.version} runtime org.springframework spring-web ${org.springframework.version} runtime org.springframework spring-webmvc ${org.springframework.version} runtime org.springframework spring-beans ${org.springframework.version} org.springframework spring-context ${org.springframework.version} org.springframework spring-aop ${org.springframework.version} org.aspectj aspectjtools 1.6.2 cglib cglib 3.1 org.springframework spring-tx ${org.springframework.version} org.springframework spring-jdbc ${org.springframework.version} org.springframework spring-orm ${org.springframework.version} log4j log4j 1.2.15 javax.mail mail javax.jms jms com.sun.jdmk jmxtools com.sun.jmx jmxri runtime org.hibernate hibernate-core 3.6.3.Final javassist javassist 3.12.1.GA javax.servlet jstl 1.2 runtime taglibs standard 1.1.2 runtime commons-dbcp commons-dbcp 1.4 mysql mysql-connector-java 5.1.9 Spring3Struts2HibernateIntegration maven-compiler-plugin 2.3.2 1.6 1.6 ``` ## 7)下载源代码 下载以上示例的源代码或获取.war 文件。 [Download Source Code](https://drive.google.com/file/d/0B7yo2HclmjI4S2c5YldiNk44aVE/edit?usp=sharing "spring + struts + hibernate tutorial source code link") [Download .war File](https://drive.google.com/file/d/0B7yo2HclmjI4T2NrS19iRU5Hb3c/edit?usp=sharing "spring + struts + hibernate tutorial .war file link") 这是 **spring 4 + struts 2 + hibernate 集成**教程的全部内容。 让我知道您的想法和疑问。 **祝您学习愉快!**