Struts2.0第05章Result_第1頁
Struts2.0第05章Result_第2頁
Struts2.0第05章Result_第3頁
Struts2.0第05章Result_第4頁
Struts2.0第05章Result_第5頁
已閱讀5頁,還剩16頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、精品文檔第五章 Result在探討Result之前,要向大家解釋清楚很容易弄糊涂的兩個概念:返回字符串和返回類型。在前面Action章節,提到返回的字符串有五種,但那不是現在要討論的Result類型,那只是Xwork.xml配置文件中result標簽name屬性的值。如下所示:<result name="success">/welcome.jsp</result>result標簽還有一個type屬性,但之前并沒有顯式使用過該屬性,即一直使用該標簽的默認值Dispatcher。在本章中將介紹Result的幾種通用類型,如Dispatcher、Redir

2、ect、Chain以及一些其他模塊的幾種返回類型,將介紹Velocity、FreeMark、JasperReport三種模塊的返回類型。在介紹他們之前,先帶著讀者看看如何自定義Result,這樣會有助于理解Result的實質,為以后的學習打下根底。5.1自定義的Result在實現自定義的Result之前,先看看中關于Result的源代碼。Result是一個接口,在xwork-2.0.4.jar中包含了這個類。xwork-2.0.4.jar的源代碼Struts2.0.9中并沒有包括,所以要去opensymphony網站下載包,解壓之后,這個類的源代碼文件的路徑就是xwork-2.0.4-srcx

3、work-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就必須實現該接口。接下來通過一個例子來看看如何自己創立一個簡

4、單的Result類型。我們給這個Result的類型取名為“test,通過這個Result類型來告訴Action返回的是何種返回字符串,我們使用一個隨機數來選擇返回的五個類型中的一種。注意:Result接口中的execute()方法沒有返回類型,因為Result就是執行最后的任務,沒有必要再返回其他數據了。而Action接口中的execute()方法返回的是String類型。實現自定義的Result前面已經說過要自定義Result類型,就必須實現Result接口,由于例子比擬簡單,只需要在execute()方法中添加幾行代碼。下面是一個完整的ResultType.java文件,它主要功能就是顯示

5、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 = i

6、nvocation.getResultCode();System.out.println("This time of Result code:"+resultCode);這個自定義的Result文件是在src的目錄下創立的。看上面的代碼很簡單吧!在這個類里面只實現了一個Result接口中的execute()方法。如果有些函數讀者不理解,可以去查看相關文檔。在這里用到的是ActionInvocation這個類,然后調用里面的getResultCode()方法,這個函數返回的是在Action中執行之后所返回的代碼,即前面提到的五種返回字符串類型之一,接下來是一句簡單的輸出語句。

7、當然這只是一個最簡單的自定義Result類型,它不能顯示一個視圖,后面讀者將會看到Struts2集成的Result類型,它們的功能將會十分強大,在下一節讀者將會體會到。其實,Struts2提供的Result類型已經夠平時使用了,如果沒有特殊的要求,沒有必要使用自定義Result類型。知道Result的定義后,下面來看看Action的具體代碼。完整的代碼如下所示:TestAction.Javapackage example.result;import java.util.Random;import com.opensymphony.xwork2.ActionSupport;SuppressWar

8、nings("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(rando

9、m<=80)return NONE;elsereturn INPUT;這個文件和ResultType.java是放在同一個目錄下的。這個Action很簡單,它先通過函數Random().nextInt(100)產生100以內的隨機數,然后再通過比擬來選擇不同返回類型,最后通過ResultType.java在控制臺上顯示出來。配置自己的Result當然只有前面兩個文件是不能運行自定義的Result的,需要做相應的配置才能使用這個Result類型。Result的配置需要用到兩個文件web.xml和xwork.xml。下面是web.xml的完整代碼:web.xml<?xml versio

10、n="1.0" encoding="UTF-8"?><web-app id="WebApp_9" version="2.4" /xml/ns/j2ee" xmlns:xsi=" :/ /2001/XMLSchema-instance" xsi:schemaLocation=" :/java.sun /xml/ns/j2ee :/java.sun /xml/ns/j2ee/web-app_2_4.xsd"> <display-nam

