一起学习Spring4.0(八)Spring整合Struts2

本节讲述Spring整合Struts2。

准备

Struts2官方示例jar包:struts2.3.15.3-blank
struts-2.3.15.3-lib
struts2官方示例web.xml
struts2官方配置文件struts.xml
spring4-required jar

Spring如何在WEB应用中使用

1).需要额外导入两个jar包。
spring-web-4.0.4.RELEASE.jar
spring-webmvc-4.0.4.RELEASE.jar
2).Spring的配置文件,和非WEB环境没有什么不同
3).需要在web.xml文件中加入如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 配置Spring配置文件的名称和位置 -->
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 启动IOC容器的ServletContextListener -->
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

4).如何创建IOC容器。
①.非WEB应用:在main方法中直接创建。
②.WEB应用:在WEB应用被服务器加载时就创建IOC容器:
在ServletContextListener#contextInitialized(ServletContextEvent sce)方法中创建IOC容器。
③.在WEB应用的其他组件中如何来访问IOC容器:
在ServletContextListener#contextInitialized(ServletContextEvent sce)方法中创建IOC容器后,可以把其放在ServletContext(即application 域)的一个属性中。
④.实际上,Spring配置文件的名字和位置应该也是可配置的!将其配置到当前WEB应用的初始化参数中较为合适。

点击new-> Other-> Dynamic web project,新建一个Web项目spring-05。

导入spring4-required jar包
新建包com.leezp.spring.struts2.beans。在该包下新建Person.java。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.leezp.spring.struts2.beans;
public class Person {
private String username;
public void setUsername(String username) {
this.username = username;
}
public void hello() {
System.out.println("My name is " + username);
}
}

新建Spring配置文件applicationContext.xml。

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.leezp.spring.struts2.beans.Person">
<property name="username" value="lee"></property>
</bean>
</beans>

在项目下新建包com.leezp.spring.struts2.listeners。
点击new-> Other-> Listener创建一个监听器。在Class Name项里填写监听器的名字。

点击Next,选择相应监听器。

点击finish。
查看新建的监听器SpringServletContextListener.java。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.leezp.spring.struts2.listeners;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class SpringServletContextListener
*
*/
@WebListener
public class SpringServletContextListener implements ServletContextListener {
/**
* Default constructor.
*/
public SpringServletContextListener() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
}

在该监听器的contextInitialized()方法中创建IOC容器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.leezp.spring.struts2.listeners;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Application Lifecycle Listener implementation class
* SpringServletContextListener
*
*/
@WebListener
public class SpringServletContextListener implements ServletContextListener {
/**
* Default constructor.
*/
public SpringServletContextListener() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent arg0) {
// 获取Spring配置文件的名称
ServletContext servletContext = arg0.getServletContext();
String config = servletContext.getInitParameter("configLocation");
// 1.创建IOC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
// 2.把IOC容器放在ServletContext的一个属性中
servletContext.setAttribute("ApplicationContext", ctx);
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
}
```

修改配置文件web.xml。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
``` bash
<?xml version="1.0" encoding="UTF-8"?>
<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_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- 配置Spring配置文件的名称和位置 -->
<context-param>
<param-name>configLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
<!-- 启动IOC容器的 ServletContextListener -->
<listener>
<listener-class>com.leezp.spring.struts2.listeners.SpringServletContextListener</listener-class>
</listener>
</web-app>

新建包com.leezp.spring.struts2.servlets。在该包下新建Servlet类TestServlet.java。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.leezp.spring.struts2.servlets;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.ApplicationContext;
import com.leezp.spring.struts2.beans.Person;
/**
* Servlet implementation class TestServlet
*/
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 1.从application域对象中得到IOC容器的引用
ServletContext servletContext = getServletContext();
ApplicationContext ctx = (ApplicationContext) servletContext
.getAttribute("ApplicationContext");
// 2.从IOC容器中得到需要的bean
Person person = ctx.getBean(Person.class);
person.hello();
}
}

新建web页面index.jsp。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ 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>
<a href="TestServlet">TestServlet</a>
</body>
</html>

运行项目,鼠标单击项目,右击,run as-> run on server-> next…

获取源代码

Spring如何整合Struts2

1).整合目标:使IOC容器来管理Struts2的Action!
2).整合方法:
①.正常加入Struts2
web.xml里加入Struts2的过滤器
添加Struts2的配置文件struts.xml。
②.在Spring的IOC容器中配置struts2的Action。
注意:在IOC容器中配置Struts2的Action时,需要配置scope属性,其值必须为prototype,即struts2的action是非单例的

