1.struts2执行过程图
整个执行过程分两部分:
- 1.服务器启动->初始化过滤器->加载struts.xml
- 2.浏览器发送请求->过滤器->struts.xml中查找动作类名称->实例化动作类
每次发送请求都会实例化动作类,因此发现struts的动作类是多例的
。(所以spring整合Struts2后,也要将动作类配置为多例)
1.1 实现一个简单的Struts2案例
1.在web.xml中配置过滤器,过滤所有路径
<!-- 配置sturts前端控制器 -->
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.编写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>
<package name="22p1" extends="struts-default">
<action name="hello" class="cn.itcast.action.HelloAction" method="hello">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
</package>
</struts>
3.编写HelloAction
public class HelloAction {
/**
* 一个被请求到类后就会执行的方法:动作方法
* @return
*/
public String hello(){
System.out.println("hello方法执行了......");
return "success";
}
}
4.index.jsp
<html>
<head>
<title>$Title$</title>
</head>
<body>
<!-- struts2的核心过滤器默认会拦截以*.action为后缀名或者没有后缀名的url请求 -->
<a href="${pageContext.request.contextPath }/hello.action">访问hello.action</a><br>
<a href="${pageContext.request.contextPath }/hello">访问hello</a>
</body>
</html>
5.success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>执行成功!</h1>
</body>
</html>
1.2 Struts获取request,response,session,servletContext的方式
package cn.itcast.action;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.util.ServletContextAware;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Map;
public class HelloAction implements ServletRequestAware, ServletResponseAware, SessionAware, ServletContextAware {
private HttpServletRequest httpServletRequest;
private HttpServletResponse httpServletResponse;
private Map<String, Object> session;
private ServletContext servletContext;
public String hello(){
System.out.println("hello方法执行了......");
return "success";
}
@Override
public void setServletRequest(HttpServletRequest httpServletRequest) {
this.httpServletRequest = httpServletRequest;
}
@Override
public void setServletResponse(HttpServletResponse httpServletResponse) {
this.httpServletResponse = httpServletResponse;
}
@Override
public void setSession(Map<String, Object> map) {
this.session = map;
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
}
2.struts2配置文件详解
2.1 struts2的6大配置文件
Struts2的核心配置文件有两大类共6种
配置文件,按照加载顺序分别说明如下:
第一类:内置的配置文件,不能修改。
- 1.default.properties
位置:struts2-core-2.3.24.jar\org.apache.struts2目录下
作用:定义了一些常量(键值对)。一些功能开关。 - 2.struts-default.xml
位置:struts2-core-2.3.24.jar目录下的末尾处
作用:定义了Bean元素、结果集类型、拦截器等。 - 3.struts-plugin.xml
位置:位于插件包的根目录
作用:用于扩展插件的一些配置。
第二大类:用户自定义的配置文件,可以修改
- 1.struts.xml
位置:位于用户工程的src下。
作用:用于用户开发的相关配置,如配action、result等。 - 2.struts.properties
位置:一般位于用户工程的src下。
作用:只能用于配置一些常量(覆盖内置的default.properties中的常量配置)
一般也不太用,可以在struts.xml中直接配置常量 - 3.web.xml
位置:WEB-INF目录下
作用:可以配置struts2的核心过滤器以及struts2的一些常量(一般不会用来配置常量)
注意:此处的加载顺序指的是struts2配置的常量的加载顺序,并不是指整个web.xml文件,web.xml是tomcat启动时就会加载的。
全部配置文件的读取顺序为:1、default.properties—2、 struts-default.xml—3、 struts-plugin.xml—4、struts.xml—5、struts.properties—6、web.xml中的常量配置
当然,常量的配置一般不在struts.properties和web.xml中来配置,在struts.xml中配置即可。
这些加载顺序,都是在Struts2的核心控制器中体现的,源码如下:
在init方法中,调用了init的initDispatcher的方法来加载配置文件,进入到该代码中:
我们会发现这个方法又调用了dispatcher的init方法。进入init方法内部:
这一系列的代码就是用来加载Struts2的配置文件的。
2.2 配置文件的注意事项
1、Struts2提供了三种配置常量的方式。
一种是key=value的方式,即使用.properties文件。
一种是在struts.xml中配置。
一种是在web.xml中配置。
我们推荐使用struts.xml文件
2、当多个配置文件中,有相同的常量的配置,后加载配置文件的会把前面配置文件中的常量配置给覆盖。
2.3 struts2中的常用常量
常量定义在了default.properties配置文件中,体现形式都是key=value。所有的struts2应用都会用到这些常量。
因为struts.action.extension默认值为action,,
,所以hello.action和hello才能进入Struts2框架中
测试:改为do
此时hello.action和hello都无法访问
改为,do
就可以hello和hello.do
3.struts.xml中的标签详解
constant标签
作用:
用于修改struts2中的常量
属性:
name:指定常量的key
value:指定常量的值
用法:
<!-- 开启开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
package标签
作用:
在struts2的配置文件中引入了面向对象的思想,使用了分包管理。可以用来管理不同功能的动作类。便于模块化开发动作类。
属性:
name:
包的名称。必须写。且必须唯一。
extends:
一般情况下需要继承struts-default包。不过如果不继承的话,将无法使用struts2提供的核心功能。struts-default.xml中定义着struts-default这个包。而struts-default.xml是在我们的struts.xml加载之前加载。
namespace:
名称空间。它的作用是把访问的URL按照模块化来管理。
名称空间的写法:
必须以/开头
后面可以是字母和数字的组合,也可只有字母。
当我们指定了名称空间之后,访问的URL就变成了:
名称空间+action标签的name属性取值
例如:
/n1/hello.action
/user/addUser.action
/user/updateUser.action
/product/findProductList.action
/product/addProduct.action
名称空间的默认值是:""(struts2官方文档中提供的index.html-Guides)
用法:
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="p1" extends="struts-default" namespace="/user">
<action name="hello" class="cn.itcast.struts.HelloAction" method="hello">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
</package>
</struts>