11、e>Struts 2 RESULT</display-name> <filter> <filter-name>struts-cleanup</filter-name> <filter-class> </filter-class> </filter> <filter-mapping> <filter-name>struts-cleanup</filter-name> <url-pattern>/*</url-pattern> </filter

12、-mapping> <filter> <filter-name>struts2</filter-name> <filter-class> </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern></filter-mapping> <welcome-file-list> <w

13、elcome-file>index.html</welcome-file> </welcome-file-list></web-app>想使用自定義的Result就要在struts.xml中進行配置,完整的struts.xml如下所示:struts.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC "-/Apache Software Foundation/DTD Struts Configuration

14、2.0/EN" " ://dtds/struts-2.0.dtd"><struts> <constant name="struts.devMode" value="true" /> <package name="default" extends="struts-default"> <result-types> <result-type name="test" class=&

15、quot;example.result.ResultType" default="true" /> <!- 配置test這個返回類型,同時指定test為默認的返回類型 -> </result-types> <default-interceptor-ref name="completeStack" /> <action name="test" class="example.result.TestAction"> <!- 分別針對五種返回字符串配置返

16、回結果 -> <result name="success" type="test"></result> <result name="error" ></result> <result name="login" ></result> <result name="none" ></result> <result name="input">l</result>

17、; </action> </package></struts>在這里可以看到與配置Action的不同之處,上述代碼中加粗局部的代碼是Action配置沒有的。這里用了一個<result-types>標簽,該標簽用來標志一個Result類型。該標簽有三個屬性,一個是name,一個是class,還有就是default。前兩個是必須的,一個指明這個Result類型的名字,一個指出處理這個Result的類是哪個。最后的default屬性只有兩個值,默認的情況下是false,即說明這個Result類型不是默認的Result類型,使用的時候必須明確指明類型,如

18、<result name="success" type="test"></result>所示;假設自己賦值為true,如上述代碼所示,可以像<result name="error" ></result>這樣使用,無須再指明其返回類型,這也是常用的方式。web.xml,xwork.xml這兩個文件安放的位置跟一般的Action配置是一樣的,最后的目錄結構如圖5-1所示。圖5-1 完整的目錄結構這樣整個自定義的Result就算配置完成了。運行測試Result沒有配置返回頁面,那么要怎么樣才能

19、看到結果和驗證自定義的Result有沒有成功呢?實際上,可以在MyEclipse下面的控制臺視圖中查看運行的結果。我們翻開瀏覽器,輸入 :/localhost:8080/ResultType/test.action,將會出現如圖5-2的畫面。圖5-2 成功的運行界面顯然在瀏覽器中不會有任何顯示,但在MyEclipse的控制臺中會有顯示。多點擊幾次瀏覽器的刷新按鈕,這樣看到的效果會更明顯,如圖5-3所示:圖5-3 控制臺的信息如圖5-3所示,在最下面的五行顯示五種不同的返回類型,這就是這個簡單的Result的功能了。可以看出來,自定義Result是很簡單的,如果結果想要返回一個頁面,就要在定義返

20、回類型的類中增加一個參數定義,在下面將介紹參數的作用。而且還要在配置返回結果的時候加上要返回的頁面,前面所有的例子都是有返回頁面。正如前面所說,根本不需要自己動手去定義Result,Struts2已經定義了許多種返回類型,這些返回類型在日常開發中足夠使用了。這節的目的主要是想通過一個簡單的Result讓讀者明白整個Result的配置以及運行方式,為后面理解Struts2提供的Result類型打下根底,便于以后的學習。5.2常用的Result我們首先了解一下Struts2是在什么地方定義以及配置Result返回類型的。將下載的.zip壓縮包解壓之后,在路徑struts-2.0.9-allstru

21、ts-2.0.9srccoresrcmainresources下有一個struts-default.xml文件,所有的Result類型都是在這里進行配置,在這里能看到對應Result類型的源代碼定義在什么地方。下面是這個文件中關于Result類型配置局部的代碼:struts-default.xml/*省略語句*/ <result-types> <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> <result-type n

22、ame="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/> <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/> <result-type name=" header" class=&quo

23、t;org.apache.struts2.dispatcher. HeaderResult"/> <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/&g

24、t; <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.X

25、SLTResult"/> <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" /> <!- Deprecated name form scheduled for removal in Struts 2.1.0. The camelCase versions are preferred. See ww-1707 -> <result-type name="redirect-action&

26、quot; class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/> <result-type name="plaintext" class="org.apache.struts2.dispatcher.PlainTextResult" /></result-types>/*省略語句*/ 從上面的代碼可以明顯看到,它與自己定義的Result類型配置是完全一樣的。文中粗體表示就是各種Struts2定義的Result類型了,至于具體

27、每個類型表示什么,可以參考表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 整

28、合 Header Result用于控制特殊的 行為Stream Result用于向瀏覽器返回一個InputStream (一般用于文件下載)PlainText Result用于顯示某個頁面的原始的文本 (例如 jsp, html 等)Redirect Action Result用于直接跳轉到另外的actionVelocity Result用于Velocity的整合FreeMarker Result用于FreeMarker的整合JasperReports Result用于JasperReports的整合下面就開始進入探討Result類型之旅了。我們會介紹其中的三種常用Result類型以及其他三種

