您的位置:首页 > 编程语言 > Java开发

Struts2权威指南总结4:深入struts2

2013-11-20 08:10 471 查看
1,深入struts2的配置文件:
(1)Bean配置:
Struts2框架的大部分核心组件,struts2不是一硬编码的方式写在代码中的,而是以自己的IoC容器来管理框架的核心组件。
如果用户想在Struts2中部署自己定义的组件,只需要提供自己的组件实现类,并将组件部署在Struts2的IoC容器中即可。
在struts2-core-2.0.6.jar中有struts-default.xml文件,这个文件中定义了大量的Bean。
通常情况下,我们无需重新定义struts2框架的核心组件,也就无需再struts.xml中配置<Bean>。

(2)常量配置
建议使用struts.xml配置常量,但是struts2也可以使用struts.properties配置,是因为保持对webwork的向后兼容性。(也可以在web.xml中配置struts2的常量)



如果在多个配置文件中配置了同一个struts2常量,则后一个会覆盖前一个。
在web.xml中配置常量,可以通过<filter>元素的<init-param>子元素指定,<param-name>指定名字,<param-value>指定值。不建议使用这种配置方式。
推荐使用struts.xml配置常量。

(3)包配置
Struts2使用包来管理Action和拦截器等,每个包就是多个Action、多个拦截器、多个拦截器引用的集合。配置包时,必须指定name属性,该属性就是引用该包的key。Extends属性用于继承另一个包。
Struts2还提供了一种抽象包,抽象包的概念是不能包含Action定义,指定为抽象包,只需在定义包时加上sbstract=”true”属性即可。

(4)命名空间配置(namespace)
在同一个web应用下可能有同名的action,struts2以命名空间的形式管理action,同一个命名空间里不能有同名的action,不同的命名空间中可以有同名的action。通过<package namespace=”...”>指定包的命名空间。默认命名空间是namespace=””。
如果指定namespace=”/user”,如果访问login.action,则url为/user/login.action,struts2会首先查找user下的login.action,如果找到则使用这个action,如果没有找到,则使用默认命名空间,去默认命名空间查找这个action。
注意:命名空间只有一个级别,即:假如访问url为/bookservice/search/get.action,则系统将在/bookservice/search的命名空间中查找get.action,如果有则使用这个action,如果没有找到,则直接进入默认命名空间查找这个action,并不会在/bookservice下查找这个get.action。

(5)包含配置
这体现的是软件工程“分而治之”的原则。
Struts2默认只加载WEB-INF/classes下的struts.xml文件,我们必须通过sturts.xml配置文件包含其他配置文件,使用<include>标签完成。例如:<include file=”struts-user.xml”>
被包含的struts-user.xml同样包含dtd信息以及<struts>根元素。

(6)拦截器配置
拦截器其实就是AOP思想。拦截器允许在Action处理之前和处理之后执行用户自定义的代码。
将多个拦截器组合在一起,就形成了拦截器栈。其实一个拦截器栈也可以看作一个拦截器。
拦截器和拦截器栈都放在<interceptors />标签中。通过定义<interceptors />的子元素<interceptor>和<interceptor-stack>,可以定义拦截器和拦截器栈。在<interceptor-stack>中通过<interceptor-ref>来定义拦截器或拦截器栈的引用。
在<action >标签中也可以定义<interceptor-ref>拦截器引用,则这个拦截器只拦截访问这个action的请求。

2,struts2的Action
Struts2的Action不需要继承任何基类或者实现任何struts2接口,可以看作是一个POJO。
在Action中,通过定义请求参数的setter和getter方法,可以获取浏览器发过来的请求参数。
如果Action中给属性添加了getter和setter方法,则可以在页面中通过struts2标签来输出这个属性的值,例如给private String tip;设置了getter和setter,那么在jsp页面中,可以通过<s:property value=”tip” />来输出这个tip的值。
为了让用户书写的Action更规范,struts2提供了一个Action接口,接口中定义了5个常量和一个execute方法。
还提供了一个ActionSupport类,这个类中提供了很多方法,可以使用户很方便的实现很多的功能。例如实现校验、国际化等等。
一般我们的Action会继承这个类,可以大大的简化开发。