1
2
3
<bean id="personAction" class="com.leezp.spring.struts2.actions.PersonAction" scope="prototype">
<property name="personService" ref="personService"></property>
</bean>

③.配置Struts2的配置文件
action节点的class属性不能再指向全类名,需要指向IOC容器中该bean的id。

1
2
3
<action name="person-save" class="personAction">
<result>/success.jsp</result>
</action>

④.导入jar:struts2-spring-plugin-2.3.15.3.jar
3).整合原理:通过添加struts2-spring-plugin-2.3.15.3.jar以后,Struts2会先从IOC容器中获取Action的实例。
具体可以看Struts2的源码,在父类SpringObjectFactory.java的buildBean()方法里做了如下判断。

1
2
3
4
5
6
if (appContext.containsBean(beanName)) {
o = appContext.getBean(beanName);
} else {
Class beanClazz = getClassInstance(beanName);
o = buildBean(beanClazz, extraContext);
}

新建一个web项目spring-06。导入spring4-required jar包
新建包com.leezp.spring.struts2.beans。在该包下新建Person.java。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.leezp.spring.struts2.beans;
public class Person {
private String username;
public void setUsername(String username) {
this.username = username;
}
public void hello() {
System.out.println("My name is " + username);
}
}

新建包com.leezp.spring.struts2.services。在该包下新建PersonService.java。

1
2
3
4
5
6
7
8
package com.leezp.spring.struts2.services;
public class PersonService {
public void save() {
System.out.println("PersonService's save...");
}
}

新建包com.leezp.spring.struts2.actions。在该包下新建PersonAction.java。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.leezp.spring.struts2.actions;
import com.leezp.spring.struts2.services.PersonService;
public class PersonAction {
private PersonService personService;
public void setPersonService(PersonService personService) {
this.personService = personService;
}
public String execute() {
System.out.println("execute...");
personService.save();
return "success";
}
}

复制struts2官方示例web.xml里的内容到web.xml并修改web.xml。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
<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_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- 配置Spring配置文件的名称和位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 启动IOC容器的 ServletContextListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置Struts2的Filter -->
<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>

新建Spring配置文件applicationContext.xml。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.leezp.spring.struts2.beans.Person">
<property name="username" value="spring"></property>
</bean>
<bean id="personService" class="com.leezp.spring.struts2.services.PersonService"></bean>
<!-- 注意:在IOC容器中配置Struts2的Action时,需要配置scope属性,其值必须为prototype,即struts2的action是非单例的 -->
<bean id="personAction" class="com.leezp.spring.struts2.actions.PersonAction"
scope="prototype">
<property name="personService" ref="personService"></property>
</bean>
</beans>

新建struts.xml。复制struts2官方配置文件struts.xml内容到struts.xml并修改这个文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<!-- Spring整合Struts2时,在Struts2中配置的Spring的Action的class需要指向IOC容器中该bean的id,而不再使用全类名(单独配置Struts2时需要使用全类名) -->
<action name="person-save" class="personAction">
<result>/success.jsp</result>
</action>
</package>
</struts>

新建web页面success.jsp。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ 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>
<h4>Success Page</h4>
</body>
</html>

新建web页面index.jsp。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>Insert title here</title>
</head>
<body>
<a href="person-save">Person Save</a>
</body>
</html>

在该页面右击,Run As-> Run on Server启动Apache服务器进行测试。点击页面的”Person Save”链接。

在控制台观察运行结果。

1
2
execute...
PersonService's save...

新建web页面test.jsp。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<%@page import="com.leezp.spring.struts2.beans.Person"%>
<%@page
import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@page import="org.springframework.context.ApplicationContext"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
<%
//1.从application域对象中得到IOC容器的实例
//利用Spring提供的工具 WebApplicationContextUtils获取
ApplicationContext ctx = WebApplicationContextUtils
.getWebApplicationContext(application);
//2.从IOC容器中得到bean
Person person = ctx.getBean(Person.class);
//3.使用bean
person.hello();
%>
</body>
</html>

在该页面右击,Run As-> Run on Server启动Apache服务器进行测试。

在控制台观察运行结果。

1
My name is spring

获取源代码

参考文献
struts2.3.15.3-blank
struts2官方示例web.xml
struts2官方配置文件struts.xml

版权声明:本文为博主原创文章,转载请注明出处 Leezp’s Blog

点击按钮打赏作者!