Struts2系列笔记之架构,Action,Result.

Struts2

1.MVC模式

MVC即模型(Model),视图(View),控制器(Control)的简写,是一个分工明确的架构模式;

Model:模型,负责封装应用的状态,并实现应用的功能,用分为数据模型和业务逻辑模型,数据模型用来存放业务数据,业务逻辑模型包含应用的业务操作。

View:视图,用来将模型的内容呈现给用户,用户可以通过视图来请求模型进行更新,视图从模型中获取要展示的数据,然后用特定的方式呈现给用户,同时,用户可以通过在视图上的操作,来向控制器发出请求。

Control:控制器,用来进行请求的转发以及控制应用程序的流程。当控制器接受到用户的请求后,调用模型来实现用户请求的功能,然后控制器会选择用于响应的视图,把模型更新后的数据展示为用户。

2.Struts2的系统架构

架构模块解释:

FilterDispacther:是Struts的调度中心,根据ActionMapper的结果来决定是否处理请求,如果请求URL应该被处理,则将会执行Action处理,并停止过链上还没有执行的过滤器。

ActionMapper:提供Http请求与Action执行之间的映射,即进行判断该请求是否被Struts2进行处理。

ActionProxy:位于Action和xwork之间,使得后期引入更多的实现方式。

ConfigurationManager:是xwork配置的管理中心,可以看做struts.xml配置文件在内存中的对应。

ActionInvocation:调用并执行Action,拥有一个Action实例,和这个Action所依赖的拦截器实例,ActionInvocation会执行这个拦截器,Action,以及对应的Result。

Interceptor:自动拦截Action,给开发者提供了在Action运行之前或Result运行之后来执行一些功能代码的机会。

Action:执行单元,用来封装业务所需要的数据。

Result:不同视图类型的抽象封装模型,不同的视图类型会对应不同的Result实现,Struts2支持多种视图类型。

Templates:各种视图类型的页面模板。

Tag Subsystem:Struts2的标签库。

3.Action

是用户操作的执行单元,在View视图中,一个action请求就对应着后台的一个Action类,即一个Action类对应着一个Action请求。Action在MVC中扮演的角色,一般认为Action作为MVC中的模型角色来看,虽然Action中也涉及控制器功能的部分,但是Struts在运行的时候,Struts的前端控制器FilterDispatcher分发并调度相应的Action,此时这个Action仅仅相当于一次请求的命令处理,

⑴Action的配置

在Struts.xml文件中通过在action标签中的class属性中,将其对应的Action类的全类名赋值该class值即可。

①<package>配置

package元素可以把逻辑上相关的一组Action,Result,Intercepter等元素封装起来,形成一个独立的模块,package也可以继承其他的package,package元素的属性有:

name - > 包名

extend ->需要继承的包

namespce -> 包的命名空间

abstract ->定义包为抽象的。

namespace:是包的命名空间,同一个命名空间中不能有相同的名字的action,但在不同的namespace中可以有,如果不配置namespce,则表示默认的enamespce,则在进行访问的时候不需要添加namespace前缀。如果使用了namespce,则在访问的时候需要添加namespace前缀的。

<action>配置:

是package的子元素,需要配置name属性和class属性,method属性,name为必须的,其他子元素有param,result,interceptor-ref.<action>元素的配置也支持使用通配符进行配置,例如:

<action name="*_*" class="com.dong.action.{1}Action" method="[2]">

name属性的*代表任意字符,因此想要和这个action匹配,只要中间带有_即可,例如:Action的名为hellword_query.action,这样class属性使用第一个通配符,(使用{1}作为占位),method属性使用第二个通配符。

默认的配置方式:

在配置struts.xml的时候,对于action来说,name属性时必须的,class可省略,class属性的默认值为com.opensymphony.xwork2.ActionSupport.如果没有class属性,则由于package元素的extends属性配置的是struts-default,即继承了一个叫struts-default的包,包下有一个struts-default.xml文件,这是struts2默认配置好的各个<package>元素的公用配置。在这个文件中,有一个配置<default-class-ref class = "com.opensymphony.xwork2.ActionSupport"/>,说明<action>元素不写class属性的时候,默认配置就是使用ActionSupport类。 

⑵Action的实现

①POJO的实现

即不需要实现任何的接口或者继承特殊的类,仅仅是POJO(Plain Old Java Object,简单的Java对象)就可以,但需要有一个公共的空参的构造方法,还要有一个execute方法。execute方法需要是公共的,无参的,返回一个字符串。

②继承ActionSupport类

ActionSupport类本身实现了Action接口,ActionSupport还实现了其他几个接口,提供更多的功能。例如:validate()方法,用来为Action增加验证的功能;getLocale()方法来获取本地消息。

⑶Action中的数据

Action中的数据就是用户在登录界面填写的数据,即这些数据来源于用户请求对象,就是Request对象。页面的值如何和Action的属性进行对应。

①属性驱动

分两种:1.基本数据类型的属性对应为属性驱动、2.JavaBean风格的属性对应为直接使用域对象。

1.基本类型的属性驱动:

Web页面上提交的HTML控件的name属性和Action的属性或者与属性相对应的getter/setter相对应。即当页面提交时,Struts2会自动从request对象里面吧数据提取出来,然后按照名称进行对应,自动设置到Action的属性里面去。action类的属性都是私有的,通过get/set方法访问,如果不想使用get/set方法,则可以将属性设置为public即可,但是建议设置为private。

2.直接使用域对象的属性驱动

把属性和对应的get/set方法从Action类中移除出去,单独做成一个域对象,然后再域对象中直接使用这个对象可以。

Action发生变化,在相应的HTML页面也需要改动,负责数据无法进行对应,即在相应的属性前面加上一个域对象的前缀,指明这个值到底对应到哪一个域对象里面去。

②模型驱动

Action类实现一个ModelDriven的接口,这个接口我们需要实现一个getModel的方法,这个方法返回的就是Action所使用的数据模型对象。当然在登录界面也需要调整,即直接使用name属性即可,不需要添加域对象的前缀。

⑷非String类型的传入

对于从页面传入的非String类型的值,Struts2会进行自动转换类型为Action类的类型,例如将页面接受到的数字字符转为Action类的int类型,但是当传入的是一个Null值,则会报错,因为Null不能转化为别的类型。

当我们使用包装类型时,如果页面的数据没有填入,则会默认传入的值为Null,

⑸传入多个值

在Action类中,我们有两种方法解决方法:

1.定义一个私有的String数组类型的属性,提供相应的get/set方法,当然直接定义一个public的String数组类型的属性也可以。

2.定义一个私有的集合类型的属性,例如List类型,提供相应的get/set方法。

⑹调用非execute方法

当需要调用非execute方法的时候,需要进行如下配置,首先在Action中实现被调用的方法,这个方法除了名字和execute不一样,其他的均一样,可见性为public, 无参。

4.Result

Result返回一个字符串,这个字符串指示了Action执行完成后,下一个页面在哪里。

ResultType类型指的是具体执行Result的类,有它来决定采用哪一种视图技术,将执行结果展现用户。

⑴预定义的Result的字符常量

SUCCESS:表示Action执行成功,显示结果视图给用户,值为字符串‘success';

NONE:表示执行成功,不需要显示视图给用户;

ERROR:表示Action执行失败,显示错误页面给用户

INPUT:表示执行Action需要更多的输入信息,回到input对应的页面

LOGIN:表示因为用户没有登录而没有正确的执行,将返回该登录视图。

⑵ResultType

Struts2中预定了很多ResultType,通过在struts-default包下的strut2-default.xml中,可以找到关于<result-type>的定义,显示了每一个<result-type>元素以及相应的实现方式。

⑶配置Result