(1)Action访问Servlet API
Struts2的API没有与任何ServletAPI耦合。
通过struts2提供的ActionContext类,可以访问Servlet API。



通过ActionContext ac =ActionContext.getContext();方式获取实例对象。

(2)Action直接访问Servlet API
Action通过实现如下接口可以直接获取servlet API实例。



例如:获取HttpServletResponse对象的实例,可以通过如下方式:
首先在Action中定义一个私有的HttpServletResponse对象。
Private HttpServletResponseresponse;
再实现ServletResponseAware接口中获取response对象必须实现的方法:
public void setServletResponse(HttpServletResponseresponse){
this.resposne = response;
}
也可以通过struts2提供的ServletActionContext类的方法直接访问Servlet API。这个类中包含如下方法:



(3)配置Action
在struts.xml中配置Action。
<action>中的class属性不是必须的,如果不指定,默认使用ActionSupport类。
配置<action>的name属性时,如果需要在name中使用/,则需要指定struts2框架允许Action name中出现斜线,通过设置struts.enable.SlashesInActionNames常量指定,设置为true,则允许出现斜线。不推荐在name属性中使用“.”或“-”,这有可能会引发异常。

(4)动态方法调用
DMI(Dynamic Method Invocation)动态方法,表单的action属性的访问格式如下:
Action=”ActionName!methodName.action”,
例如:<form action=”login!regist.action”>是访问login Action的regist方法。
要在struts2中使用动态方法调用,必须要设置struts.enable.DynamicMethodInvocation常量,设置该常量的值为true。

(5)使用通配符
Name,method,class都支持通配符。通配符通过*指定。
表达式也可以出现在action的class属性中,例如:
<action name=”*Action_*” class=”{1}Action”method=”{2}”>
则,如果访问loginAction_login,则是访问loginAction类的login方法。
对于模式*_*,如何定义校验文件呢?校验文件的文件名符合一定的格式,ActionName-validation.xml,如果是<actionname=”*_*”>如何定义校验文件呢?通常,前面的*是Action,后面的是mehtod,也就是说,如果访问路径是User_login.action,则处理类是Action,处理方法是这个Action中的login,Action的名字就是User,所以校验文件名因该是User-validation.xml。
Struts2在action的name,class,method和result中支持表达式。
<!—定义一个通用的action,匹配任何jsp页面 -->
<action name=”*”>
<result>/{1}.jsp</result>
</action>
通配符匹配规律:



(6)配置默认Action
当用户的请求找不到对应的Action时,系统将使用默认Action来处理用户请求。通过<default-action-ref .../>标签实现。每个标签配置一个默认的Action。



配置默认的Action只需要指定一个name属性,这个name属性指向一个有效的Action。该Action将成为默认容器。

3,处理结果
Action不应该直接生成对浏览者的相应,应该通过视图技术生成。
(1)配置结果
两种方式,
<action name=”” class=”” method=””>
<result name=”” type=”dispatcher”> </result>
</action>

<package name=”” extends=”” namespace=”” >
<global-results>
<result name=””></result>
</global-results>
</package>


在<result>中,通过<param name=”location”>(视图资源路径)</param>可以指定访问的视图资源。
对于上述第一种方式,name属性可以指定两种:
Location:指定该逻辑视图对应的实际视图的资源。
Parse:指定是否可以在实际视图名字中使用OGNL表达式。默认值为true。通常无需指定。
Struts2的默认结果类型是:dispatcher,可以通过修改配置文件来改变默认结果类型。
Name属性也是可以省略的,默认是success。

(2)struts2支持的结果类型
JSP、Velocity、FreeMarker等。
Action处理后返回一个字符串作为逻辑视图名,该逻辑视图没有与任何实际视图相关联,必须在struts.xml中配置之后才能关联上。
Struts2的结果类型要求实现com.opensymphony.xwork.Result,这个结果是所有Action的通用接口。如果我们需要自己实现结果类型,需要实现这个接口,再在struts.xml中配置即可。
在struts-default.xml中可以查看struts2定义的所有结果类型。如:



此外,在struts2-jasperreports-plugin-2.0.6.jar的struts-plugin.xml、struts2-jfreechart-plugin-2.0.6.jar的struts-plugin.xml、struts2-jsf-plugin-2.0.6.jar的struts-plugin.xml中也配置了struts2支持的结果类型。
Struts2使用dispatcher作为默认结果类型的原因:



在配置dispatcher结果类型时,指定default=”true”。
Struts2支持的14中内建结果类型:



(3)plaintext结果类型
不常用,用于显示视图资源的源代码。即:在用户浏览器中显示的是指定视图资源的源代码。
这种结果类型中,返回页面中如果存在中文,可能会出现乱码,解决方式就是在指定result时加上<param>参数,如下:
<result type=”plaintext”>
<paramname=”charSet”>GBK</param>
</result>
(4)redirect结果类型
redirect重定向结果类型,dispatcher是转发。重定向会丢失请求数据,也丢失Action的处理结果。
使用redirect相当于使用HttpServletResponse的sendRedirect(String)方法。
(5)redirect-action结果类型
产生一个新的请求。与redirect的区别是:redirect-action使用ActionMapperFactory提供的ActionMapper来重定向请求。需要将结果重定向到另一个action时,使用这种结果类型。
使用的<param>参数有:actionName,namespace。
(6)动态结果
指在指定实际视图资源时使用了表达式语法,例如<result>{1}.jsp</result>
(7)请求参数指定结果
在指定视图资源名称时,通过${属性名}指定视图资源。这个属性名就是Action的属性。也可以使用OGNL表达式:${属性名.属性名.属性名}
(8)全局结果集
在<package>中定义<global-results>
<package name=”” extends=”” namespace=””>
<global-results>
<result name=””> ... .jsp</result>
</global-results>
</package>


4,属性驱动和模型驱动
Struts2的模型驱动不仅封装了请求信息,还封装了结果信息。由于Action既要封装请求参数,又要完成逻辑控制,这样结构不清晰,为了结构清晰,考虑使用单独的Model来封装请求参数和处理结果,这就是所谓的模型驱动。
所谓的模型驱动就是使用单独的JavaBean实例来贯穿整个MVC流程。与之对应的属性驱动模式,则使用属性作为贯穿MVC流程的信息携带者。属性依赖于Action实例对象。
模型驱动的ModelDriven接口。
实现了ModelDriven接口,struts2是如何将请求参数存入JavaBean的呢?
查看strtus-default.xml,里面定义了struts2默认的包<package name=”struts-default”>
在这个包中,定义了struts2的默认拦截器栈:
<default-interceptor-ref name=”defaultStack”/>
这个默认拦截器栈中包含模型驱动和属性驱动的拦截器:model-driven,params。这两个拦截器引用系统的拦截器,其中params负责提取请求参数,如果使用属性驱动模式,还负责将请求参数传递给Action实例的属性;而model-driven拦截器负责将请求参数传递给模型的属性。

如果Action关联的Model是User,User中有username属性,则:在JSP页面中通过
<s:property value=”username” />会直接输出Action关联的Model User的username的属性值。

5,struts2的异常机制
(1)为了使用struts2的异常处理机制,我们必须打开struts2的异常映射功能。开启异常映射功能需要一个拦截器,通过struts-default.xml文件可以知道,在这个配置文件中已经开启了异常映射。
<interceptor name=”exception” class=”...”/>
并在默认拦截器栈中引用了异常拦截器:
<interceptor-stack name=”defaultStack”>
...
<interceptor-refname=”exception” />
</interceptor-stack>

(2)声明式异常捕捉
Struts2的异常处理机制是通过在struts.xml文件中配置<exception-mapping ... />元素完成的。需要指定两个属性:
Exception:指定该异常的异常类型。
Result:指定Action出现这个异常时,系统转入result属性所指向的结果。
局部异常:将<exception-mapping ... />作为<action>的子元素配置。
全局异常:将<exception-mapping ... />作为<global-exception-mapping>的子元素配置。
如果局部异常和全局异常配置了同一个异常类型,则局部的覆盖全局的,即执行局部的result,而不执行全局的result。

(3)输出异常信息
在JSP页面中,可以通过以下标签输出异常信息。
<s:property value=”exception” />输出异常对象本身
<s:property value=”exceptionStack”/>输出异常堆栈信息

第一种方式也可以通过<s:property value=”exception.message”/>输出信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: