- 浏览: 310263 次
最新评论
-
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
hunanjun000:
《研磨struts2》第四章 Action 之 4.5 Action的其它重要知识
5.2 预定义的Result
5.2.1 预定义的ResultType
在Struts2中,预定义了很多ResultType,其实就是定义了很多展示结果的技术。Struts2把内置的<result-type>都放在struts-default包中。struts-default包就是我们配置的包的父包,在第4章已经看到这个包定义在struts2-core-2.1.8.1.jar包中的根目录下的文件struts-default.xml中。
在这个包中,可以找到相关的<result-type>的定义,<result-types>元素是<package>元素的直接子元素。Struts2预定义如下:
- <result-types>
- <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
- <result-type name="dispatcher"
- class="org.apache.struts2.dispatcher.ServletDispatcherResult"
- default="true"/>
- <result-type name="freemarker"
- class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
- <result-type name="httpheader"
- class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
- <result-type name="redirect"
- class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
- <result-type name="redirectAction"
- class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
- <result-type name="stream"
- class="org.apache.struts2.dispatcher.StreamResult"/>
- <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
- <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
- <result-type name="plainText"
- class="org.apache.struts2.dispatcher.PlainTextResult" />
- </result-types>
上面的每一个<result-type>元素都是一种视图技术或跳转方式的封装。其中的name属性是在<result>元素中如何引用这种视图技术或跳转方式,对应着<result>元素的type属性的值。
可能有朋友会说,我们在配置<result>元素的时候,没有配置过type属性嘛。没错,你确实没有配置过,原因就在于Struts2里面设置了默认的type,就是上面加粗的那句话,你没有配置,默认就是“dispatcher”。这个“dispatcher”的技术就相当于在Servlet里面的“RequestDispatcher”的技术,也就是一个页面跳转的技术。
而class属性是这种视图技术或跳转方式的具体实现类,这些实现类都已经是Struts2实现好的,我们只需要引用就可以了。
5.2.2 如何配置使用
Result的配置非常简单,<result>元素可以有name属性和type属性,但是两种属性都不是必须的。
1:配置name属性
按照前面的讲述,name属性是用来跟Action的execute方法返回的字符串相对应的,用来指示Action运行后跳转到的下一个页面,因此name属性的值可以是任意字符串。比如有如下的execute方法:
那么,这里返回的“toWelcome”,在struts.xml里面就有如下的配置来对应:
如果不设置的话,默认值为“success”,正好和Action中的“SUCCESS”这个常量相对应,那样的话,execute方法就应该返回SUCCESS,如下:
此时在struts.xml里面就有如下的配置来对应:
或者是:
2:配置type属性
<result>元素的type属性也可以是任意字符串,不过,一定是某一个<result-type>元素的name属性。在没有自定义ResultType的情况下,type属性的值,就是在struts-default.xml中所定义的<result-type>的name属性的值。比如:
这里的“dispatcher”就是在struts-default.xml中所定义的默认的<result-type>的name属性值。既然是默认的,那就可以不用配置,也就是说,上面的配置跟如下配置是等价的,示例如下:
好了,基本的Result配置使用就差不多了,接下来,挑选几个常见的ResultType,来看看如何配置并使用它们。
5.2.3 名称为dispatcher的ResultType
1:基本使用
名称为“dispatcher”的ResultType,在struts-default.xml里的配置如下:
通过配置可以看出,它对应的实现类是ServletDispatcherResult。
如果采用JSP作为视图的实现技术,那么这个ResultType是最常用的。在这个ResultType的实现中,调用了javax.servlet.RequestDispatcher类的forward方法,也就是说它相当于是对RequestDispatcher的一个再包装。
既然是这样,那么在Servlet中使用RequestDispatcher来进行页面跳转的特性,也就自然被“dispatcher”这个ResultType继承下来了。那么Servlet中的RequestDispatcher,到底有什么特性呢?
那就是通过RequestDispatcher来进行页面跳转,将会保持是同一个请求对象。这有什么好处呢?由于是同一个对象,那就意味着有同样的数据,而请求对象里面数据众多,在Servlet的request对象里面,典型有如下数据:
- 参数区(parameter),就是用户在页面上填写并提交的数据
- Head区,由浏览器在发出请求的时候,自动加入到请求包的数据
- 属性区(Attribute),由开发人员存储在属性区的值,通常是通过request.setAttribute方法、request.getAttribute方法来进行访问
- Cookie区,由浏览器在发出请求的时候,自动把相关的Cookie数据通过request传递到服务端
好处是不是很大?因此这也是使用Struts2来进行web开发中最常使用的ResultType。至于怎么使用,前面很多例子都是用的“dispatcher”,这里就不再赘述了。
2:几个小知识点
(1)在<result>元素的定义中可以使用Action的execute方法运行之后的数据。怎么做呢?一起来看看示例。
或许我们都已经习惯于以下这种简单的<result>配置:
里面用于指定jsp位置的字符串都是固定的。如果我们希望这个字符串是活动的,可以根据某些参数值来变化,该怎么做到呢?
如果我们在Action中定义一个folder字符串,并在execute中对它赋值:
- public class HelloWorldAction extends ActionSupport {
- private String account;
- private String password;
- private String submitFlag;
- private String folder;
- public void setFolder(String folder){
- this.folder = folder;
- }
- public String getFolder(){
- return folder;
- }
- public String execute() throws Exception {
- this.folder = "s2impl";
- return "toWelcome";
- }
- //属性对应的getter/setter方法,省略了
- }
那么,在<result>的定义中就可以引用folder这个变量,示例如下:
这样配置的结果和前面写死的路径效果时完全一样的。
仔细观察一下你会发现,“${folder}”的写法跟以前在jsp上写的el表达式类似,而里面的“folder”是跟Action的属性相对应的。
(2)对于dispatcher的使用范围,除了可以配置jsp外,还可以配置其他的web资源,比如其他的Servlet等。
如果在web.xml中有如下配置:
那么在struts.xml中可以如下配置:
但是请注意,如果这个web资源是另一个Action的话,不能这么配置,需要使用Struts2的另一种名称为“chain”的ResultType。
(3)使用“dispatcher”的ResultType,不能访问其他web应用中的web资源。当然,这个特性是由javax.servlet.RequestDispatcher类的forward方法决定的。
(4)更完整的配置方式
平时把result对应的jsp的路径,直接作为<result>元素中的文本来配置,这是简化的写法,实际上对于dispatcher还有两个参数可以配置,示例如下:
location参数就是咱们平时写的下一个jsp的位置,而parse参数决定了location是否可以通过使用OGNL来引用参数,默认为true。
其实,前面使用${folder}来引用Action的folder属性的值的例子,就是使用的OGNL来引用参数。
5.2.4 名称为redirect的ResultType
1:基本使用
名称为“redirect”的ResultType,在struts-default.xml里的配置如下:
通过配置可以看出,它对应的实现类是ServletRedirectResult。
这种Result同常也使用JSP作为视图技术。它包装的是javax.servlet.http.HttpServletResponse类的sendRedirect方法,这个ResultType也是用来实现跳转到下一个页面的。
但是它的功能与上面的dispatcher不同,“redirect”的特点是全新的请求,这就意味着,本次请求和跳转到下一个页面的请求是不同的对象,因此它们的值是不一样的。
可以通过如下的方式来测试一下。修改前面dispatcher的示例,主要是修改struts.xml,需要把result的type设置为“redirect”。示例如下:
其他的可以不用改变,然后回到登录页面,填写帐号和密码,然后点击登录按钮,正确的跳转到了欢迎页面,如下图所示:
图5.1 使用redirect的欢迎页面
仔细看看,有什么不同?
很明显,这里没有正确的显示出帐号的值来,看看后台有值吗?肯定是有的。这就说明经过“redirect”这个ResultType,跳转到欢迎页面的时候,两个请求对象不是一个了,因此在欢迎页面无法获取到帐号的值了。
你可以把struts.xml中,type=“redirect”的配置去掉,或者改成type=“dispatcher”,再次运行看看,欢迎页面就应该有值了。
2:几个小知识点
对比着dispatcher的ResultType,来看看相应的几个问题。
(1)同样在<result>元素的定义中可以使用Action的execute方法运行之后的数据。
测试示例,同样在Action中定义一个folder字符串,并在execute中对它赋值,跟前面一样,这里就不去赘述了。
那么,在<result>的定义中就可以引用folder这个变量,示例如下:
由于redirect采取重定向的方式,下一个页面会取不到上一个请求对象里面的值,如果要传值的话,可以采用get的方式传参。示例如下:
上面这个配置,会向新请求里面传入account的参数,这样在欢迎页面就可以获取到account的值了。
但是,前面写的欢迎页面是取不到这个account的值的,为什么呢?先来看看前面写的欢迎页面取值的那句话,如下:
以前的欢迎页面,是通过使用Struts2的标签来获取的account的值,Struts2的标签会到Struts2的值栈里面去取值,而这里是执行Result的时候,才再请求上添加了account这么一个参数,然后就直接回到页面了,根本不会再走一次Struts2的运行过程,也就是说,这里传递的这个参数,根本不会进入到这个请求对应的值栈,因此这里这个写法是取不到值的。
那么该怎么写才能获取到这个account参数的值呢?
有两个简单的方法,一个是直接使用Servlet的HttpServletRequest对象的方法来获取参数,另外一个方法是直接使用EL表达式,都是可以的,示例如下:
再次测试看看,此时的欢迎页面就应该有account的值了。
(2)对于redirect的使用范围,除了可以配置jsp外,还可以配置其他的web资源,比如其他的Servlet等。具体写法跟dispatcher一样,不再赘述。
(3)使用“redirect”的ResultType,可以访问其他web应用中的web资源,甚至是任何你想要访问的网站都可以。
(4)更完整的配置方式
与“dispatcher”一样,“redirect”也可以配置<param>,同样可以配置location和parse,连含义都是一样的,因此就不去示例了。
5.2.5 名称为chain的ResultType、
1:基本使用
名称为“chain”的ResultType,在struts-default.xml里的配置如下:
chain是一种特殊的视图结果,用来将Action执行完之后链接到另一个Action中继续执行,新的Action使用上一个Action的上下文(ActionContext),数据也会被传递。
这在实际开发中,也是经常用到的一种ResultType。比如我们在Servlet开发中,一个请求,被一个Servlet处理过后,不是直接产生相应,而是把这个请求传递到下一个Servlet继续处理,直到需要的多个Servlet处理完成后,才生成响应返回。
同样的,在Struts2开发中,也会产生这样的需要,一个请求被一个Action处理过后,不是立即产生响应,而是传递到下一个Action中继续处理。那么这个时候,就需要使用chain这个ResultType了。
来示例一下,先看看第一个Action,就用HelloWorldAction吧,稍微简化一下,示例如下:
- public class HelloWorldAction extends ActionSupport {
- private String account;
- private String password;
- private String submitFlag;
- public String execute() throws Exception {
- this.businessExecute();
- return "toSecond";
- }
- public void businessExecute(){
- System.out.println("用户输入的参数为==="+"account="+account+",password="+password+",submitFlag="+submitFlag);
- }
- //属性对应的getter/setter方法,省略了
- }
第二个Action,示例代码如下:
然后到struts.xml中,配置这两个Action,要注意第一个Action的配置,在配置“toSecond”这个result的时候,用的就是chain这个ResultType,示例如下:
- <package name="helloworld" extends="struts-default">
- <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">
- <result name="toSecond" type="chain">
- <param name="actionName">secondAction</param>
- </result>
- </action>
- <action name="secondAction" class="cn.javass.action.action.SecondAction">
- <result name="toWelcome">/s2impl/welcome.jsp</result>
- </action>
- </package>
其他的可以不用改变,然后回到登录页面,填写帐号和密码,然后点击登录按钮,正确的跳转到了欢迎页面,如下图所示:
图5.2 使用chain的欢迎页面
仔细观察上面的欢迎页面,会发现能够访问到用户在登录页面填写的帐号数据。再来看看后台,会输出如下信息:
其中第一行是HelloWorldAction输出的信息,而第二行,很明显是SecondAction输出的信息了。也就是说,用户提交登陆请求,只发出了一次请求,但是有两个Action来处理了这个请求。这个请求先被HelloWorldAction进行处理,然后链接到SecondAction,由SecondAction来继续处理这个请求,并在处理完成后,产生响应,回到欢迎页面。
2:几个小知识点
(1)chain不能在result配置的时候传递参数,也就是说,不能类似于如下的配置:
这种配置方式是不行的,因为这里要求配置的是要链接的Action的name,不能传递参数,那么,要传递参数怎么办呢?
那就需要在Action里面使用ActionContext或者ServletActionContext,由于还没有学到,这里先不去示例了。
(2)在上面示例的欢迎页面,照样输出了用户在登录页面提交给HelloWorldAction的值,这说明使用chian的方式,后面的Action会和前面的Action共用同一个ActionContext,简单点说就是有同样的数据。
(3)名称为“chain”的ResultType在配置的时候,除了前面示例中的actionName外,还有一个参数,名称为“namespace”,表示被链接的Action所在包的命名空间,如果不设置,默认的即是当前的命名空间。配置示例如下:
5.2.6 名称为freemarker的ResultType
Struts2除了支持以JSP作为视图技术之外,还支持其他的模板技术,比如FreeMarker和Velocity。这里仅以FreeMarker为例,来讲述一下Struts2如何使用其他模板技术。
FreeMarker是一个纯Java模板引擎,是一种基于模板来生成文本的工具。具体的FreeMarker的知识这里就不去介绍了,感兴趣的朋友可以到http://freemarker.sourceforge.net/去获取详细的信息。
freemarker的ResultType,顾名思义,就是用来处理结果页面为使用FreeMarker制作的页面的这样一种ResultType。在struts-default.xml中,名称为“freemarker”的ResultType的配置如下:
下面通过一个简单的示例,来看看如何使用名称为freemarker的ResultType。
1:沿用前面的资源
HelloWorldAction和login.jsp都和前面的示例一样,这里就不再赘述了。
2:制作Freemarker的页面welcome.ftl
这个页面很简单,只是简单的输出帐号信息,示例代码如下:
这个页面就像一个普通的jsp,其中的${account},就像在jsp中调用el表达式一样。而其中的内容,就像以前在welcome.jsp中使用el表达式${ account }取值一样。
这里要注意的一个问题是,究竟这个welcome.ftl放在什么地方?
FreeMarker对应的ftl文件,并不是放在WebContent下,而是放在classes的路径下,在Eclipse中开发的时候,放到src下,因为Eclipse会自动将其编译到classes路径去。
3:配置struts.xml
主要是要修改toWelcome的result配置,示例代码如下:
注意其中的type是freemarker,对应的值是“welcome.ftl”,意味着在classes的根下有一个“welcome.ftl”的文件。如果对应的值是“/aa/ welcome.ftl”,那就表明在classes的根下有一个名称为“aa”的文件夹,在aa文件夹下有一个名为“welcome.ftl”的文件
4:关于freemarker的配置
freemarker类型Result的共有4个参数,示例如下:
- location用于指定ftl文件的位置。
- parse默认为true,指定在location中出现的形如${name}的表达式是否会被解析。
- contentType默认为text/html,指定输出方式。
- writeIfCompleted默认为false,指定是否不存在ftl解析错误的时候才写入到流中。
使用freemarker类型Result之后,可以发现,在Struts2中,同一个web应用可以同时使用多种不同的视图技术。
如果一个web应用中,以freemarker类型的Result为主的话,完全可以设置freemarker类型的Result为默认的Result。 只需要在包中覆盖对freemarker类型的声明,设置default属性为true即可,示例如下:
5.2.7 其他ResultType
除了前面提到的这些result,Struts2还提供其他的Result,比如用于同Velocity、xslt等的结合,这里简单的介绍一下:
1:velocity:用来处理velocity模板。Velocity是一个模板引擎,可以将Velocity模板转化成数据流的形式,直接通过JavaServlet输出。
2:xslt:用来处理处理XML/XLST模板,将结果转换为xml输出。
3:httpheader:用来控制特殊HTTP行为
4:stream:用来向浏览器进行流式输出
私塾在线网站原创《研磨struts2》系列
转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4051.html】
欢迎访问http://sishuok.com获取更多内容
评论
default="true"/>
发表评论
-
研磨struts2 目录贴
2012-08-24 12:12 163531.1 《研磨struts2》 第一章 Struts2 ... -
跟着cc学设计 之 研磨设计模式 视频教程 出炉了
2012-08-15 07:16 2研磨设计模式——跟着CC学设计系列精品课程,上线了! ... -
研磨struts2 目录
2012-07-30 21:15 2471.1 《研磨struts2》 第一章 Strut ... -
研磨struts2 目录
2012-07-30 16:54 361.1 《研磨struts2》 第一章 Stru ... -
《研磨struts2》A.2 struts.properties的配置 之 A.2.1 概述
2012-07-09 12:10 3072A.2.1 概述 如果我们希望覆盖在 ... -
《研磨struts2》附录A Struts2的配置 之 A.1 struts.xml的配置
2012-07-09 12:10 2719A.1 struts.xml的配置 A.1.1 ... -
《研磨struts2》第二十一章 零配置 之 21.3 通过注解来实现零配置
2012-07-06 08:07 293021.3 通过注解来实现零配置 21.3.1 ... -
《研磨struts2》第二十一章 零配置 之 21.2 约定大于配置
2012-07-05 10:44 247421.2 约定大于配置 21.2.1 约定 ... -
《研磨struts2》第二十一章 零配置 之 21.1 概述
2012-07-05 10:44 232621.1 概述 21.1.1 零配置概述 在 ... -
《研磨struts2》第二十章 整合SiteMesh 之 20.3 整合Struts2与SiteMesh
2012-07-04 08:15 2090在Struts2中使用SiteMesh ... -
《研磨struts2》第二十章 整合SiteMesh 之 20.2 单独使用SiteMesh
2012-07-03 08:00 210520.2 单独使用SiteMesh 20. ... -
《研磨struts2》第二十章 整合SiteMesh 之 20.1 调整应用的风格
2012-07-03 07:59 187020.1 调整应用的风 ... -
《研磨struts2》19.2 使用execAndWait拦截器模拟进度条 之 19.2.1 模拟长时间运行的Action
2012-07-02 12:24 215019.2.1模拟长时间运行的Action ... -
《研磨struts2》第十九章 进度条 之 19.1 使用“进度条”告知用户进度
2012-07-02 12:23 215219.1 使用“进度条”告知用户进度 ... -
《研磨struts2》第十八章 结合JFreeChart 之 18.3 Struts2结合JFreeChart
2012-06-28 12:12 201518.3 Struts2结合JFreeChart ... -
《研磨struts2》第十八章 结合JFreeChart 之 18.2 Struts2插件概述
2012-06-28 12:11 2031Struts2并没有求大求全,企图把所有 ... -
《研磨struts2》第十八章 结合JFreeChart 之 18.1 JFreeChart使用
2012-06-20 15:48 229618.1 JFreeChart使用 18.1.1概 ... -
研磨struts2(1-10章)电子书下载
2012-06-19 07:30 6078研磨struts2的博客文章 私塾在线学习网 《研 ... -
《研磨struts2》第十七章 防止重复提交 之 17.3 更强大的tokenSession拦截器
2012-06-18 13:46 208217.3 更强大的tokenSession拦截器 ... -
《研磨struts2》第十七章 防止重复提交 之 17.2 使用标签
2012-06-18 13:45 234017.2 使用<s:token/>标签 ...
相关推荐
2. **拦截器(Interceptors)**:Struts2的核心之一是其拦截器机制,它们在Action执行前后执行一系列预定义或自定义的操作。这些拦截器可以用于登录验证、日志记录、性能监控等。源代码中可能包含了不同类型的拦截器...
### 知识点一:Struts2入门(MVC HelloWorld) #### 1.1 Struts2简介 ...以上就是关于“研磨Struts2”的主要知识点梳理,通过深入学习这些内容,开发者可以更好地掌握Struts2框架的核心技术和实践技巧。
Result是Struts2中负责返回结果的对象,第五章详细介绍了Result的各种类型和用法。预定义的Result类型如dispatcher、redirect、chain等,以及如何自定义Result,都是本章的重点。此外,Struts2的异常映射、...
由于文件较大,我把这个文档切割为2部分,这是第一部分,请下载完第一部分后一定要下载第二部分,否则不能阅读。
Struts2框架的拦截器是其一大特色,它允许开发者定义一系列预定义或自定义的行为,这些行为在请求被处理前和后执行。例如,登录验证、日志记录、性能监控等都可以通过拦截器实现。通过灵活的拦截器链,开发者可以...
Struts2提供了多种预定义的Result类型,同时支持自定义Result类型的扩展。 ### 拦截器(Interceptor) 拦截器是Struts2的一个核心特性,用于在Action执行前后进行一系列操作,如权限检查、数据校验、事务管理等。...
根据提供的文件信息,我们可以推断出这是一份关于《研磨Struts 2》书籍PDF版本的下载资源。为了更好地理解和概括这份资料所涉及的知识点,我们先来了解一下Struts 2框架及其重要性,然后深入探讨《研磨Struts 2》这...
预定义的Result类型如`dispatcher`、`redirect`等简化了结果的配置。 11. **Interceptor**:拦截器是Struts2中的另一个重要特性,它们在Action执行前后插入,提供了日志、权限检查、事务控制等功能。拦截器链可以...
研磨Struts2 高清完整版,请和第一部分一起下载啊
研磨Struts2_12859679_高清完整版
研磨Struts2-高清-完整目录-2011年10月,分享给所有需要的人
第5章 单例模式(Singleton) 第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11...
第5章 单例模式(Singleton) 第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11...
Java工程师三大框架面试题.pdf
第5章 单例模式(Singleton) 第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11...
第5章 单例模式(Singleton) 第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) ...