1.1 Struts2框架的概述
1.1.1 什么是Struts2
Struts2是基于MVC模式的轻量级Web框架,代替Servlet技术来处理服务器的请求。是一个WEB层的框架。
1.1.2 Struts2的优势
- 自动封装参数
- 参数校验
- 结果的处理(转发|重定向)
- 国际化
- 显示等待页面
- 表单的防止重复提交
- Struts2具有更加先进的架构以及思想
1.1.3 Struts2的历史
- Struts2与Struts1的区别就是技术上没有什么关系。
- Struts2解决了线程安全的问题
- Struts2的前身就是Webwork框架
1.2 搭建Struts2框架
1.2.1 导包
1.2.1.1 下载Struts2
Struts2的官网:https://struts.apache.org/
1.2.1.2 解压Struts2的开发包
- apps: Struts2的示例程序,各示例均为war文件,可以通过zip方式进行解压。
- docs: 官方提供的Struts2文档
- lib: Struts2的核心类库,以及Struts2的第三方插件类库。
- src: 该文件夹用于存放该Struts2版本对应的源代码。
1.2.1.3 创建一个web工程导入jar包
从apps文件中解压struts2-blank.war,在WEB-INF下的lib中
1.2.2 编写一个Action类
在src下创建一个包,在该包下新建一个HelloAction的类
public class HelloAction {
public String hello() {
System.out.println("hello world");
return "success";
}
}
1.2.3 完成Action的配置
在src下新建一个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="hello" namespace="/hello" extends="struts-default">
<action name="HelloAction" class="com.yyh.struts2.a_hello.HelloAction" method="hello">
<result name="success">/hello.jsp</result>
</action>
</package>
</struts>
1.2.4 配置Struts2核心过滤器
Struts2框架想要执行,所有的请求都要经过前段控制器(核心过滤器),所以需要配置这个核心过滤器。
打开web.xml,在web.xml中进行如下配置
<!-- struts2配置核心过滤器 -->
<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>
1.2.5 测试
访问后发现页面跳转到了hello.jsp,控制台输出了hello world.
1.3 Struts2访问流程
从客户端发送请求过来,先经过前端控制器(核心过滤器StrutsPrepareAndExecuteFilter)过滤器中执行了一组拦截器(一组拦截器 就会完成部分功能代码),到底哪些拦截器执行了呢,在Struts2中定义很多拦截器,在默认栈中的拦截器会得到执行,这个我们可以通过断点调试的方式测试,拦截器执行完成以后,就会执行Action,在Action中返回一个结果视图,根据Result的平体制进行页面的跳转
1.4 Struts2工作原理(了解)
上图来源于Struts2官方站点,是Struts2的整体结构
- 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
- 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
- 接着FilterDispatcher(现已过时)被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
- 如果ActionMapper决定需要某个Action,FilterDispatcher把请求的处理交给ActionProxy
- ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Aciton类
- AcitonProxy创建一个AcitonInvocation的实例
- ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用
- 一旦Action执行完毕,AcitonInvocation负责根据Struts.xml中的配置找到对应的返回结果,返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被执行的JSP或者FreeMarker的模板。在表示的过程中可以使用Struts2框架中继承的标签。在这个过程中需要涉及到ActionMapper
在上述过程中所有的对象(Action、Results、Interceptors等)都是通过ObjectFactory来创建的。
1.5 配置struts.xml中的提示(在不联网的情况下)
- 工具栏 -> window -> Preferences -> 搜索xml -> XML Catalog
2. 在下载Struts2解压包中的lib包中找到其核心包struts2-core-2.3.24.jar,使用解压工具解压成文件夹形式,有个struts-2.3.dtd.
3. 将struts-2.3.dtd打开找到http地址复制
4. 点击Add按钮,点击File System,找到刚解压的struts-2.3.dtd,然后将界面的Key trpe改为URL,并将刚才复制的地址黏贴到Key中
1.6 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: 将Action配置封装,就是可以在Package中配置很对action
name: 给包起个名字,起到标识作用,随便取.不能与其他包名重复.
namespace: 给Action的访问路径中定义一个命名空间
extends: 继承一个指定包 struts-default默认指定包
abstract: 包是否为抽象的;标示性属性. 标识该包不能独立运行,专门被继承
-->
<package name="hello" namespace="/hello" extends="struts-default">
<!--
action: 配置Action类
name: 决定类Aciton访问资源名
class: Action类的完整类名
method: 指定调用Action中的哪个方法来处理请求
-->
<action name="HelloAction" class="com.yyh.struts2.a_hello.HelloAction" method="hello">
<!--
result: 结果配置
name: 标识结果处理的名称,与Action方法的返回值对应。
type: 指定调用哪一个Result类来处理结果,默认使用转发
标签体: 填写跳转页面的相对路径
-->
<result name="success" type="dispatcher">/hello.jsp</result>
</action>
</package>
<!-- 引入其他struts配置文件 -->
<include file="com/yyh/struts2/b_dynamic/struts.xml"></include>
</struts>
1.7 Struts2常量配置
1.7.1 Struts2默认常量配置位置
1.7.2 修改Struts2常量配置
一共有三种改法:方式先后也是加载顺序,后加载会覆盖先加载的
1. struts.xml
2. struts.properties
3. web.xml
在实际开发中一般采用方式二struts.xml
1.7.3 Struts2常量
<!-- il18n:国际化. 解决post提交乱码 -->
<constant name="struts.i18n.encoding" value="utf-8"></constant>
<!-- 指定访问action时的后缀名 action和空 -->
<constant name="struts.action.extension" value="action,,"></constant>
<!--
Struts2是否以开发模式运行
1. 热加载主配置(不需要重启即可生效)
2. 提供更多错误信息输出,方便开发时的调试
-->
<constant name="struts.devMode" value="true"></constant>
1.8 Struts2配置的进阶
1.8.1 动态方法调用
1. 修改动态方法调用常量(了解)
<!--
配置动态方法调用是否开启常量
默认是关闭的,需要开启
-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<package name="dynamic" namespace="/dynamic" extends="struts-default">
<action name="Demo1Action" class="com.yyh.struts2.b_dynamic.Demo1Action">
<result name="success">/hello.jsp</result>
</action>
</package>
在Action后!加方法来动态调用方法
2. 在action的name属性action类名后加上_* (_不是必须的)
<package name="dynamic" namespace="/dynamic" extends="struts-default">
<action name="Demo1Action_*" class="com.yyh.struts2.b_dynamic.Demo1Action" method="{1}">
<result name="success">/hello.jsp</result>
</action>
</package>
使用{1}取出第一个*匹配的内容
1.8.2 Struts2中的默认配置(了解)
<?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="default" namespace="/default" extends="struts-default">
<!-- method属性: 默认值execute -->
<!-- result的name属性: 默认值success -->
<!-- result的type属性: 默认值dispatcher 转发 -->
<!-- class属性: 默认值com.opensymphony.xwork2.ActionSupport -->
<!-- 如果找不到包下的action,会使用Demo2Action -->
<default-action-ref name="Demo2Action"></default-action-ref>
<action name="Demo2Action">
<result>/hello.jsp</result>
</action>
</package>
</struts>
1.9 Action的详解
1.9.1 Action类的书写方式
方式1: 创建一个类,可以是POJO.
不用继承任何父类.也不需要实现任何接口
使struts2框架的代码侵入性更低
public class Demo3Action {
}
方式2: 实现一个Action接口
里面有execute方法,提供action方法的规范
Action接口配置了一些字符串,可以在返回结果时使用
public class Demo4Action implements Action {
@Override
public String execute() throws Exception {
return null;
}
}
方式3: 继承ActionSupport类 (一般采用此方法)
帮我们实现了Validateable, ValidationAware, TextProvider, LocaleProvider接口
如果我们需要用到这些接口的实现,不需要自己来实现
public class Demo5Action extends ActionSupport {
}