Result Types
从action生成结果,并返回组用户不同的结果值,不都需要相同的类型.结果"success"可以渲染为一JSP页面,但结果"error"可能需要发送一个HTTP头返回给浏览器.
结果的类型使用"type"属性在结果节点配置.与"name"属性相似,这个属性也有一个默认值-"dispatcher"-将渲染JSPs.大多数的时间,你将使用所提供的结果类型,但有时也可能提供自定义的实现.
Request and Form Data
为了要做出Action应该如何工作的决定,并且提供数据的数据库持久对象,Action可能需要从请求字符串中访问值,并生成数据.
Struts2沿序JavaBean的方式-如果你想访问数据,你需要为字段提供一个getter和setter方法.访问请求字符串和form里的值是一样的.每个请求字符串或是Form里的值都是一个简单的名值对,所以为一个特定的名称赋值,需在action里创建一个setter方法.例如,如果JSP发起了一个请求,"/home.action?framework=struts&version=2",Action需要提供setter方法"setFramework(String frameworkname)",和setter方法"setVersion(int version)".
注意在这个例子中,setter方法不是一定需要一个String的值.默认的,Struts2将从一个String转换成action所需的类型.可以转换所有的原始类型和基础对象类型,而且可以配置你自己的自定义类.Struts2同样可以操作复杂对象中的值,例如,一个名称在Form元素中称为"person.address.home.postcode",值为"2",Struts2将使用同样的调用方式"getPerson().getAddress().getHome().setPostcode(2)".
Accessing Business Services
到现在为止,我们都在讨论如果配置action,如果控制渲染不同的结果返回给用户.对于action是做什么的,是非常重要的一部分,但是,返回它们的结果之前,一些处理需要执行.对于这个,它们需要访问一些不同类型的对象-商业对象,数据访问对象,或是其他资源.
为了提供一个松耦合的系统,Struts2使用称为依赖注入或是控制反转(IOC)的技术.依赖注入可以通过构造函数注入,接口注入和set方法注入来实现.Struts2使用set方法注入.意思是对于action可用的对象,你仅需要提供一个setter.首选的依赖注入框架是Spring框架,可以通过插件配置进来.另一个选择是Plexus,或都如果你喜欢,你可以替换成你自己的实现.
也有一些对象不能用Spring框架管理,比如像HttpServletRequest.这些对象是组合使用setter注入和接口注入来操作.对于每一个非商业对象,都有个相应的口(大家都知道的"aware"接口),Action必须实现这个接口.
注:
WebWork最初有自己的依赖注入框架.它在2.2版时,删除了这个特征,而改用Spring框架替换.最初的组件框架是基于接口的,所以为每个组件接口和接口的实现类,都需要提供.
另外,每个组件都有一个"Aware"接口,为组件提供一个setter.如果接口是"UserDAO",那么Aware接口则为"UserDAOAware"(约定俗成),并且拥有一个方法-一个setter,"void setUserDAO(UserDAO dao);".
拦截器会为必要的接口和setters注入必要的对象注入.
Accessing Data from the Action
有些时候,需要查看被action修改过的对象.有几种技术可以被使用.
很多WEB程序员熟悉的技术是将需要访问的对象放到HttpServletRequest和HttpSession中.这可以通过实现"aware"接口来完成,然后设置对像,使用特定的名称访问.
如果你想使用内建的标签或是引入JSTL支持,访问数据就非常容易了.他们两个都可以通过值栈直接存取action.唯一的工作就是程序员需要给Action里允许被访问的需要存取的对象提供getter方法.
我们将在后面的部分更详细的讨论值栈.
Interceptors
Struts2框架使用拦截器提供了许多特征;例如包含异常处理,文件上传,生命周期回调和验证.拦截器是同Servlet过滤器或是JDKs的代理类相同的概念.它们提供了Action的前处理和后处理的方法.与Servlet过滤器相似,拦截器也可以分层和排序.They have access to the action being executed, as well as all environmental variables and execution properties.
让我们开始讨论拦截器依赖注入.依赖注入到action当中,与我们之前看到的一样,有两种不同的形式出现.有一些拦截器是我们已经提过的:
Spring框架-ActionAutowiringInterceptor拦截器
请求字符串和Form值-ParametersInterceptor拦截器
Servlet基础对象-ServletConfigInterceptor
前两个拦截器独立工作,不需要Action再做什么,但最后一个却是不同的.它同下面的接口协作工作:
SessionAware-通过一个Map来提供对所有Session属性的访问
ServletRequestAware-提供对HttpServletRequest对象的访问
RequestAware-通过一个Map来提供对所有Request属性的访问
ApplicationAware-通过一个Map来提供对所有Application属性的访问
ServletResponseAware-提供对ServletResponse对象的访问
ParameterAware-通过一个Map来提供对所有请求字符串和Form值的访问
PrincipalAware-提供对PrincipleProxy对象的访问;这个对象实现了HttpServletRequest对象的规则和角色的方法, 但提供个代理,允许独立于Action的实现
ServletContextAware-提供对ServletContext对象的访问
为了将正确的数据注入到Action当中,它需要实现必需的接口.
Configuration
如果我们想要能够注入(或任何其他由拦截器提供的功能)到我们的Action,我们需要提供配置.像其他元素一样,大多数的拦截器已经为你配置好了.只需要你的Actions的包继承自"struts-default"包即可.
要配置一个新的拦截器,我们首先需要定义这个拦截器.将<interceptors … />和<interceptor …/>标签直属<package>标签.对于上面提到的Spring框架拦截器,它的配置如下:
<interceptors>2
…3
<interceptor name="autowiring"4
class="interceptor.ActionAutowiringInterceptor"/>5
</interceptors>
我们同样需要确认将拦截器应用到需要它的Action上.这可以通过两种方法实现.第一种是将拦截器分配给每个Action:
<action name="my" class="com.fdar.infoq.MyAction" >2
<result>view.jsp</result>

