Struts2介绍
Struts2是一种基于MVC模式的轻量级Web框架。本质上相当于一个Servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。
Struts2优势
- 自动封装参数
- 参数校验
- 结果的处理 转发 重定向
- 国际化
- 显示等待页面
-
防止重复提交
Struts2优势
WEB层框架基于的前端控制器模式
在传统的开发中,有一次请求就会对应一个Servlet。这样会导致出现很多的Servlet。而Struts2将所有请求都先经过一个前端控制器,在前端控制器中实现框架的部分功能。具体的操作交到具体的Action中。
传统开发方式 前端控制器模型
快速入门
下载Struts2开发包
- Struts2的官网 https://struts.apache.org/
官网
解压开发包
-
解压后的目录结构如下:
解压后的目录 - apps:该文件夹用于存放官方提供的Struts2示例程序。
- docs:该文件夹用于存放官方提供的Struts2文档
- lib:该文件夹用于存放Struts2的核心类库。以及Struts2的第三方插件类库
创建一个web工程引入相应jar包
可以参考apps下的一些示例代码,其中struts2-blank.war是struts2的空工程,我们可以查看它的lib目录
基本开发包
这些就是基本的开发包了,具体含义如下:
基本开发包解释
创建一个页面:放置一个链接
首先需要在WebContent下创建一个目录demo1,在demo1下创建一个新的jsp 在jsp中编写
创建Action
/**
* @Auther: wxblack-mac
* @Date: 2018/5/23 16:49
* @Description: Struts2 Action类
*/
public class HelloAction {
public String hello() {
System.out.println("hello world");
return "success";
}
}
编写配置文件 struts.xml
引入dtd约束文件
<?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>
</struts>
将struts2配置到web.xml中
由于Struts2是基于filter,所以需要配置Struts2的核心过滤器
<!--配置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>
Struts2框架架构演示
访问过程架构图.png
AOP思想
核心配置详解
Struts2 核心配置 Struts.xml
<struts>
<!--
package:将Action配置封装,可以在Package中配置很多action
name属性:给包起个名字,起到标识作用,不能与其他包名重复
namespace属性:给action定义一个访问前缀,指定一个命名空间
extends属性:继承一个指定包,struts2默认提供一个struts-default用于继承,必须继承
由于struts2的配置文件是从上到下处理的,所以父包应该在子包前面定义
abstrac属性:包是否为抽象的;标识性属性。抽象包意味着该包不能包含Action定义
-->
<package name="hello" namespace="/hello" extends="struts-default">
<!--
action:配置Action类
name属性:决定了action访问的资源名 指定该Action所处理的请求的URL
class属性:指定action资源完整类名
method:指定具体调用action的哪个方法
-->
<action name="HelloAction" class="cn.probuing.struts2lesson.action.HelloAction"
method="hello">
<!--
result:结果配置
name属性:标识结果处理的名称与action方法的返回值对应
type属性:指定调用哪一个Result类来处理结果 默认使用转发处理结果
标签体:填写处理页面的相对路径
-->
<result name="success">/hello.jsp</result>
</action>
</package>
</struts>
Struts2常量配置
Struts默认常量配置位置
默认常量配置修改Struts2常量配置
第一种 在struts.xml文件中使用<constant> 标签 开发中常用
struts.xml第二种 在src下创建strtus.properties文件
struts.propertiesstruts.properties
第三种 在项目的web.xml中
web.xml以上的顺序 也是配置文件的加载顺序 后加载的会覆盖先加载的
常量配置
基本常量配置
<!--常量配置-->
<!--
国际化常量配置 可以解决POST提交乱码
-->
<constant name="struts.i18n.encoding" value="utf-8"/>
<!--
指定访问action时的后缀名,两个逗号表示分割后缀名 两个逗号间为空 表示可以不加后缀
-->
<constant name="struts.action.extension" value=",,"/>
<!--
开发模式
提供热加载主配置
提供更多的错误信息输出,方便开发的时候调试
-->
<constant name="struts.devMode" value="true"/>
- 通常 Struts2框架按如下搜索顺序加载Struts2常量:
- struts-default.xml 该文件保存在struts2-core-2.5.14.jar文件中
- struts-plugin.xml Struts2等插件中
- struts.xml web应用默认的Struts2配置文件
- struts.properties Struts2默认的配置文件
- web.xml 该文件是Web应用的配置文件
如果在多个文件中配置了同一个Struts2常量,则后一个文件中配置的常量会覆盖前面文件中配置的常量值
配置进阶
Struts2动态方法调用
动态方法调用指的是:
我们在配置struts.xml需要配置method属性 代表调用的方法,如果调用的方法过多则会出现复杂且冗余的method配置,这样显然是不合理的。Struts2提供了动态的方法调用,可以让我们在调用方法时 指定方法的名称 调用对应的方法。这样可以大大简化我们的配置
方式一:
- 需要开启动态方法调用
<!--配置动态方法调用常量 false: 关闭 true 开启 默认关闭-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
- 不需要配置method属性
<package name="dynamic" namespace="/dynamic" extends="struts-default">
<action name="Demo1Action" class="cn.probuing.strutsLesson.dynamic.Demo1Action">
<result name="success">/hello.jsp</result>
</action>
</package>
- 在调用时 通过 !方法名 来指定方法的调用
http://localhost:8080/ss/dynamic/Demo1Action!add
> 表示调用Demo1Action中的add方法
这种方式有一个弊端:由于地址路径的特殊,对SEO优化不友好
方式二:
- 通配符方式 动态方法调用
<package name="dynamic" namespace="/dynamic" extends="struts-default">
<!--
指定name 为 xxx_*时 在前缀匹配到的时候 *代表任何字符
Struts2会将*号的值记录下来 填充到{1}中
-->
<action name="Demo1Action_*" class="cn.probuing.strutsLesson.dynamic.Demo1Action" method="{1}">
<result name="success">/hello.jsp</result>
</action>
</package>
http://localhost:8080/ss/dynamic/Demo1Action_find 这个地址中 *代表"find" 相当于配置了 method="find"
使用PreResultListener
PreResultListener是一个监听器接口,可以在Action完成控制处理之后,系统转入实际的物理视图之间被回调
Struts2应用可由Action、拦截器添加PreResultListener监听器,添加PreResultListener监听器通过ActionInvocation的addPreResultListener()方法完成。一旦为Action添加了PreResultListener监听器,该监听器就可以在应用转入实际物理视图之前回调该监听器的beforeResult()方法
- 一旦为拦截器添加了PreResultListener监听器,该监听器会对该拦截器所拦截的所有Action都起作用
ActionInvocation invocation = ActionContext.getContext().getActionInvocation();
invocation.addPreResult(ActionInvocation invocation,String resultCode)
{
.....处理逻辑
invocation.getInvocationContext().put("extra",new Date());
}
Struts2默认配置
Struts2的很多配置都有默认值,在不配置的时候就以默认值来指定
<!--
默认值:
method属性:默认值 execute 如果配置文件中没有找到method会去对应的类中找execute方法
class属性:com.opensymphony.xwork2.ActionSupport
-->
<!--
如果找不到命名空间下的action会使用默认的action处理 也就是DefaultDemo处理请求
-->
<default-action-ref name="DefaultDemo"></default-action-ref>
<action name="DefaultDemo" class="cn.probuing.strutsLesson.defaultconf.DefaultDemo">
<!--
result的name属性:success
result的Type属性:dispatcher 转发
-->
<result name="success">/hello.jsp
</result>
</action>
配置默认Action
当用户请求找不到对应的Action时,系统默认的Action即将处理用户请求
配置默认Action通过<default-action-ref.../>元素完成
<package name = "lee" extends="struts-default">
<default-action-ref name="simpleViewResultAction"/>
<!--通过action元素配置默认的Action-->
<action name="simpleViewResultAction" class="........">
<result..../>
</action>
配置默认Action使用<default-action-ref.../>元素即可,配置该元素时需要制定一个name属性,该name属性指向容器中另一个有效的Action,该Action将成为容器中默认的Action
配置Action默认处理类
在配置<action.../>元素时可以不指定class属性,如果没有指定class属性则系统默认使用ActionSupport作为Action处理类
自定义Action默认处理类
配置默认Action处理类使用<default-class-ref.../>元素,配置该元素时只需要指定一个class属性,该属性指定的类就是Action的默认处理类
action类的详解
action的创建方式
方式一:直接创建一个类,可以是POJO(不用继承任何父类 也不需要实现任何接口)
这种方式并不好,使得Struts2框架的代码浸入性更低
方式二:实现一个接口Action
/**
* Action的详解
* @author wx-blackmac
* @create 2018-05-23 22:34
* bestwishes for you
* good luck!
* Action接口预置了一些字符串
* SUCCESS
* NONE
*
**/
public class Demo3Action implements Action {
/**
* execute是提示Action方法规范
* @return
* @throws Exception
*/
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
方式三:继承ActionSupport
ActionSupport帮我们实现了 Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable 这些接口 当我们使用这些接口时,不需要自己实现
/**
* Action的详解
* @author wx-blackmac
* @create 2018-05-23 22:34
* bestwishes for you
* good luck!
*
**/
public class Demo3Action extends ActionSupport {
}
因为ActionSupport完全符合一个Action的要求,所以也可直接使用ActionSupport作为业务控制器,如果配置Action没有指定class属性(没有用户提供Action类),系统自动使用ActionSupport类作为Action处理类
配置异常处理
Struts2的异常处理我们一般希望如果出现异常1的时候系统转入视图资源1,如果出现异常2系统转入视图资源2。我们可以采用如下的方式
public class XxxAction
{
public String execute(){
try{
....
}catch(异常1 e){
return 结果1;
}catch(异常2 e){
return 结果2;
}
}
}
但是,这样的方式会出现大量的try-catch块,完全手动处理异常,非常烦琐。
我们可以声明execute()抛出全部异常,将异常直接抛给Struts2框架。Struts2框架接收到Action抛出的异常之后,根据struts.xml配置异常映射。转入指定的视图
<interceptors>
<!--执行异常处理的拦截器-->
<interceptor name="exception" class="自定义异常处理类"/>
<!--struts2默认的拦截器栈-->
<interceptor-stack name="defaultStack">
<!--引用异常映射拦截器-->
<interceptor-ref name="exception"/>
</interceptor-stack>
</interceptors>
声明式异常捕捉
Struts2的异常处理机制是通过在struts.xml文件中配置<exception-mapping.../>元素完成的。
- exception:此属性指定该异常映射所设置的异常类型
- result:指定Action出现该异常时,系统返回Result属性值对应的逻辑视图名
异常映射分类
- 局部异常映射
将<exception-mapping.../>元素作为<action.../>元素的子元素配置
局部异常映射进队该异常映射所在的Action内有效。 - 全局异常映射
将<exception-mapping.../>元素作为<global-exception-mapping>元素的子元素配置
全局异常映射对所有的Action都生效
如果局部异常映射和全局异常映射配置了同一个异常类型,在该Action内部局部异常映射会覆盖全局异常映射
网友评论