Action是什么?
在Struts2中,一个Action类代表一次请求或调用,每个请求的动作都对应一个相应的Action类,一个Action类是一个独立的工作单元。也就是说,用户的每次请求,都会转到一个相应的Action类里面,由这个Action类来进行处理,因此说,一个Action类代表了用户的一次请求或调用。换句简单的话来说,Action就是用来处理一次用户请求的对象。
到底Struts的Action相当于MVC中的控制器部分还是模型部分?
虽然两种说法都过得去,但是目前大家的共识是把Struts2的Action作为MVC中的模型角色来看待。原因在于,在Struts运行的时候,是由Struts2中的前端控制器FilterDispatcher分发并调用相应的Action的,此时这个Action仅仅相当于一次请求的命令处理,层面比较小,再加上已经有FilterDispatcher来做控制器进行分发调度了,因此,一般不把Struts2的Action当作MVC的控制器来看,而是当作MVC的模型部分来看。
基本数据对应的方式:
在Struts2中,页面的数据和Action有两种基本对应方式,分别是:属性驱动(FieldDriven)和模型驱动(ModelDriven)。其中属性驱动两种情况:一种是基本数据类型的属性对应;一种是JavaBean风格的属性对应。
1.属性驱动FieldDriven(基本数据类型的属性对应)
基本数据类型的属性对应,就是Web页面上要提交的HTML控件的name属性,和Action的属性或者与属性相对应的getter/setter相对应,这种做法就是基本数据类型的属性对应的属性驱动。
2.属性驱动FieldDriven(直接使用域对象)
用对象来封装数据,然后在Action里面直接使用这个对象。
3.模型驱动ModelDriven
实现的方式是让Action实现一个ModelDriven的接口,这个接口需要我们实现一个getModel的方法,这个方法返回的就是Action所使用的数据模型对象。
为什么模型驱动不需要前缀了呢?
因为使用ModelDriven的方式,一个Action只能对应一个Model,因此不需要添加前缀,Struts2就能够知道,页面上的属性的值就对应到这个Model的属性。如果用户加上前缀,反而对应不上了。
属性驱动(基本数据类型的属性驱动)。优点:简单,页面name和属性直接对应。缺点:导致Action类看上去比较零乱。
属性驱动(直接使用域对象)。优点:把模型数据从Action中分离出来,让Action专注于请求处理,使得程序结构更清晰;缺点:页面上在对应的时候,必须添加正确的前缀,稍嫌麻烦。
模型驱动。优点:把模型数据从Action中分离出去了,使得程序结构更清晰。缺点:Action实现特殊的接口,而且把模型数据和Action做了一个绑定,这极大的限制了一个Action对应多个数据模型的能力,当然也可做到,就是在这个模型里面包含其他的数据模型。并且当模型驱动与属性驱动同时存在时,会优先模型驱动的对应方式
拦截器的优点:
1、简化Action的实现。拦截器能把很多功能从Action中独立出来,大量减少Action的代码。
2、功能更单一。把功能从Action中分离出来,分散到不同的拦截器中,这样每个拦截器的功能,以及Action本身的功能都更单一了。
3、通过代码模块化。从Action中把功能分离出来,放到拦截器去实现,这样能把一些在多个Action中通用的代码进行模块化,封装在一个或几个拦截其中。
4、提高重用性。当通用的功能代码被封装在拦截器中,实现了代码模块化过后,这就可以对不同的Action,根据功能需要,来配置相同的拦截器了。
5、实现AOP。Struts2通过拦截器实现了AOP(面向切面编程),AOP是一种编程范式,它是一种分散实现关注功能的编程方法。