Struts2.0第05章Result.doc_第1页
Struts2.0第05章Result.doc_第2页
Struts2.0第05章Result.doc_第3页
Struts2.0第05章Result.doc_第4页
Struts2.0第05章Result.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第五章 Result在探讨Result之前,要向大家解释清楚很容易弄糊涂的两个概念:返回字符串和返回类型。在前面Action章节,提到返回的字符串有五种,但那不是现在要讨论的Result类型,那只是Xwork.xml配置文件中result标签name属性的值。如下所示:/welcome.jspresult标签还有一个type属性,但之前并没有显式使用过该属性,即一直使用该标签的默认值Dispatcher。在本章中将介绍Result的几种通用类型,如Dispatcher、Redirect、Chain以及一些其他模块的几种返回类型,将介绍Velocity、FreeMark、JasperReport三种模块的返回类型。在介绍他们之前,先带领读者看看如何自定义Result,这样会有助于理解Result的实质,为以后的学习打下基础。5.1自定义的Result在实现自定义的Result之前,先看看Struts2.0.9中关于Result的源代码。Result是一个接口,在xwork-2.0.4.jar中包含了这个类。xwork-2.0.4.jar的源代码Struts2.0.9中并没有包括,所以要去opensymphony网站下载xwork-2.0.4-src.zip包,解压之后,这个类的源代码文件的路径就是xwork-2.0.4-srcxwork-2.0.4srcjavacomopensymphonyxwork2Result.java。package com.opensymphony.xwork2;import java.io.Serializable;public interface Result extends Serializable public void execute(ActionInvocation invocation) throws Exception;可以看到,在Result的接口中只定义一个execute()方法,如果读者想实现自己的Result就必须实现该接口。接下来通过一个例子来看看如何自己创建一个简单的Result类型。我们给这个Result的类型取名为“test”,通过这个Result类型来告诉Action返回的是何种返回字符串,我们使用一个随机数来选择返回的五个类型中的一种。注意:Result接口中的execute()方法没有返回类型,因为Result就是执行最后的任务,没有必要再返回其他数据了。而Action接口中的execute()方法返回的是String类型。5.1.1实现自定义的Result前面已经说过要自定义Result类型,就必须实现Result接口,由于例子比较简单,只需要在execute()方法中添加几行代码。下面是一个完整的ResultType.java文件,它主要功能就是显示Action返回的类型。ResultType.javapackage example.result;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.Result;SuppressWarnings(serial)public class ResultType implements Result public void execute(ActionInvocation invocation) throws ExceptionString resultCode = invocation.getResultCode();System.out.println(This time of Result code:+resultCode);这个自定义的Result文件是在src的目录下创建的。看上面的代码很简单吧!在这个类里面只实现了一个Result接口中的execute()方法。如果有些函数读者不理解,可以去查看相关文档。在这里用到的是ActionInvocation这个类,然后调用里面的getResultCode()方法,这个函数返回的是在Action中执行之后所返回的代码,即前面提到的五种返回字符串类型之一,接下来是一句简单的输出语句。当然这只是一个最简单的自定义Result类型,它不能显示一个视图,后面读者将会看到Struts2集成的Result类型,它们的功能将会十分强大,在下一节读者将会体会到。其实,Struts2提供的Result类型已经够平时使用了,如果没有特殊的要求,没有必要使用自定义Result类型。知道Result的定义后,下面来看看Action的具体代码。完整的代码如下所示:TestAction.Javapackage example.result;import java.util.Random;import com.opensymphony.xwork2.ActionSupport;SuppressWarnings(serial)public class TestAction extends ActionSupportpublic String execute() throws Exception/产生一个100以内的整数int random = new Random().nextInt(100); /根据产生的随机数,分别返回五种不同的字符串if(random=20)return SUCCESS;else if(random=40)return ERROR;else if(random=60)return LOGIN;else if(random=80)return NONE;elsereturn INPUT;这个文件和ResultType.java是放在同一个目录下的。这个Action很简单,它先通过函数Random().nextInt(100)产生100以内的随机数,然后再通过比较来选择不同返回类型,最后通过ResultType.java在控制台上显示出来。5.1.2配置自己的Result当然只有前面两个文件是不能运行自定义的Result的,需要做相应的配置才能使用这个Result类型。Result的配置需要用到两个文件web.xml和xwork.xml。下面是web.xml的完整代码:web.xml Struts 2 RESULT struts-cleanup org.apache.struts2.dispatcher.ActionContextCleanUp struts-cleanup /* struts2 org.apache.struts2.dispatcher.FilterDispatcher struts2 /* index.html 想使用自定义的Result就要在struts.xml中进行配置,完整的struts.xml如下所示:struts.xml l 在这里可以看到与配置Action的不同之处,上述代码中加粗部分的代码是Action配置没有的。这里用了一个标签,该标签用来标志一个Result类型。该标签有三个属性,一个是name,一个是class,还有就是default。前两个是必须的,一个指明这个Result类型的名字,一个指出处理这个Result的类是哪个。最后的default属性只有两个值,默认的情况下是false,即说明这个Result类型不是默认的Result类型,使用的时候必须明确指明类型,如所示;若自己赋值为true,如上述代码所示,可以像这样使用,无须再指明其返回类型,这也是常用的方式。web.xml,xwork.xml这两个文件安放的位置跟一般的Action配置是一样的,最后的目录结构如图5-1所示。图5-1 完整的目录结构这样整个自定义的Result就算配置完成了。5.1.3运行测试Result没有配置返回页面,那么要怎么样才能看到结果和验证自定义的Result有没有成功呢?实际上,可以在MyEclipse下面的控制台视图中查看运行的结果。我们打开浏览器,输入http:/localhost:8080/ResultType/test.action,将会出现如图5-2的画面。图5-2 成功的运行界面显然在浏览器中不会有任何显示,但在MyEclipse的控制台中会有显示。多点击几次浏览器的刷新按钮,这样看到的效果会更明显,如图5-3所示:图5-3 控制台的信息如图5-3所示,在最下面的五行显示五种不同的返回类型,这就是这个简单的Result的功能了。可以看出来,自定义Result是很简单的,如果结果想要返回一个页面,就要在定义返回类型的类中增加一个参数定义,在下面将介绍参数的作用。而且还要在配置返回结果的时候加上要返回的页面,前面所有的例子都是有返回页面。正如前面所说,根本不需要自己动手去定义Result,Struts2已经定义了许多种返回类型,这些返回类型在日常开发中足够使用了。这节的目的主要是想通过一个简单的Result让读者明白整个Result的配置以及运行方式,为后面理解Struts2提供的Result类型打下基础,便于以后的学习。5.2常用的Result我们首先了解一下Struts2是在什么地方定义以及配置Result返回类型的。将下载的Struts2.0.9.zip压缩包解压之后,在路径struts-2.0.9-allstruts-2.0.9srccoresrcmainresources下有一个struts-default.xml文件,所有的Result类型都是在这里进行配置,在这里能看到对应Result类型的源代码定义在什么地方。下面是这个文件中关于Result类型配置部分的代码:struts-default.xml/*省略语句*/ /*省略语句*/ 从上面的代码可以明显看到,它与自己定义的Result类型配置是完全一样的。文中粗体表示就是各种Struts2定义的Result类型了,至于具体每个类型表示什么,可以参考表5-1,表中列出的也只是一些能用到的部分而并非全部,其他的Result类型请读者参考Struts2官方文档。上述配置代码中,属性class是各个Result类型对应的类文件。在接下来的章节中,对几个常用的Result的源代码进行一些解析,这样就能进一步了解Result的工作流程以及它的内涵。表5-1 Result类型列表Result类型Result对应的功能Dispatcher Result用于JSP的整合Redirect Result用于直接跳转到例外的URLChain Result用于 Action ChainingXSL Result用于 XML/XSLT 整合HttpHeader Result用于控制特殊的HTTP行为Stream Result用于向浏览器返回一个InputStream (一般用于文件下载)PlainText Result用于显示某个页面的原始的文本 (例如 jsp, html 等)Redirect Action Result用于直接跳转到另外的actionVelocity Result用于Velocity的整合FreeMarker Result用于FreeMarker的整合JasperReports Result用于JasperReports的整合下面就开始进入探讨Result类型之旅了。我们会介绍其中的三种常用Result类型以及其他三种关于视图的Result类型。5.2.1 Dispatcher要想真正理解Dispatcher的作用,应该首先通过struts-default.xml找到Dispatcher 对应的类文件,查看其源代码。在目录Struts2-.0.9Struts2-src-.0.9comopensymphonyStruts2dispatcher下可以找到一个ServletDispatcherResult.java文件。下面是截取ServletDispatcherResult.java的部分代码:ServletDispatcherResult.java/*省略语句*/ public class ServletDispatcherResult extends StrutsResultSupport /*省略语句*/private static final Log log = LogFactory.getLog(ServletDispatcherResult.class);/*省略部分方法*/实现从父类继承的方法 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); if (dispatcher = null) /给出错误的提示信息 response.sendError(404, result + finalLocation + not found); return; if(!response.isCommitted()&(request.getAttribute(javax.servlet.include.servlet_path) = null) /设置request中元素的值 request.setAttribute(struts.view_uri, finalLocation); request.setAttribute(struts.request_uri,request.getRequestURI();dispatcher.forward(request, response); else dispatcher.include(request, response); 在前面自定义Result的时候说过,任何Result类型都需要实现Result接口的execute()方法,但是在此处并未实现,为什么呢?在上述代码中的粗体部分可以看到ServletDispatcherResult类是继承StrutsResultSupport类的,那再分析一下StrutsResultSupport这个类,在与ServletDispatcherResult.java文件相同目录下可以找到StrutsResultSupport.java文件,其部分代码如下:StrutsResultSupport.java/*省略语句*/ /这个类实现了Result接口public abstract class Struts2ResultSupport implements Result, StrutsStatics private static final Log _log = LogFactory.getLog(Struts2ResultSupport.class); public static final String DEFAULT_PARAM = location; private boolean parse; private boolean encode; private String location; private String lastFinalLocation; /*省略一些方法*/public void setLocation(String location) this.location = location;public String getLastFinalLocation() return lastFinalLocation; public void setParse(boolean parse) this.parse = parse; public void setEncode(boolean encode) this.encode = encode;public void execute(ActionInvocation invocation) throws Exception lastFinalLocation = conditionalParse(location, invocation); doExecute(conditionalParse(location, invocation), invocation); protected String conditionalParse(String param, ActionInvocation invocation) /*省略语句*/ protected abstract void doExecute(String finalLocation, ActionInvocation invocation) throws Exception;看了StrutsResultSupport.java文件,想必大家就很明白为什么ServletDispatcherResult类没有实现Result接口的execute()方法了。文中粗体所示的部分表明StrutsResultSupport类是一个抽象类,在它里面实现了execute()方法,不过它的实现是调用一个doExecute()方法。在继承StrutsResultSupport类的时候,只要实现doExecute()方法就能达到对Result接口execute()方法的实现!所以在ServletDispatcherResult.java文件中只有这一个方法。下面来看看Result的参数,就是在配置struts.xml文件时标签对应的参数。在Struts2ResultSupport.java文件中用粗体表示的还有一些代码:public static final String DEFAULT_PARAM = location;protected boolean parse ;protected String location;这三句代码就定义了Dispatcher的两个参数,各自功能如下:n location (默认):执行后转到的地方(如jsp页面)。n parse:这个值在构造函数中已经默认为true。如果设置为false,location参数就不会被解析为Ognl表达式。location对应的就是自己编写的页面的地址,如果要返回一个页面就得拥有这个参数,否则定义的返回类型就不能返回到指定的页面。在以后介绍的每一种Result类型的时候,都会有这个DEFAULT_PARAM静态字符串变量。这个变量指明location是默认的参数,这就让使用者能够更方便的使用这种类型。清楚了返回类型怎么实现之后,接下来要考虑如何如在Action中用到它们。首先回顾一下第一个Action的例子,在xwork.xml配置文件里有这些代码:/*省略语句*/ /*省略语句*/ /welcome.jsp/*省略语句*/ 在struts.xml中将struts-default.xml文件包含进来,就是为了可以使用在struts-default.xml中定义的各种Result类型。再看标签,它只有一个name属性,没有type属性的指定也没有参数的指定,为什么可以这样?它怎么知道选择何种Result类型?原来在struts-default.xml中是这样定义Dispatcher的:原来已经定义default为true了,而且其他的Result都没有这个定义。location参数,因为有了默认的DEFAULT_PARAM静态字符串来表示,所以location参数也可以不需要显式表明。那么对于上面的Result标签更完整的配置应该是这样的/welcome.jsp至于parse参数,它是一个布尔型的,默认值为true,它是用来解析参数location的,具体的Ognl部分请参看以后的关于表达式语言的章节。弄清楚上述问题之后,现在重点来看ServletDispatcherResult.java中的doExecute()方法,弄清楚它的工作流程。ServletDispatcherResult.java/*省略语句*/ 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 dispatcherrequest.getRequestDispatcher(finalLocation); if (dispatcher = null) /404错误代码对应的错误信息的输出 response.sendError(404, result + finalLocation + not found); return; if(!response.isCommitted()&(request.getAttribute(javax.servlet.include.servlet_path) = null) /设置request中元素的值 request.setAttribute(struts.view_uri, finalLocation); request.setAttribute(struts.request_uri,request.getRequestURI();dispatcher.forward(request, response); else dispatcher.include(request, response); 上面是doExecute()方法的具体实现,可以从粗体部分看出这个Result有三种执行方式:n 如果在一个JSP的范围内(PageContext对象可用),PageContext的include(String)方法会被调用。n 如果没有PageContext对象,并且也不在任何形式的include中(在request的属性中没有javax.servlet.include.servlet_path),那么调用RequestDispatcher的forward方法。n 否则调用RequestDispatcher的include方法。还可以看到,如果dispatcher=null的话,会返回404代码错误。所以以后在使用Dispatcher的时候遇到404错误的时候,就应该知道是返回对应的页面地址或者Action找不到的问题。至于具体的类的含义以及方法是干什么的,读者可以自己去查阅servlet的API文档。这就是整个Dispatcher Result的流程了。下面用一个流程图来概括一下,如图5-4所示。图5-4 Dispatcher Result的流程这一节因为是第一次讲解Struts2定义的Result类型,所以内容比较多。这个小节对源代码进行了探讨,介绍了参数,执行方式等内容,让读者完全理解Dispatcher Result。后面因为有了这节的基础,Result的讲解将比较简单了。5.2.2 RedirectRedirect,即重定向,Action如果配置这种返回类型,那么就可以有三种不同的返回效果,分别是返回到页面、连接到另一个Action、还可以连接到一个网址。有了前面Dispatcher Result的基础,Redirect Result理解起来就比较容易了。让我们看看Redirect Result的源代码是如何实现的。首先看Redirect在struts-default.xml中的配置:这就是Redirect在struts-default.xml中的配置,与Dispatcher的不同就是没有default属性,通过上一小节可以知道,Redirect并不是默认的,使用的时候必须指明类型属性type=”redirect”。在ServletDispatcherResult.java文件路径下可以找到ServletRedirectResult.java文件,其代码如下:ServletRedirectResult.java/*省略语句*/ public class ServletRedirectResult extends StrutsResultSupport private static final Log log = LogFactory.getLog(ServletRedirectResult.class);/*省略部分代码*/ protected boolean prependServletContext = true; public void setPrependServletContext(boolean prependServletContext) this.prependServletContext = prependServletContext; protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception /*省略语句*/ response.sendRedirect(finalLocation); /*省略语句*/ 在这里只是简单的截取一些代码片断,粗体部分显示了它和Dispatcher一样都是继承StrutsResultSupport类的,都实现了doExecute()方法。有兴趣的读者可以把这段完整的源代码找出来研究一下,在这里就不再赘诉了。同样,Redirect也有自己的参数。n location(默认):action执行后跳转的地址。n parse:这个值在构造函数中已经默认为true。如果设置为false,location参数不会被当作Ognl表达式解析。参数和Dispatcher是一样的,不过这里的location可以是一般的JSP页面,可以是一个Action,还可以是一个其他的网址(譬如:)。这就是Redirect被称为重定向的原因,可以定向到不同的方式。下面通过一个简单的例子来了解一下Redirect。在一个项目里面定义三个Action,他们的Result的类型都是redirect,但是他们重定向的对象不同,一个为一般的JSP页面,一个为Action,一个是一个网址URL。可以把本书一开始创建的第一个Action项目拿出来使用,在同一个包中再添加两个Action,这两个Action只返回SUCCESS,不做其他事情。下面是三个Action的对应源代码:helloworld.javapackage example;import com.opensymphony.xwork2.ActionSupport;SuppressWarnings(serial)public class helloworld extends ActionSupportpublic String message;public String name;public String execute()if ( name = null | .equals(name)|w.equals(name)message=Blank names or w not allowed;return INPUT;message = hello +name+!n;return SUCCESS;public String getMessage()return message;public void setName(String

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论