框架学习(一)Struts2框架总结


对于web开发初学者而言,三大框架是比较重要的部分。因此,作为学习的总结,我打算对于WEB层的Struts2框架进行一个小总结,如有不对的地方也希望大家指出讨论,本次总结主要基于传智播客的Struts框架学习视频。话不多说,我们进入正题。

1. Struts2的简介:

首先,我们需要明确,Struts2框架是一个MVC框架,所以在web开发中,Struts2是web层进行开发的框架。而MVC是指 Model模型、View视图、Controller控制器。这里不打算展开说这些东西,不知道可以百度下web层以及mvc等词汇。Struts2可以简化web开发,并且降低程序的耦合程度。
在学习框架中,导包第一步,那么对于初学者而言,我们只需要导入 apps/struts2-blank.war 中所有jar包即可满足Struts2的开发。这里需要说明下,当我们需要查看源码时,需要查看两个包,一个是xwork-core包,另一个是core包,那么到底查看那个包呢?这里有个小技巧,如果类全路径是 com. opensymphony .xxx ,则导入xwork-core包;如果是org.apache.struts2 则导入core包。在导包结束后,需要开始开发了,那么开发少不了的就是配置了,下面我们来谈谈基础的Struts2的配置吧。

2. Struts2的配置:

配置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>

这里可以看到,这个过滤器特殊的地方在于我们类的标签后面导入的是一个固定的类:org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
也就是说,在jsp请求后,过滤器进行了拦截,并且从过滤器名字可以看出,它进行了“准备”和“执行”Struts2的操作。它可以找到ActionProxy类,用来执行action请求的。大家简单理解下就是该过滤器进行Struts2的初始化操作以及通过ActionProxy来执行action操作。这里的action就是来替代web层中servlet的,先简单理解为web层的servlet。提到了action,那么自然,我们需要对Struts.xml中的action进行配置。这里引用传智播客中的例子进行讲解

<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
	

<package name="default" namespace="/" extends="struts-default">
	<action name="hello" class="cn.itcast.action.HelloAction"
		method="say">
		<result name="good">/hello.jsp</result>
	</action>
</package>

可以看到,这里需要主要配置三个标签,分别是 < package > < action >和< result >,它们是干什么用的? 属性都是什么意思呢?下面我们来看下:

1.< package > 用于声明一个包。用于管理action
name:它用于声明一个包名,包名不能重复,也就是它是唯一的。
namespace: 它与action标签的name属性合并确定了一个唯一访问action的路径,默认值为""。
extends : 它代表继承的包名。
abstrace: 它可以取值为true/false,如果为true,代表这个包是用于被继承的。

2< action > 用于声明 一个action
name: 就是action的一个名称,它是唯一的(在同包内) ,与package中的namespace确定了访问action的路径。
class :action类的全名,默认值为com.opensymphony.xwork2.ActionSupport
method :要访问的Action类中的方法的名称,方法无参数 ,返回值为String.

3.< result > 用于确定返回结果类型
name: 它与action中的方法返回值做对比,确定跳转路径,默认值为"success"。
type: 用于定义跳转方式,常用参数如下:

ispatcher:它代表的是请求转发,也是默认值。它一般用于从action跳转到页面。

chain:它也相当于请求转发。它一般情况下用于从一个action跳转到另一个action。

redirect:它代表的是重定向 它一般用于从action跳转到页面

redirectAction: 它代表的是重定向 它一般用于从action跳转另一个action。

stream:代表的是服务器端返回的是一个流,一般用于下载。

对于上面进行总结,当某个访问路径被filter拦截后,依据其访问路径,可以找到对应的action进行执行,执行结束之后,返回值为字符串类型,那么依据action的返回值和result标签中的name进行对比,符合则进行对应的操作,比如跳转到某一个jsp,或者某个action等。依据这种方式则可以完成整个web层的操作。而我们编写的action类建议继承ActionSupport类.虽然这样耦合度可能相对于实现接口或者一个简单类要高,但是该类完成了表单校验、错误信息设置、读取国际化信息等功能。在大致了解了使用struts2的过程之后,我们来理解下Struts2的模型,体验下这个框架的魅力。

3. Struts2的模型解析:

这里我们看下Struts2的运行流程,下面这张图学习Struts2框架的大家可能都不陌生。橙色部分就是filter完成的部分,在此部分中,通过filter可以得到ActionProxy来进行action的代理操作,实际上struts2框架的底层就是动态代理。我们可以看到黄色部分为action,即在运行action之前还会执行若干了拦截器,实际上前面说的表单校验等功能就是拦截器完成的。通过对于Struts2的源码进行分析,实际上在DefaultActionInvocation中,其通过动态代理以及递归的方式来完成拦截器的操作,每个拦截器都是独立的。在Dispatcher中通过获取Action的代理对象 ActionProxy,在其执行操作时,会调用它的invoke方法,在invoke方法中将所有的拦截器调用 。因此,对于Struts2框架而言,编写的action只需要注重业务上的编程就可以了,其它的一些通用性等功能,我们都可以通过加入拦截器的方式进行完成。这也符合了Struts2面向切面的编程思想,极大对web层进行了解耦合操作。那么,到底怎么使用拦截器以及自定义拦截器呢,我们在下节中将进行讨论。

在这里插入图片描述

4. Struts2的拦截器:

如第三节的图所示,拦截器采用责任链模式,即:

  • 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
  • 责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行
    Struts默认使用了18个拦截器,如果感兴趣,可以自行查看下。当我们需要自己定义拦截器时,我们需要自定义一个类,并且该类需要实现com.opensymphony.xwork2.interceptor.Interceptor接口。并且该接口中有3个方法:init,destory 和 intercept方法,其中第三个方法是真正的拦截方法。但是我们建议创建一个继承MethodFilterInterceptor的类,并且重写doIntercept方法。在写完了该方法后,需要在Struts.xml中进行声明,声明格式为
<interceptors>
	<interceptor name="" class=""/>
</interceptors>

并且需要在action中指定使用哪些拦截器:

<interceptor-ref name=""/>

在使用了自定义拦截器后,默认拦截器不再使用,因此我们需要对于拦截器栈进行声明
<interceptors> <interceptor-stack name="myStack"> <interceptor-ref name="" /> <interceptor-ref name="defaultStack" /> </interceptor-stack> </interceptors>
并在action中进行指定

<interceptor-ref name="myStack" />

最后我们对比下拦截器和滤波器之间的区别:
1、拦截器是基于java反射机制的,而过滤器是基于函数回调的。
2、过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。
3、拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。
4、拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。
5、在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。

5.OGNL 和 ValueStack:

OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言。我们可以把他类比于jsp中的el表达式,但是其功能又比el表达式强很多。其提供了5大类功能:
1、支持对象方法调用,如xxx.doSomeSpecial();

<s:property value="'abc'.length()"/>

2、支持类静态的方法调用和值访问

<s:property value="@java.lang.Math@max(10,20)"/>

3、访问OGNL上下文(OGNL context)和ActionContext; 这部分为本节的重点
4、支持赋值操作和表达式串联
5、操作集合对象。

那么什么是ValueStack呢?
它是一个com.opensymphony.xwork2.util.ValueStack接口,我们使用它是将其作为一个容器,用于携带action数据到页面,这样我们就可以通过OGNL获取数据了。在ValueStack中存在root属性以及context属性,其中root本质就是ArrayList,而context本质为Map。root存储了action相关信息,而map则存储的是相关映射信息。
在Struts2中,ActionContext中持有了ValueStack的引用,ValueStack有一个实现类叫做OgnlValueStack。OGNL中有一个OgnlContext,它可以设置root与非root .root中数据获取时,不需要加#,而非root中数据在获取时,需要加上#。而下面这张图表明了它们之间的关系
在这里插入图片描述
我们可以看出OgnlContext实际上是ValueStack的Map部分,但是map中包含了root。

6.小结:

由于Struts2的内容还是比较多的,我这里没有一一列举出来,因为我觉得了解框架的原理以及理解思想是最重要的。比如校验,上传下载等功能的本质实际上是拦截器,那么我们需要使用时去找些案例配置一下就可以简单使用,再比如具体OGNL怎么写,其本质是#,%,$号的使用,这些东西在真正接触这些框架之后很快就能上手。本篇博客更多算是我对于自己学习内容的一个小结吧,谢谢观看,本人也是萌新,如果错误,请指出,多多包含。

猜你喜欢

转载自blog.csdn.net/weixin_44183252/article/details/85694910