浅析 struts2

Posted Zempty笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析 struts2相关的知识,希望对你有一定的参考价值。

导语

查阅了很多资料去了解和学习 struts2 ,本文是对自己学习 struts2 的一个总结,以便淡忘的时候拿来回味一番。

 

struts2 的初印象


struts2 是一个用来同 web 端页面和后端数据进行交互的一个框架,在 MVC 中更多的是担任 C 的角色。相较于 servlet  ,struts2 框架的优势就是写很少的代码,做到想做的事(框架的底层代码可能帮我们实现了部分需求)。


在 Java 的编程中 ,struts2 有着很重要的地位。找工作可能明确要求要会 struts2,因此在接触她之前,我对她有着很多的期待,可以说是迫不及待,想早点拥有她,当我细细品味之后发现她其实跟 servlet 长的很像。长的比 servlet 好看,有点难追!


开追 struts2


工欲善其事,必先利其器。学习 struts2 的最好方法我认为是去 strut2 的官网,了解一下应该怎么开始 struts2 。首先第一步是准备 struts2 的工具( struts2 需要的一些jar 包 ),官方网站的介绍是通过 Maven 来构建 struts2 的 jar 包的,这样做方便快捷,但是如果你对 Maven 不是很了解,我建议下载 struts2 的文件,然后根据文件提供的例子,拷贝所需要的 jar 包即可。如图所示:


 这是官方下载下来的文件   :         


 打开文件找到apps 点击打开  :  


浅析 struts2



解压缩其中的一个例子 :                浅析 struts2


我是通过修改例子的后缀名为.zip ,然后拷贝需要的 jar 包 浅析 struts2       浅析 struts2      浅析 struts2       浅析 struts2


如上图所示:在解压缩的 WEN-INF 文件夹里面找到 lib 文件夹 ,在 lib 文件夹里面拷贝所需要的 jar 包到新建的 web 工程中。这里需要特别强调一下:切记不要拷贝所有的 jar 包,这样容易导致你的工程执行 action 时出现 404 错误。下面是工程需要的 jar 包 :如图所示:


           浅析 struts2

        

第二步编写一个 Java 类 ,其中包含方法名为 execute 和返回值为 String 的方法,编写完成后,在 classpath 路径下面配置一个名称为 struts.xml 文件(其实就是在 src 下面配置 struts.xml ,如果要是使用 Maven 的话,就在 src/main/resources 下面配置 struts.xml 文件)。


浅析 struts2

浅析 struts2


关于这两张图片做一下稍微的解析:strut2 会默认执行类中的 execute 方法 ,而且会根据方法的返回值做出相应的处理,比如说 :转发、跳转等。在 struts.xml 文件中首行定义了 XML 文件的版本和编码方式,下面一行则是引入 struts2 的 .dtd 文件,它定义了 struts2 的 XML 文件特有的格式,节点构成。所有的节点都在根节点<struts></struts>标签中,<package>标签是一个包,里面装着不同的 action ,它有常用的三个属性 name 用来表示这个包的名称,namespace 是一个路径,在浏览器中用来定位 action ,extends 表示该包继承的父包名称,一般都是继承 struts-default 。包中的 action 用来表示定位你写的哪一个类,要做什么处理,action 中的 name 属性用来给你所定义的类起个名字,用来在浏览器中定位资源,class 则是只能指名你所要操作的是哪个类。result 标签中 name 表示方法的返回值,同 execute 方法的返回值一致。result 标签中的文本标签 /index.jsp 表示执行完这个 action 要转发到的页面是 index.jsp 。


第三步配置 web.xml ,如图所示:


浅析 struts2


新建一个 index.jsp 用来测试 action 的效果


浅析 struts2


前面所述都是在你建立的 web 项目中操作的。下面把我的工程截图如下:


            浅析 struts2


下面启动服务器运行第一个 action 。


浅析 struts2


浏览器路径中输入你要操作的 action 名称 ,最好加上 .action 后缀,如上图所示。

如果你经过操作看到了上面的页面,那么恭喜你!你的 struts2 的征程正式开启了 !

struts2 编写 action 类 

上文提到的一个类 HelloStruts2 就是一个 action 类,上文强调方法中需要有 execute 方法 ,因为 struts2 框架中默认执行 action 中的 execute 方法。


下面就来分析如何编写 action 类:


第一种方法:编写一个 Java 常规类,类中的方法返回值为 String 类型,这样方便根据返回值 ,进行页面的转发、跳转等。然后在 struts2 .xml 文件中进行 action 的配置。具体配置上文有提到,可参考。

第二种方法:编写一个 Java 常规类继承框架中的 Action 接口,并实现 Action 中的execute 方法,然后配置 struts2.xml 文件。如图所示:


浅析 struts2


浅析 struts2


第三种方法:编写一个 Java 常规类,让该类继承 struts2 中的 ActionSupport 。 分析ActionSupport 类就可以知道它也是实现了 Action 接口,继承类的好处是不需要去重写跟需求无关的的方法,既可以拓展父类父类中的方法,又可以把父类中的东西直接拿来用。我认为最大的一个好处是让人一目了然,一看就知道这是一个 action 类,所以建议使用第三种方法创建 action 类。如图所示:


浅析 struts2


浅析 struts2


解析 struts.xml


分析上面的情况:有这样一种情景:有一个工程,有多个人去负责开发,A 开发的时候去配置一个 struts.xml ,B 也去配置一个 struts.xml ,C 也如此,。。。,那么请问应该用谁的 xml 呢?可以汇总,整合,这样可以实现但是太麻烦,针对这种情景,有一个普遍的做法就是 A 去定义一个自己的 .xml 文件,同上文提到的 struts2 配置相同,最好是类名.xml ,B 呢也去自己定义一个,依次类推。然后在定义一个 struts.xml 文件,把所有人定义的 .xml 文件都引入进来就可以了,如图所示:图中的 struts-one.xml 就是我自己定义的一个,引入 struts.xml 就可以使用了。


浅析 struts2


下面在分析一个情景,上文提到了 action 创建的时候默认执行 execute 方法,如果我的action 类中有多个方法呢?我想要执行我需要的方法总么办呢?下面给出两种解决的办法,都是配置文件来解决的:


浅析 struts2


如上图 ,我想执行图中的 testMethod1 方法或者 testMethod2 方法,需要在配置文件中做如图所示的配置:


浅析 struts2


打开服务器,浏览器中输入相应的 action 就会执行对应的方法:

浅析 struts2

将会执行 testMethod1 方法。


浅析 struts2

将会执行 testMethod2 方法。


上面的问题解决了,但是如果一个 action 类中的方法很多,配置文件就会配置很多的action。于是可以通过通配符去解决这个问题。如图所示:


浅析 struts2


在浏览器中输入如下路径就会访问 test_Method1 方法 :

浅析 struts2


但是上面的配置方式在 struts 2.5 的版本中是行不通的,输入相应的路径会报 404 的错误 ,应该采用如下的方法配置,在配置文件中列出允许执行的方法:


浅析 struts2


下面在说明一个场景,如果多个方法返回同一个值,转发到同一个页面,配置文件的 result 标签就会大量的重复,如何解决呢?配置全局变量。如图所示:


浅析 struts2


struts2 获取表单数据


一、普通方式获取表单数据


在 servlet 中获取表单的数据主要是通过 HttpServletRequest 获取。同样在 action 类中可以通过类似的方法获取:下面介绍如下:


(1)通过 ActionContext 获表单请求数据:

ActionContext context = ActionContext.getContext();

Map<String, Parameter> map = context.getParameters();

介绍一下 map 中的 key 是表单中的 name 值 ,value 是表单中的 value 值


(2)通过 ServletActionContext 获取 HttpServletRequest ,然后获取表单中的数据

HttpServletRequest request=ServletActionContext.getRequest();

ServletActionContext 可以得到 servlet 中的三个域对象。

二、通过属性封装
(1)、在 action 类中封装同表单名称一样的属性。

(2)、生成属性的 setter和getter方法。

如图所示:


浅析 struts2


浅析 struts2


三、表达式封装

(1)、在 action 中声明一个实体类。
(2)、创建实体类的 set 、get 方法。

(3)、在请求表单中使用 实体类 . 属性 的方式。


浅析 struts2


浅析 struts2


当使用表达式封装的时候,一定要注意表达属性的命名,要使用 action 中定义的实体类引用.实体类的属性名。

四、模型封装

(1)、定义的 action 要实现 ModelDriven 接口。
(2)、实现 getModel 方法。


浅析 struts2


浅析 struts2


