大多数情况下我们的用例可以被分成两个部分。一是我们需要改变和查询应用程序的状态,而是需要呈现和更新应用程序的视图。在Struts2中Action管理应用程序的状态,Result Type管理视图。
Rsult是什么
简单的说Result就是Action方法执行完毕之后返回的一串字符串,他指示出Action执行完之后的下一个页面在哪里,具体页面的位置是我们在struts.xml中配置的,就是<result>子元素,例如我们在前面UserAction中配置的Result:
<actionname="*User"class="action.UserAction"method="{1}">
<resultname="input">/input.jsp</result>
<resultname="success">success.jsp</result>
</action>
Action执行完之后返回的字符串就是雨上面result元素的name属性的值相对应。
Result Type
对于Result,实际上就是一串字符串而已,它并不能完成什么工作,真正完成执行Result功能的就是Result Type所对应的实现类,通常情况下我们并不区分Result和Result Type。在Struts2中内建了许多ResultType,他们都定义在strtus-default包中,我们可以在struts-default.xml中找到这些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"/>
</result-types>
具体的Rsult Type的作用在Stuts2的文档中有描述:
虽然Strtus2内建支持这么多Result Type,但是一般情况下我们都用不到这么多,因此我们挑几个常用的学习一下,其他的可以在需要的时候再去查看文档。
Dispatcher
从是struts2.xml的配置中可以看出对于Dispatcher类型的Result Type被设置为默认使用的结果类型。与Dispatcher类型对应的实现类为org.apache.struts2.dispatcher.ServletDispatcherResult,查看该类的源代码,其中的doExecute方法:
public void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
if (LOG.isDebugEnabled()) {
LOG.debug("Forwarding to location " + finalLocation);
}
PageContext pageContext = ServletActionContext.getPageContext();
if (pageContext != null) {
pageContext.include(finalLocation);
} else {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);
//add parameters passed on the location to #parameters
// see WW-2120
if (invocation != null && finalLocation != null && finalLocation.length() > 0
&& finalLocation.indexOf("?") > 0) {
String queryString = finalLocation.substring(finalLocation.indexOf("?") + 1);
Map parameters = (Map) invocation.getInvocationContext().getContextMap().get("parameters");
Map queryParams = UrlHelper.parseQueryString(queryString, true);
if (queryParams != null && !queryParams.isEmpty())
parameters.putAll(queryParams);
}
// if the view doesn't exist, let's do a 404
if (dispatcher == null) {
response.sendError(404, "result '" + finalLocation + "' not found");
return;
}
//if we are inside an action tag, we always need to do an include
Boolean insideActionTag = (Boolean) ObjectUtils.defaultIfNull(request.getAttribute(StrutsStatics.STRUTS_ACTION_TAG_INVOCATION), Boolean.FALSE);
// If we're included, then include the view
// Otherwise do forward
// This allow the page to, for example, set content type
if (!insideActionTag && !response.isCommitted() && (request.getAttribute("javax.servlet.include.servlet_path") == null)) {
request.setAttribute("struts.view_uri", finalLocation);
request.setAttribute("struts.request_uri", request.getRequestURI());
dispatcher.forward(request, response);
} else {
dispatcher.include(request, response);
}
}
}
可以看出Dispatcher内部使用了Servlet API,主要是使用RequestDispatcher类进行了请求的转交。转发有两种方式,一是使用include方式,一是forward方式,这两种方式有些不同。使用include方式是临时转交,在转发之前前一个Action已经开始写入了响应,include进来的内容只能作为请求的一部分。使用forward方法进行的转交是永久转交,在转交之前前一个Action并没有开始写入响应。但是他们都与重定向的方式有所不同,整个转交过程都属于同一个Request请求。
Redirect
redirect类型的Result Type使用了HttpServletResponse的sendRedirect方法来完成重定向。使用冲定向的方式将不会保留前一个Action的状态,他们不再是同一个Request请求。如果要想在重定向之后能够访问前一个Action的状态,那么我们就需要将需要的信息保存在session中或者在result的url中通过查询参数的方式进行传递。
<resultname="toWelcome"type="redirect">/${folder}/welcome.jsp?account=${account}</result>
在strtus.xml中配置result的时候如果要动态的访问Action中的属性值,那么动态值需要放在“${}”内才能被正确解析,另外就是一些特殊字符如”&”和”+”都需要使用相应的转义序列来表示。
对于dispacher类型和redirect类型的result的配置,我们都是用了简便的方式,实际上他们有两个共同的参数:
location:用来指出结果视图的地址
parse:用来表明是否要把location参数的值当作OGNL表达式来解析。默认值是true。
1. <resultname="toWelcome"type="dispatcher">
2.
<paramname="location">/s2impl/welcome.jsp</param>
3. <paramname="parse">true</param>
4.
</result>
Redirect Action
这种结果类型与Redirect结果类型的行为有几分相似,但是Redirect Action不是重定向到另一个资源,而是重定向到另一个动作。它可以有一下几个参数:
actionName:用来指定目标Action的名字,是默认属性,可以不用显示指出。
namespace:用于指定目标Action的命名空间,如果没有指定值,那么Struts2会认为目标Action与起始Action的命名空间相同。
<actionname="userAction"class="action.UserAction">
<resultname="next"type="redirect-action">
<paramname="actionName">userInput</param>
<paramname="namespace">hello</param>
</result>
</action>
除了这两个参数之外,还可以使用相同的形式来想目标Action传递参数。
<resultname="next"type="redirect-action">
<paramname="actionName">userInput</param>
<paramname="userName">hello</param>
<paramname="password">world</param>
</result>
目标result地址将被翻译成:
userInput.action?userName=hello&passworld=world
Strtus2的除了支持Jsp作为结果页面之外还内建支持常用的两个模版引擎FreeMaker和Velocity。他们对应的Result Type是freenaker和velocity。有关这两种模版引擎技术的使用和介绍可以在需要的时候查看相关文档。
全局Result
以前我们的result都配置在action元素里面,这种result叫做局部result。他们只能被特定的action所访问。有时候我们需要将一些result作为多个action共享的资源,那么我们就可以将这些result设置为全局Result。他们的配置不再放在action元素中,而是放在package元素中了:
<packagename="default"namespace="/"extends="struts-default">
<global-results>
<resultname="error">/error.jsp</result>
<resultname="login">/admin/login.jsp</result>
</global-results>
<actionname="*User"class="action.UserAction"method="{1}">
<resultname="input">/input.jsp</result>
<resultname="success">success.jsp</result>
</action>
</package>
当我们配置了这些result之后,需要大致了解一下这些result的查找循序:
(1)首先会在<action>元素内查找是否有匹配的<result>元素,如果有则执行这个result,如果没有则执行下一步
(2)其次,在查找自己所在的package中的全局result,看有没有匹配的,如果有则执行,没有则执行下一步
(3)再次,递归查找自己所在包的父包中的全局result,如有匹配的result则执行,如果没有则执行下一步
(4)最后,以上三种情况均没有找到匹配的result,那么struts2就会抛出异常。
注:这个顺序同样适用有多个同名result时的执行优先级。
在学习Action的时候学到了Action的匹配可以使用通配符,同样对于Result的匹配也可以使用通配符,原理和用法相同:
1. <actionname="*_*_*_*"class="cn.javass.action.action.{1}Action"method="{2}">
2.
<resultname="{3}">/${folder}/{4}.jsp</result>
3. </action>
分享到:
相关推荐
本文将深入探讨Struts2的核心概念,包括Action、Result、配置文件、OGNL与ValueStack、Tags以及项目中的关键实践。 **一、Action** Action是Struts2中处理业务逻辑的核心组件,它是实现了`...
### Struts2 学习重点知识点总结 #### 一、Struts2 概念与架构 **1.1 Struts2 简介** - **定义**:Struts2 是 Apache 组织提供的一个基于 MVC 架构模式的开源 Web 应用框架。 - **核心**:Struts2 的核心其实是 ...
### Struts2学习笔记知识点详解 #### 一、Struts2框架的基本引入步骤 ##### 1. 导入Struts2相关Jar包 在引入Struts2框架时,首先需要将Struts2的相关Jar包导入到项目的类路径中。这些Jar包通常包括核心库以及其他...
13. ** strut2四天笔记**:这份学习笔记可能涵盖了以上所有知识点,包括如何创建Action,配置struts.xml,使用OGNL表达式,处理异常,以及实践中的各种技巧和最佳实践。 在四天的学习过程中,你应该通过实践和理解...
**六.Struts2的属性驱动和模型驱动** 1. **属性驱动**:Action类中的字段直接对应请求参数,Struts2自动将请求参数值填充到Action字段。 2. **模型驱动**:使用一个公共对象作为模型,Action类持有这个模型的引用,...
以上内容仅是Struts2学习笔记中的核心部分,实际学习时还需要深入理解拦截器、结果类型配置、插件机制、异常处理等更多高级特性。Struts2提供了强大的功能和灵活性,是Java Web开发中不可或缺的一部分。
本学习笔记将深入探讨Struts2的核心概念、架构以及实际应用。 一、Struts2框架概述 1. 架构:Struts2基于Model-View-Controller(MVC)设计模式,将业务逻辑、数据处理和用户界面分离,提高了代码的可读性和可维护...
综上所述,**牧紫小岩的Struts2学习笔记**涵盖了Struts2框架的关键概念和技术细节,从框架的初始化流程、配置管理到Action的实现与调用,再到结果处理和异常管理,为初学者和资深开发者提供了一个全面深入的学习资源...
### Struts2学习笔记2012 #### 一、建立一个Struts2工程 **步骤详解:** 1. **创建Web项目:** - 在MyEclipse中选择“File” > “New” > “Dynamic Web Project”,创建一个新的Web项目。 2. **解压并配置...
02 Struts2-Result 19 一、 Result类型 (type) 19 二、 全局结果集(Globle Result) 20 三、 动态的结果集(dynamic result) 21 四、 带参数的结果集 21 五、 Result总结 22 六、 项目经理: 22 03 OGNL表达式语言 23 ...
这份"struts2学习笔记和源码"资源是学习这个框架的理想材料,特别适合初学者。 一、Struts2框架基础 Struts2是Apache软件基金会下的一个项目,它是Struts1的升级版,弥补了Struts1的一些不足,如动作映射和拦截器等...
2. **Package**:包是Struts2中的一个关键概念,用于组织相关的Action和结果(Result)。包可以继承其他包,从而实现配置的复用和分层。`package`标签的属性包括name、extends、namespace等,其中,namespace用于...
本课程笔记主要涵盖了Struts2的基础概念、核心功能及其工作流程。 首先,Struts2的处理流程是通过一系列的组件协作完成的,包括Filter Dispatcher(过滤器调度器)、Action、Interceptor(拦截器)和Result。当用户...
这个"struts2学习笔记.rar"文件很可能包含了关于Struts2框架的详细教程和实践案例,对于学习和理解Struts2的核心概念和技术是非常有帮助的。 首先,Struts2框架的引入是为了克服早期Struts1框架的一些局限性,提供...