`
jdluojing
  • 浏览: 16425 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

Struts2学习笔记(六) 结果(Result)(上)

 
阅读更多

大多数情况下我们的用例可以被分成两个部分。一是我们需要改变和查询应用程序的状态,而是需要呈现和更新应用程序的视图。在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>


分享到:
评论

相关推荐

    毕业设计:基于SSM的mysql-羽毛球交流平台系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_羽毛球交流平台系统(源码 + 数据库 + 说明文档) 2 关键技术介绍 6 2.1 JSP技术概述 6 2.2 MYSQL简介 6 2.3 B/S结构 7 2.4 JAVA语言 8 2.5 MyEclipse简介 9 2.6 性能分析 9 2.7 SSM概述 10 3 需求分析与设计 11 3.1 系统需求分析 11 3.2 运行可行性 11 3.3 系统可行性分析 11 3.3.1 技术可行性 11 3.3.2 经济可行性 12 3.3.3 操作可行性 12 3.4 系统功能分析 12 3.5 系统功能结构图 13 3.6 系统流程分析 14 4 数据库设计 17 4.1数据库逻辑结构设计 17 4.2数据库物理结构设计 20 5 系统的详细设计与实现 25 5.1首页页面 25 5.2站内新闻页面 25 5.3场地列表页面 26 5.4场地详情页面 26 5.5在线留言页面 27 5.6修改密码页面 27 5.7注册用户管理信息页面 28 5.8场地信息管理页面 28 5.9场地预约管理页面 29 5.10评论信息管理页面 29 5.11添加友情链

    node-v10.15.1-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    VLT 变频器工程指南 danfoss

    VLT 变频器工程指南 Guía de funcionamiento Safe Torque off Convertidores de frecuencia VLT

    基于Java的C语言试题生成与考试系统的设计与实现(源代码+论文)

    基于Java的C语言试题生成与考试系统的设计与实现是一个毕业设计题目,旨在通过使用Java编程语言设计和开发一个功能完善的C语言试题生成与考试系统。 该毕业设计题目的背景和意义在于,随着计算机科学的不断发展,C语言作为一门基础编程语言,被广泛应用于软件开发、系统编程等领域。为了更好地评估学生对C语言的掌握程度,传统的纸质试卷已经无法满足需求,因此,开发一个基于Java的C语言试题生成与考试系统具有重要的实际意义。 该毕业设计题目的主要研究内容包括以下几个方面:首先,需要进行系统需求分析,明确系统的功能需求和技术要求。然后,需要进行系统设计,包括数据库设计、模块划分、算法设计等。接下来,需要使用Java编程语言进行系统开发,包括前端界面开发、后台逻辑实现、数据库操作等。最后,需要进行系统测试和优化,确保系统的稳定性和可靠性。 通过完成该毕业设计题目,学生可以深入学习和掌握Java编程语言,提高软件开发能力。同时,学生还可以学习和了解C语言的相关知识,以及试题生成和考试系统的设计与实现方法。这对于学生未来的职业发展具有积极的推动作用。

    毕业设计:基于SSM的mysql-智能图书馆导航系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_智能图书馆导航系统(源码 + 数据库 + 说明文档) 2 系统总体设计 1 2.1 需求调研 1 2.2系统功能性需求 2 2.3可行性分析 3 2.2.1经济可行性 3 2.2.2技术可行性 3 2.2.3操作可行性 4 2.4功能性需求分析 4 2.5本章小结 5 第3章 系统设计 6 3.1设计的思路 6 3.2系统结构设计 6 3系统功能结构 6 3.3数据库设计 7 3.3.1数据库设计概述 7 3.3.2概念设计 8 3.3.3表设计 9 3.4业务功能设计与实现 11 3.4.1查询功能的设计与实现 11 3.4.2借阅功能的设计与实现 12 第四章 系统实现 14 4.1 系统登录页面实现 14 4.2管理员操作界面实现 14 4.3 图书管理实现 15 4.4读者表管理实现 17 4.5 借还管理实现 17 4.6图书借阅实现 18 4.7我的借还信息实现 18 第五章 系统测试 20 5.1系统测试环境 20 5.2系统单元测试 20 5.3集成测试 20 5.4测试用例 21 5.5 性能测试 21 5.6 测试结果分析 22

    毕业设计:基于SSM的mysql-学习交流平台(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_学习交流平台(源码 + 数据库 + 说明文档) 第二章 需求分析 5 2.1需求调研 5 2.2可行性分析 6 2.2.1技术的可行性 6 2.2.2经济的可行性 6 2.2.3操作可行性 6 2.2.4法律的可行性 7 2.3系统用户用例图 7 2.3.1管理员用例图 7 2.4功能模块需求分析 7 2.5设计的基本思想 9 2.6性能需求 9 2.6.1系统的安全性 9 2.6.2数据的完整性 9 2.7界面需求 10 2.7非功能性需求分析 11 2.7.1端到端响应时间 11 2.7.2易用性需求 11 2.7.3 可扩展性 11 第三章 系统分析与设计 12 3.1数据库的分析与设计 12 3.1.1数据库的概念结构设计 13 3.1.2数据库的逻辑结构设计 14 第四章 系统功能实现 17 4.1系统登陆页面实现 17 4.2总体功能模块 18 4.2.1注册用户信息管理 19 4.2.2学习资讯管理信息管理 20 4.2.3文章发表管理 21 4.2.4公告信息管理 22 4.2.5留言信息管理 22 4.2.6修改密码 23 4.2.

    基于JAVA的RSA文件加密软件的设计与实现(源代码+论文).rar

    本资料包名为“基于JAVA的RSA文件加密软件的设计与实现”,是一个针对计算机专业学习者提供的实用资源。它包含了完整的Java源代码以及一篇详细的论文,旨在帮助用户深入理解并实践RSA加密算法在文件加密领域的应用。该源码是基于Java语言开发的,利用了Java平台的安全和网络特性,实现了一个简单而强大的RSA文件加密工具。通过这个工具,用户可以对任意文本或数据文件进行加密和解密操作,确保信息传输的安全性。代码结构清晰,注释齐全,便于学习和修改。配套的论文则详细介绍了整个项目的设计理念、开发过程、关键技术点以及可能的改进方向。它从理论到实践,逐步引导读者了解RSA加密原理,并通过实例演示如何在Java环境中实现这一算法。无论是对于正在学习密码学、网络安全或是Java编程的学生,还是对于需要实现文件加密功能的开发者来说,这份资料包都是一份宝贵的学习资源。它不仅提供了现成的解决方案,更开辟了一条探索信息安全和Java编程深层次结合的道路。重新回答||

    毕业设计:基于SSM的mysql-学生网上请假系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_学生网上请假系统(源码 + 数据库 + 说明文档) 第2章 主要技术和工具介绍 5 2.1 SSM 框架 5 2.1.1. Spring 框架 5 2.1.2 SpringMVC 6 2.1.3. MyBatis 的选用 6 2.2 mysql数据库 6 2.3eclipse与Tomcat简介 6 第3章 系统分析 4 3.1可行性分析 4 3.1.1经济可行性 4 3.1.2技术可行性 4 3.1.3操作可行性 4 3.2需求分析 4 3.3业务流程分析 5 3.4数据流程分析 5 第4章 系统设计 8 4.1系统结构设计 8 4.2功能模块设计 8 4.3数据库设计 9 4.3.1数据库设计概述 9 4.3.1概念设计 9 4.3.2表设计 11 第5章 系统实现 15 5.1基本论坛 15 5.2主页面的实现 15 5.3登录模块的实现 16 5.4班级信息管理模块的实现 17 5.6基础信息模块的实现 18 5.6用户权限管理模块的实现 19 5.7学生请假管理模块的实现 22 第6章 系统测试 23 6.1测试目的 23 6.2测试概述

    MFC,C++-简单学生成绩管理系统.zip

    学生成绩管理系统c

    node-v8.5.0-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基于matlab开发的AUV惯性导航系统matlab仿真程序,包括轨迹生成、gps和sins组合、gps和dvl组合.rar

    基于matlab开发的AUV惯性导航系统matlab仿真程序,包括轨迹生成、gps和sins组合、gps和dvl组合.rar

    M24LC04B EEPROM的Verilog行为模型

    M24LC04B EEPROM的Verilog行为模型

    node-v12.5.0-x86.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    2023商业银行数据资产体系白皮书,主要介绍了“三位一体”数据资产体系的构成与工作机制,以及商业银行数据资产体系建设实践

    2023商业银行数据资产体系白皮书 目录 第 1 章 数据资产化与数据要素市场化相辅相成,相互促进 第 2 章 数据资产化是企业数据治理向上演进的必经之路 第 3 章 数据资产体系发展概述 第 4 章 “三位一体”数据资产体系的构思 4.1“三位一体”数据资产体系的构成与工作机制 数据资产管理 数据资产运营 数据资产评价 数据资产体系工作机制 4.2“三位一体”数据资产体系的相互作用关系 4.3“三位一体”数据资产体系的构建 4.4“三位一体”数据资产体系的优势 第 5 章 商业银行数据资产体系建设实践 5.1商业银行开展数据资产体系建设的背景和目标 5.2商业银行数据资产体系建设的工作步骤 5.3上海银行数据资产体系建设实践的主要成果 第 6 章 数据要素流通市场赋能企业数据资产化 6.1全国多层次数据要素市场的建设 6.2上海数据交易所赋能企业数据资产化 6.3数据要素流通交易市场赋能企业数据资产化的展望 第 7 章 未来演进与展望

    基于matlab实现wsn路由,用matlab仿真,具有选簇的功能.rar

    基于matlab实现wsn路由,用matlab仿真,具有选簇的功能.rar

    什么是学生成绩管理系统c++以及学习学生成绩管理系统的意义

    学生成绩管理系统c++

    Dubins曲线算法讲解和在运动规划中的使用.pdf

    Dubins曲线算法讲解和在运动规划中的使用.pdf

    基于TOGAF的4A企业架构规划方法论.pptx

    基于TOGAF的4A企业架构规划方法论.pptx

Global site tag (gtag.js) - Google Analytics