模型驱动封装需要注意一定要把定义的实体类实例化。这样数据才能封装进去。


上述的五种方式,模型驱动经常用到,有时候可能需要用到其他几种进行对数据的封装,可以根据自己的需求进行合理的应用。


struts2 的值栈


struts2 值栈主要分为两部分 一部分叫 root 是个 list 集合,一部分是context 是个 map 集合 。通过 struts2 的 debug 标签可以很清晰的看到值栈中的内存结构(<s:debug />)。


一、向值栈中放入数据通常有三种方法:

(1)、调用值栈中的 set 方法。

(2)、调用值栈中的 push 方法。
(3)、在 action 中定义变量 ,生成 get 方法。

(4)、通过上述的模型封装,数据也会进入值栈。


浅析 struts2


二、从值栈中取出数据

通过 struts2 标签和 ognl 表达式一起使用来获取值栈的数据。


(1)、取出通过 set 方法放进值栈的数据。

浅析 struts2


浅析 struts2


(2)、取出通过 push 方法放进值栈的数据。

浅析 struts2


浅析 struts2


通过标签 <s:property value="[0].top" 获取的是值栈栈顶的数据,一般 push 都把数据推到栈顶。


(3)、取出通过 action 放进值栈的数据。下面在 action 中定义一个 List 属性,然后通过 struts 标签遍历 List 集合取出数据。

浅析 struts2


浅析 struts2


关于上图遍历 list 的集合的时候一定要注意有两种遍历方法,需要注意自己采取哪种方法进行遍历,下面是通过第二种方法获取遍历的 list 集合,一定要注意下图标识的 # 标识符必须使用:

浅析 struts2


(4)、通过模型封装的方法获取值栈。

浅析 struts2


浅析 struts2


通过模型驱动不单单可以从表单获取数据封装到实体类中,还可以把实体类的数据输出到页面当中。


struts2 的拦截器


拦截器是在 action 对象创建之后,action 的方法执行之前执行的。

拦截器实现原理:

(1)、AOP :就是面向切面编程。用我的理解就是:不改变原来方法的代码,就可以拓展其功用。

(2)、责任链模式:就像 servlet 中的过滤器,多个过滤器按顺序执行,然后执行目标代码,然后在依次经过过滤器一一返回。责任链模式跟过滤器的过滤链模式功用相同。


如何去定义一个过滤器呢?

查看 struts2 的源代码你会发现有这样一个抽象类叫 AbstractInterceptor ,它是实现的是 Interceptor 的接口。因此我们可以有两种方式定义一个拦截器,继承 AbstractInterceptor 或者实现

Interceptor 接口。


通常的做法是继承接口,这样我们不用去复写不必要的方法,只关心主要的功能即可。下图是继承 AbstractInterceptor 的一个自定义拦截器。


浅析 struts2



定义完一个拦截器,应该如何使用呢?去配置文件配置拦截器。如图所示:


浅析 struts2


如上图红线框标注的是配置一个拦截器,在配置拦截器的过程中最好把默认的拦截器给引用进来,否则,struts2 默认的拦截器将不会执行,如上图红线标注是引用的默认拦截器。


有可能你的某些方法并不需要执行拦截器,那么应该怎么去做处理呢?
有这样一个类叫 MethodFilterInterceptor 它是继承了 AbstractInterceptor 。我们定义一个类去继承它就可以去解决上述问题。如下图所示:


重要的是我们自定义拦截器的时候通常都是继承  MethodFilterInterceptor 这个类,因为它用起来更方便,更实用。


浅析 struts2



如上图所示配置,就可以不让 action 类中的 test 方法执行拦截器。


总结:


本文浅析了什么是struts2、struts2 中 action 的定义和使用、struts.xml 文件的解析、struts2 的数据封装,、struts2 的值栈、struts2 的拦截器。


记忆力很差,有时候用到相关知识点的时候总是不那么流畅,因此总结记录一下,以便随时阅读回味。


推荐阅读

 




Zempty 笔记

生活|写作|程序员代码

以上是关于浅析 struts2的主要内容,如果未能解决你的问题,请参考以下文章

Struts2struts2处理请求参数及其校验

struts2struts2中的流接收与流发送

Struts2Struts2与Spring整合后,如何指定Action为多例模式

ssh整合

JAVA中框架总结

flinkFlink 1.12.2 源码浅析 : StreamTask 浅析