Action配置
上节大致讲了关于struts.xml的整体结构,下面讲一下它的一些详细的配置。先从action说起吧!
Method属性
在action中有一个method属性,可以指定此action调用哪一个方法。如果没有指定,默认调用execute()方法。
例如:
<actionname="Login"class="com.stuqbx.web.action. HelloWorld" method=”login”>
<resultname="error">/pages/error.jsp</result>
<resultname="success">/pages/HelloWorld.jsp</result>
</action>
上面的配置指定Login.action调用HelloWorld的login方法。但是需注意调用的方法的签名要和execute()签名一样,即login的签名为:public String login() throws Exception。
Action动态方法调用
在Struts 2的核心jar包-struts2-core中,有一个default.properties的默认配置文件。里面配置了一些全局的信息。这里如果把struts.enable.DynamicMethodInvocation= true(default.properties是不能被更改的。如需要更改里面的配置信息,可以在src根目录下建一个 struts.properties的配置文件,然后重写所要更改的配置信息或者可以用constant标签在struts.xml配置),――动态方法调用,为true时,就可以在struts.xml配置“*”的通配符,来调用action里的方法。
通配符有点类似于变量,但这里的变量是用“*”表示。
看一个例子:
<actionname="HelloWorld_*"method="{1}"class="com.stuqbx.web.action.HelloWorld ">
<resultname="success">/pages/success.jsp</result>
<resultname="error">/pages/error.jsp</result>
</action>
这里在action的name中通配了一个HelloWorld_*",它对应映射的是method属性。如果在客户端发生一个这样的请求:HelloWorld_login.action、HelloWorld_show.action等,这时服务器就会自动调用这个action中的login ()方法或show()方法。这里的method="{1}"代表是第一个“*”,如果有多个星号,就要根据顺序来通配{1},{2},{3}....
再如下面多个星号的配置:
<actionname="*/*"method="{2}"class="com.stuqbx.web.action.{1}">
<resultname="succes">/pages/success.jsp</result>
<resultname="error">/pages/error.jsp</result>
</action>
其中第一个“*”映射到具体的某个action类,第二个“*”映射到该类的方法。不过这里要注意的name=”*/*",是相当于客户端要发送如 “HelloWorld/login.action”,在地址栏里就变成了/struts/HelloWorld/login.action,那服务器到底是会认/login.action还是HelloWorld/login.action呢。其实服务器默认还是/login.action,如果要使带"/"的action生 效,需要把default.properties中的struts.enable.SlashesInActionNames= false改为true就可以。
默认的Action
当没有指定Action的class属性的时候,例如:
<action name="HelloWorld"/>
则默认使用com.opensymphony.xwork.ActionSupport。ActionSuppor有两个方法input和execute,每个方法都是简单的返回SUCCESS。
通常情况下,请求的Action不存在的情况下,Struts2框架会返回一个Error画面:“404 - Page not found”,有些时候或许我们不想出现一个控制之外的错误画面,我们可以指定一个默认的Action,在请求的Action不存在的情况下,调用默认的Action,通过如下配置可以实现:
<packagename="com.stuqbx.web.action"extends="action-default">
<default-action-refname="DefaultAction"/>
<actionname="DefaultAction">
<result>/pages/default.jsp</result>
</action>
</package>
Action参数
在struts2中可以为action指定参数。大家还记着struts1是如何设置的action参数不?在struts 1中可以使用<action>标签的parameter属性为其指定一个action参数,如果要指定多个,就只能通过逗号(,)或其他的分隔符将不同的参数隔开。而在struts 2中可以通过<param>标签为action指定任意多个参数。
配置如下:
<action name="ParamAction"class="com.stuqbx.web.action.ParamAction">
<param name="param1">value1</param>
<param name="param2">value2</param>
<result name="save">/pages/save.jsp</result>
</action>
在action中读参数非常简单,只需要像获取请求参数一样在action类中定义相应的setter方法即可(一般不用定义getter方法),这样就可以将参数的值注入相应的参数中。
如下面的代码将读取param1和param2参数的值:
publicclass ParamAction extends ActionSupport
{
private String param1;
private String param2;
publicvoid setParam1(String param1)
{
this.param1 = param1;
}
publicvoid setParam2(String param2)
{
this.param2 = param2;
}
public String execute() throws Exception
{
String str = param1 + param2;
…
}
}
当struts 2在调用execute之前,param1和param2就已经被注入相应的值了,因此,在execute方法中可以直接使用param1和param2。
Result类型
在action的result时,如果没有指定type,那么默认为” dispatche”(实际上就是转发,forward)。我们也可以根据需要指定它的类型。
如下面的配置指定result的类型为redirect:
<actionname="HelloWorld!login"class="com.stuqbx.web.action.HelloWorld">
<resultname="error"type="redirect">/pages/error.jsp</result>
</action>
result-type可以在struts2-core-2.*.jar包或struts 2源代码中的struts-default.xml文件中找到,在这个文件中找到<result-types>标签,所有的result-type都在里面定义了。
代码如下:
<result-types>
<result-typename="chain"class="com.opensymphony.xwork2.ActionChainResult"/>
<result-typename="dispatcher"class="org.apache.struts2.dispatcher.ServletDispatcherResult"default="true"/>
<result-typename="freemarker"class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-typename="httpheader"class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-typename="redirect"class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-typename="redirectAction"class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-typename="stream"class="org.apache.struts2.dispatcher.StreamResult"/>
<result-typename="velocity"class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-typename="xslt"class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-typename="plainText"class="org.apache.struts2.dispatcher.PlainTextResult" />
<!-- Deprecated name form scheduledfor removal in Struts 2.1.0. The camelCase versions are preferred. See ww-1707-->
<result-typename="redirect-action"class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-typename="plaintext"class="org.apache.struts2.dispatcher.PlainTextResult"/>
</result-types>
类型 |
描述 |
chain |
用来处理Action链 |
dispatcher |
用来转向页面,通常处理JSP,这是默认的结果类型 |
freeMarker |
处理FreeMarker模板 |
httpHeader |
用来控制特殊的Http行为 |
redirect |
重定向到一个URL |
redirect-action |
重定向到一个Action |
stream |
向浏览器发送InputSream对象,通常用来处理文件下载 |
velocity |
处理Velocity模板 |
xslt |
处理XML/XLST模板 |
plaintext |
|
tiles |
结合Tile使用 |
另外第三方的Result类型还包括JasperReports Plugin,专门用来处理JasperReport类型的报表输出;JfreechartPlugin;JSF Plugin。
全局的result
很多时候,很多action可能有相同的result(也就是说一个result被多个action使用),可是在每个action里都定义一个result很繁琐,这时我们可以把这个公用的result定义成全局的,这样就可以同时被多个action使用了。
例如:
<packagename="com.stuqbx.web.action"namespace="/action" extends="struts-default">
<global-results>
<resultname="print">/pages/global.jsp</result>
</global-results>
<actionname="PrintHelloWorld"class=" com.stuqbx.web.action. HelloWorld"method="print">
<resultname="error">/pages/error.jsp</result>
<resultname="success">/pages/HelloWorld.jsp</result>
</action>
<actionname="PrintTest"class="com.stuqbx.web.action.Test"method="print"/>
</packgage>
HelloWorld和Teat里都有一个方法print(),返回值都是”print”, PrintTest.action和PrintHelloWorld.action都调用各自的print()方法,但是他们的action里都没有定义name=”print”的result,此时,它们仍然可以访问,其实它们都是用global-results里的name为”print”的result。
以上讲的都是关于action的配置,既然说到action,再补充一点不是关于配置的。
Action访问Servlet
Struts2中的Action并没有和任何Servlet API耦合,这样框架更具灵活性,更易测试。
但是,对于web应用的控制器而言,不访问Servlet几乎是不可能的,例如跟踪HTTPSession状态等。Struts 2框架提供了一种更轻松的方式来访问Servlet。Struts 2中提供了一个ActionContext类(当前Action的上下文对象),通过这个类可以访问Servlet。
下面是该类中提供的几个常用方法:
public static ActionContext getContext() :获得当前Action的ActionContext实例。
public Object get(Object key) :此方法类似于调用HttpServletRequest的getAttribute(String name)方法。
public void put(Object key,Object value) :此方法类似于调用HttpServletRequest的setAttribute(String name,Object o)。
public Map getParameters() :获取所有的请求参数。类似于调用HttpServletRequest对象的getParameterMap() 方法。
public Map getSession() :返回一个Map对象,该Map对象模拟了HttpSession实例。
public void setSession(Map session) :直接传入一个Map实例,将该Map实例里的key-value对转换成session的属性名-属性值对。
public Map getApplication() :返回一个Map对象,该对象模拟了该应用的ServletContext实例。
public void setApplication(Map application) :直接传入一个Map实例,将该Map实例里的key-value对转换成application的属性名-属性值对。
Struts2中通过ActionContext来访问Servlet,让Action彻底从Servlet中分离出来,最大的好处就是可以脱离Web容器测试Action。
另外,Struts2中还提供了一个ServletActionContext类,Action只要继承自该类,就可以直接访问Servlet。具体方法参看struts 2的API文档。