配置name属性,name属性时用来跟Action的execute方法返回的字符串相对应的,用来标识Action运行后跳转到下一个页面,name可以是任意字符。如果不进行设置,默认为“success",正好与Action中的”SUCCESS"这个常量对应,这样的话,execute方法就应该返回SUCCESS。

配置type属性,在没有自定义的情况下,type属性值是在strut2-default.xml中定义的<result-type>的name属性值,默认的type为dispatcher,默认的可以不用配置,

result type的类型:

dispatcher:对应的实现类是ServletDispatcherResult,通过RequestDispatcher来进行页面的跳转,将会保持是同一个请求,即意味着是同一个请求对象,有着同样的数据。

redirect:可在struts2-default.xml文件中查看它所对应的类,它是一个全新的请求,即本次请求和跳转到下一个页面的请求是不同的对象。

chain:将Action执行完后链接到另一个action中继续执行,新的Action使用上一个Action,数据也会进行传递。一般是在一个请求被一个Action处理过后,不是立即产生响应,而是传递到下一个Action中继续处理的时候,这个时候可以使用类型为chain的result来满足需求。使用的时候需要在result标签的type属性设置为chain,同时再其下添加一个子标签,名为<param> 然后指定想要跳转的下一个Action。注意chain不能再result配置的时候传递参数。

...等等等。

⑷全局和局部Result

前面介绍的Result都是局部的,只对其包含的Action有用,如果想对所有的action建立一个公有的Result,则可以使用全局的Result。

配置方式为:

在package元素下使用<global-results></global-results>,剩下的配置和局部的Result没有区别。

Action运行后,根据execute方法返回值寻找Result顺序是:在自己的action元素内的result进行匹配,如果有,则执行这个result,无,则进行下一步 ---》然后再自己的action所在的package的全局Result进行匹配, 如果有,则执行这个result,无,则进行下一步,---》然后递归的寻找自己的包的父包,祖父包的全局Result,有,执行Result  无 则抛出异常。

5.Struts2的异常映射

局部异常映射

在Action元素中设置<exception-mapping>元素,可以指定在execute方法抛出指定错误的时候,跳转到哪个指定的页面。exception属性用来指定Exception的全类名。如果抛出的方法是这个Exception类的实例或其派生类的实例,则会跳转到对应的result属性所指定的结果。eg:

<action name="xxxAction" class="com.dong.xxxx" >
    <exception-mapping result="math-exception" exception="java.lang.AritheticException"/>
    <result name="math-exception"> /xxx.jsp</result>
    <result name="success"> /xxx.jsp</result>
</action>

全局异常映射

和局部Result与全局Result是一样的,全局局部映射仍然是<exception-mapping>元素,只不过不在是<action>元素的子元素,而是<global-exception-mappings>元素的子元素,而<global-exception-mappings>元素是<package>元素的子元素,同时它的子元素也改为相应的<global-results> </globale-results>。

当发生异常的时候,对于其搜索结果和全局Result的搜索结果是一致的,从小范围到大范围慢慢扩张。

想在页面输出异常信息:可以使用Struts2提供的标签:<s:property value="exception"/>仅仅简单的打印exception对象的信息,<s:property value="exceptionstack"/> 可以打印出exception的堆栈信息,注意使用Struts2提供的标签需要进行标签的导入。

6.PreResultListener

在实际开发中,当执行完action后,而result还没有开始时,如果需要进行一些处理,可以使用preResultListener。

实现方式:

创建一个实现PreResultListener接口的类,然后再Action的execute方法里面,注册这个监听器对象

public class MypreResult implements PreResultListener{
    '''
}
public string exectue() throws Exception{
    PreResultListener pr = new MypreResult();
    ActionContext.getContext().getActionInvocation().addPreResultListener(pr);
    return this.SUCCESS;
}

 

 

参考《研磨Struts2》,建议亲自阅读此书,加深理解。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值