一、 Struts2框架概述
是一种基于MVC模式的轻量级web框架。本质是一个Servlet。作为控制器建立模型与视图的数据交互。Struts2以WebWord为核心,采用拦截器的机制处理客户的请求。使得业务逻辑控制能够与Servlet分隔开,减少耦合度。
二、 Struts2框架优势
- 项目开源,使用及拓展方便
- 提供Exception处理机制
- 自动封装参数
- 参数校验
- 结果的处理(转发|重定向)
- 国际化
- 显示等待页面
- 防止表单重复提交
三、 常见的WEB层的框架
- Struct2
- Struct1
- Webwork
- SpringMVC
WEB层的框架都会基于前端控制器的模式,传统开发中,一个请求就会对应一个Servlet。这样会出现过多的Servlet。Struct2会将所有的请求先经过一个前端控制器,在前端控制器中实现框架的部分功能,剩下具体操作都要提交到具体的Action中。前端控制器使用过滤器实现的,所有的请求都会被过滤器拦截没然后在过滤器实现部分的功能。Struct2的前端控制器也是由过滤器来实现的。
四、 Struts2快速入门
第一步:下载开发包
直接上官网:https://struts.apache.org/下载包
第二步:查看目录
- apps:该文件夹存用于存放官方提供的Struts2示例程序,这些程序可以作为学习者的学习资料,可为学习者提供很好的参照。各示例均为war文件,可以通过zip方式进行解压。
- docs:该文件夹用于存放官方提供的Struts2文档,包括Struts2的快速入门、Struts2的文档,以及API文档等内容。
- lib:该文件夹用于存放Struts2的核心类库,以及Struts2的第三方插件类库。
- src:该文件夹用于存放该版本Struts2框架对应的源代码。
第三步:导包
点开apps下的一个struct2-blank
找到其WEB-INF中的lib包。struct2-blank
需要使用winRAR
进行解压。
将里面所有的jar包全部导入到项目中。
第三步:书写一个Action类
public class HelloAction {
public String hello() {
System.out.println("helloWord");
return "success";
}
}
第四步:引入主配置文件 (src下)
<?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.aiit.a_hello.HelloAction" method=" hello">
<result name="success">/hello.jsp</result>
</action>
</package>
</struts>
第五步:将struts2配置到我们的web.xml过滤器中
<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>
注意此处的filter-class是固定值
第六步:做测试(在浏览器中输入)
http://localhost:8080/struts2_day01/hello/HelloAction
五、 Struts2的访问流程
从客户端发送请求过来,先经过前端控制器(核心过滤器StrutsPrepareAndExecuteFilter)过滤器中执行一组拦截器(会完成部分功能代码),Struts2中有很多拦截器,在其默认栈中的拦截器会得到执行。拦截器执行完毕后,会执行目标Action,在Action中会返回一个结果(success),根据Result的配置进行访问。
如图:
第一步:在url地址中访问路径
第二步:在web.xml中执行StrutsPrepareAndExecuteFilter过滤器
第三步:过滤器加载struts.xml文件
第四步:根据action标签中的name属性。寻找action类,通过method方法去访问jsp文件。
六、 Struts架构
可自行书写拦截器,apo思想,纵向的重复代码,横向的进行抽取
七、 strut2的配置文件详解
strut2框架的核心配置文件是struts.xml文件,该文件主要是来配置Action和请求的对应关系
<struts>
<!-- il8国际化,解决post乱码问题 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!-- http://localhost:8080/struts2_day01/hello/HelloAction.do -->
<!-- 指定访问action时的后缀名 -->
<constant name="struts.action.extension" value="do"></constant>
<!-- 指定strut2是否以开发者模式运行
1.热加载主配置(不需要重启即可生效)
2.提示更多错误信息输出,方便开发时的调试
-->
<constant name="struts.devMode" value="false"></constant>
<!--
package:将Action配置封装,可以在package中配置很多action
name:给包起别名。如包名为user,里面放的即为用户类。但不能与其他报名重复
namespace:给Action的访问路径中,定义一个命名空间
extends:继承一个指定包
abstract:包是否为抽象的;标识性属性,标识该包不能独立运行,专门被继承
-->
<package name="hello" namespace="/hello" extends="struts-default">
<!--
action元素:配置action类
name属性:决定了Action的访问资源名
class属性:action类的完整类名
method属性:指定调用action中的哪个方法来处理请求
-->
<action name="HelloAction" class="com.aiit.a_hello.HelloAction" method=" hello">
<!--
result:结果配置
name属性::标识结果处理的名称,与action方法的返回值对应
type:指定调用哪一个result类来处理结果,默认使用转发
标签体:填写页面的相对路径
-->
<result name="success" type="dispatcher">/hello.jsp</result>
</action>
</package>
</struts>
- package配置
Struts2框架的核心组件是Action和拦截器。使用包来管理Action和拦截器。每个包就是多个Action,多个拦截器,多个拦截器引用的集合。在struts2.xml文件中,package元素用于定义包配置,每个package元素定义了一个包配置。
常见属性如下:
属性 | 说明 |
---|---|
name | 必填属性,它指定该包的名字,此名字是该包被其他包引用的key |
namespace | 可选属性,该属性定义该包的命名空间 |
extends | 可选属性,它指定该包继承自其他包。继承其他包,可以继承其他包中的Action定义,拦截器定义等 |
abstract | 可选属性,它指定该包是否是一个抽象包,抽象包不能包含Action定义 |
- Action配置
Action映射是框架中的基本“工作单元”,Action映射就是将每一个请求的URL映射到一个Action类,当一个请求匹配某个Action名称时,框架就使用这个映射来确定如何处理请求。在struts.xml中拥有四个属性
属性 | 说明 |
---|---|
name | 必填属性,表示Action,制定了Action所处理的请求的URL |
class | 可选属性,指定Action对应Action类 |
method | 可选属性,指定请求Action时调用的方法。默认值:execute |
converter | 可选属性,指定类型转换器的类 |
其中package配置中name属性和namespace属性共同决定了访问路径
class对应的是Action类的全路径。Method制定了执行Action的哪个方法,默认是execute方法。以下是一些属性的默认值。
<!-- method属性值:execute-->
<!-- result的name属性值:success-->
<!-- result的type属性值:dispatcher-->
<!-- action中的class属性:com.opensymphony.xwork2.ActionSupport -->
八、 Struts常量的配置
Struts常用大多在默认的配置文件中已经配置好,但根据用户需求的不同,开发的要求页不同,可能需要修改常量值,修改的方法就是在配置文件对常量进行重新配置。
重新配置有三种方式:
- 在struts.xml文件中使用
<constant>
元素配置常量 - 在struts.properties文件中配置常量
- 在web.xml文件中通过
<init-param>
元素配置常量
这三种方式书写顺序,也是加载的顺序,所以优先考虑struts.xml的书写方式。默认的struts2的配置位置。
方式一:在struts.xml文件中通过<constant>
元素配置常量
该方式为最为常用的方式,在struts.xml文件中配置,必须要使用name和value属性。
<!-- il8国际化,解决post乱码问题 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!-- http://localhost:8080/struts2_day01/hello/HelloAction.do -->
<!-- 指定访问action时的后缀名 -->
<constant name="struts.action.extension" value="do"></constant>
<!-- 指定strut2是否以开发者模式运行
1.热加载主配置(不需要重启即可生效)
2.提示更多错误信息输出,方便开发时的调试
-->
<constant name="struts.devMode" value="false"></constant>
方式二:在struts.properties文件中配置常量
其格式为key-value这样的键值对,并且文件位置在src下
方式三:在web.xml中进行配置
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!-- 通过init-param元素配置struts2常量,配置默认编码集为utf-8 -->
<init-param>
<param-name>struts.i18n.encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
注意,后加载的配置文件的常量值会辅导先加载的文件中的常量值。加载顺序为struts2.xml——>struts.properties——>web.xml
常用配置介绍
<!-- 引入其他的struts配置文件 -->
<include file="com/aiit/dynamic/struts_demo1.xml"></include>
<include file="com/aiit/dynamic/struts_demo2.xml"></include>
我们在项目中尝尝模块化设计,通常在主配置文件中引入其他的struts.xml
的配置文件
九、 struts2配置文件进阶——动态方法调用
我们如果在一个Action类中书写了许多方法如下
public class Demo1Action {
public String add() {
System.out.println("添加用户");
return "success";
}
public String delte() {
System.out.println("删除用户");
return "success";
}
public String update() {
System.out.println("修改用户");
return "success";
}
public String find() {
System.out.println("查找用户");
return "success";
}
}
此时我们想要访问每一个方法
方式一:
进行常量配置 <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<package name="dynamic1" namespace="/dynamic1" extends="struts-default">
<action name="Demo1Action" class="com.aiit.dynamic.Demo1Action" >
<result name="success">/hello.jsp</result>
</action>
</package>
此时我们并没有书写方法题,而是引入了上面一点中的一个常量值。此时我们访问浏览器
方式二:(重点)
<package name="dynamic1" namespace="/dynamic1" extends="struts-default">
<!-- 动态方法调用方式2:通配符方式
使用 {1}取出第一个通配符的内容
-->
<action name="Demo1Action_*" class="com.aiit.dynamic.Demo1Action" method="{1}"><!-- 匹配第一个✳号 -->
<result name="success">/hello.jsp</result>
</action>
</package>
此时我们在浏览器中进行访问
十、 Action类的书写方式
Action作为框架的核心类,实现对用户请求的处理,Action类被称为业务逻辑控制器。一个Action类代表一次请求或调用,每个请求的动作都对应于一个相应的Action类。
一个Action类是一个独立的工作单元。用户每次请求,都会转到一个相应的Action类里面,由这个Action类来进行处理
实现Action类控制类有三种方式
方式一:书写一个POJO类
就是说不继承,不实现接口,仅仅书写一个POJO(POJO:一个简单的java对象)
一般有一个公共的无参构造方法execute
该方法必须是public属性
返回一个字符串。方法没有参数
//方式一:创建一个类可以是Pojo,不用继承任何父类,也不需要实现任何接口
//使struts框架的代码侵入性更低。
public class Demo1Action {
public String execute() {
return "success";
}
}
方式二:实现一个接口
为了使用户书写规范,提供Action接口。
public class Demo2Action implements Action{
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return null;
}
}
方式三:继承一个类
//方式三:继承一个类ActionSupport
//实现了一系列接口Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable
//如果我没呢需要用浙西而接口的实现,不需要自己实现
public class Demo5Action extends ActionSupport{
}
Action接口中提供了五个定义的常用
- SUCCESS :success 代表成功
- NONE :none代表页面不跳转
- ERROR :error代表页面跳转到错误页面
- INPUT :input 数据校验的时候跳转的路径
- LOGIN :login:用来跳转到登陆页面