29、關于視圖的Result類型。 Dispatcher要想真正理解Dispatcher的作用,應該首先通過struts-default.xml找到Dispatcher 對應的類文件,查看其源代碼。在目錄Struts2-.0.9Struts2-src-.0.9comopensymphonyStruts2dispatcher下可以找到一個ServletDispatcherResult.java文件。下面是截取ServletDispatcherResult.java的局部代碼:ServletDispatcherResult.java/*省略語句*/ public class ServletDispatc

30、herResult 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

31、 " + finalLocation); PageContext pageContext = ServletActionContext.getPageContext(); if (pageContext != null) pageContext.include(finalLocation); else ServletRequest request = ServletActionContext.getRequest(); ServletResponse response = ServletActionContext.getResponse(); RequestDispatcher di

32、spatcher = request.getRequestDispatcher(finalLocation); if (dispatcher = null) /給出錯誤的提示信息 response.sendError(404, "result '" + finalLocation + "' not found"); return; if(!response.isCommitted()&&(request.getAttribute("javax.servlet.include.servlet_path")

33、 = 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(

34、)方法,但是在此處并未實現,為什么呢?在上述代碼中的粗體局部可以看到ServletDispatcherResult類是繼承StrutsResultSupport類的,那再分析一下StrutsResultSupport這個類,在與ServletDispatcherResult.java文件相同目錄下可以找到StrutsResultSupport.java文件,其局部代碼如下:StrutsResultSupport.java/*省略語句*/ /這個類實現了Result接口public abstract class Struts2ResultSupport implements Result, St

35、rutsStatics 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(Strin

36、g 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 =

37、 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;看了Struts

38、ResultSupport.java文件,想必大家就很明白為什么ServletDispatcherResult類沒有實現Result接口的execute()方法了。文中粗體所示的局部說明StrutsResultSupport類是一個抽象類,在它里面實現了execute()方法,不過它的實現是調用一個doExecute()方法。在繼承StrutsResultSupport類的時候,只要實現doExecute()方法就能到達對Result接口execute()方法的實現!所以在ServletDispatcherResult.java文件中只有這一個方法。下面來看看Result的參數,就是在配置st

39、ruts.xml文件時<result>標簽對應的參數。在Struts2ResultSupport.java文件中用粗體表示的還有一些代碼:public static final String DEFAULT_PARAM = "location"protected boolean parse ;protected String location;這三句代碼就定義了Dispatcher的兩個參數,各自功能如下:n location (默認):執行后轉到的地方(如jsp頁面)。n parse:這個值在構造函數中已經默認為true。如果設置為false,location

40、參數就不會被解析為Ognl表達式。location對應的就是自己編寫的頁面的地址,如果要返回一個頁面就得擁有這個參數,否那么定義的返回類型就不能返回到指定的頁面。在以后介紹的每一種Result類型的時候,都會有這個DEFAULT_PARAM靜態字符串變量。這個變量指明location是默認的參數,這就讓使用者能夠更方便的使用這種類型。清楚了返回類型怎么實現之后,接下來要考慮如何如在Action中用到它們。首先回憶一下第一個Action的例子,在xwork.xml配置文件里有這些代碼:/*省略語句*/ <include file="struts-default.xml"

41、 />/*省略語句*/ <result name="success">/welcome.jsp</result>/*省略語句*/ 在struts.xml中將struts-default.xml文件包含進來,就是為了可以使用在struts-default.xml中定義的各種Result類型。再看<result>標簽,它只有一個name屬性,沒有type屬性的指定也沒有參數的指定,為什么可以這樣?它怎么知道選擇何種Result類型?原來在struts-default.xml中是這樣定義Dispatcher的:<result-typ

42、e name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>原來已經定義default為true了,而且其他的Result都沒有這個定義。location參數,因為有了默認的DEFAULT_PARAM靜態字符串來表示,所以location參數也可以不需要顯式說明。那么對于上面的Result標簽更完整的配置應該是這樣的<result name="success" type

43、="dispatcher"><param name="location">/welcome.jsp</param></result>至于parse參數,它是一個布爾型的,默認值為true,它是用來解析參數location的,具體的Ognl局部請參看以后的關于表達式語言的章節。弄清楚上述問題之后,現在重點來看ServletDispatcherResult.java中的doExecute()方法,弄清楚它的工作流程。ServletDispatcherResult.java/*省略語句*/ if (log.isDebu

44、gEnabled() log.debug("Forwarding to location " + finalLocation); PageContext pageContext = ServletActionContext.getPageContext(); if (pageContext != null) pageContext.include(finalLocation); else ServletRequest request = ServletActionContext.getRequest(); ServletResponse response = Servlet

45、ActionContext.getResponse(); RequestDispatcher dispatcherrequest.getRequestDispatcher(finalLocation); if (dispatcher = null) /404錯誤代碼對應的錯誤信息的輸出 response.sendError(404, "result '" + finalLocation + "' not found"); return; if(!response.isCommitted()&&(request.getAtt

46、ribute("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, respons

47、e); 上面是doExecute()方法的具體實現,可以從粗體局部看出這個Result有三種執行方式:n 如果在一個JSP的范圍內(PageContext對象可用),PageContext的include(String)方法會被調用。n 如果沒有PageContext對象,并且也不在任何形式的include中(在request的屬性中沒有"javax.servlet.include.servlet_path"),那么調用RequestDispatcher的forward方法。n 否那么調用RequestDispatcher的include方法。還可以看到,如果dispatc

48、her=null的話,會返回404代碼錯誤。所以以后在使用Dispatcher的時候遇到404錯誤的時候,就應該知道是返回對應的頁面地址或者Action找不到的問題。至于具體的類的含義以及方法是干什么的,讀者可以自己去查閱servlet的API文檔。這就是整個Dispatcher Result的流程了。下面用一個流程圖來概括一下,如圖5-4所示。圖5-4 Dispatcher Result的流程這一節因為是第一次講解Struts2定義的Result類型,所以內容比擬多。這個小節對源代碼進行了探討,介紹了參數,執行方式等內容,讓讀者完全理解Dispatcher Result。后面因為有了這節的根

49、底,Result的講解將比擬簡單了。 RedirectRedirect,即重定向,Action如果配置這種返回類型,那么就可以有三種不同的返回效果,分別是返回到頁面、連接到另一個Action、還可以連接到一個網址。有了前面Dispatcher Result的根底,Redirect Result理解起來就比擬容易了。讓我們看看Redirect Result的源代碼是如何實現的。首先看Redirect在struts-default.xml中的配置:<result-type name="redirect" class="org.apache.struts2.dis

50、patcher.ServletRedirectResult"/>這就是Redirect在struts-default.xml中的配置,與Dispatcher的不同就是沒有default屬性,通過上一小節可以知道,Redirect并不是默認的,使用的時候必須指明類型屬性type=redirect。在ServletDispatcherResult.java文件路徑下可以找到ServletRedirectResult.java文件,其代碼如下:ServletRedirectResult.java/*省略語句*/ public class ServletRedirectResult e

51、xtends StrutsResultSupport private static final Log log = LogFactory.getLog(ServletRedirectResult.class);/*省略局部代碼*/ protected boolean prependServletContext = true; public void setPrependServletContext(boolean prependServletContext) this.prependServletContext = prependServletContext; protected void d

52、oExecute(String finalLocation, ActionInvocation invocation) throws Exception /*省略語句*/ response.sendRedirect(finalLocation); /*省略語句*/ 在這里只是簡單的截取一些代碼片斷,粗體局部顯示了它和Dispatcher一樣都是繼承StrutsResultSupport類的,都實現了doExecute()方法。有興趣的讀者可以把這段完整的源代碼找出來研究一下,在這里就不再贅訴了。同樣,Redirect也有自己的參數。n location(默認):action執行后跳轉的地址。n

53、 parse:這個值在構造函數中已經默認為true。如果設置為false,location參數不會被當作Ognl表達式解析。參數和Dispatcher是一樣的,不過這里的location可以是一般的JSP頁面,可以是一個Action,還可以是一個其他的網址譬如: :/ 。這就是Redirect被稱為重定向的原因,可以定向到不同的方式。下面通過一個簡單的例子來了解一下Redirect。在一個工程里面定義三個Action,他們的Result的類型都是redirect,但是他們重定向的對象不同,一個為一般的JSP頁面,一個為Action,一個是一個網址URL。可以把本書一開始創立

54、的第一個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

55、()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 name) = name;pub

56、lic String getName()return name;這就是第二章實現的第一個Action helloworld。下面是添加的兩個Action:OtherTest.javapackage example;import com.opensymphony.xwork2.ActionSupport;public class OtherTest extends ActionSupportpublic String execute()return SUCCESS;Test.javapackage example;import com.opensymphony.xwork2.ActionSupp

57、ort;public class Test extends ActionSupportpublic String execute()return SUCCESS;這兩個Action的execute()方法只是返回SUCCESS,通過這三個Action來試驗一下Redirect這種返回類型的三種不同返回形式。最后再看struts.xml的配置代碼:struts.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC "-/Apache Software F

58、oundation/DTD Struts Configuration 2.0/EN" " ://dtds/struts-2.0.dtd"><struts> <constant name="struts.devMode" value="true" /> <package name="default" extends="struts-default"><action name="helloworld" class="example.helloworld"><interceptor-ref name="completeStack" /> <!-返回到自定義的頁面-><result name="success" type="redirect"&g

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論