......
Struts和Webwork同為服務於Web的一種MVC框架,從某種程度上看,Struts2是從WebWork2上升級得到的。甚至Apache的官方文檔也講:WebWork2到Struts2是平滑的過渡。我們甚至也可以說Struts2就是WebWork2.3而已。在很多方面Struts僅僅是改變了WebWork下的名稱。Struts2對應的有自己的標籤,並且功能強大。Webwork也有自己的標籤。在2005年12月,WebWork與Struts Ti決定合併,在此同時, Struts Ti 改名為 Struts Action Framework 2.0,成為Struts真正的下一代。
ActionSupport基類中定義了五個標準的返回值,當然我們可以自己隨意定義返回的名字
String SUCCESS = "success"; //默認是 SUCCESS 類型
String NONE = "none";
String ERROR = "error";
String INPUT = "input";
String LOGIN = "login";
ActionSupport基類定義了了一些方法,程序員自己寫的action如果繼承了ActionSupport基類,就可以應用這些方法,很方便解決一些問題。
一些比較常用的方法:
getText(String aTextName);//國際化用到
...//getText(String aTextName)的重載方法
addActionMessage(String aMessage);
addFieldError(String fieldName, String errorMessage);
//校驗失敗后返回給客戶端的信息,struts2 標籤可以取得
addActionError(String anErrorMessage);
在默認時,標籤的type屬性值是“dispatcher”(實際上就是轉發,forward)。開發人員可以根據自己的需要指定不同的類型,如redirect、stream等。如下面代碼所示:
/result.jsp
這此result-type可以在struts2-core-2.0.11.1.jar包或struts2源代碼中的struts-default.xml文件中找到,在這個文件中找到標籤,所有的result-type都在裡面定義了。代碼如下:
dispatcher
用來轉向頁面,通常處理JSP
1 | org.apache.struts2.dispatcher.ServletDispatcherResult |
freemarker
處理FreeMarker模板
1 | org.apache.struts2.views.freemarker.FreemarkerResult |
httpheader
控制特殊HTTP行為的結果類型
1 | org.apache.struts2.dispatcher.HttpHeaderResult |
stream
向瀏覽器發送InputStream對象,通常用來處理文件下載,還可用於返回
AJAX數據
1 | org.apache.struts2.dispatcher.StreamResult |
StreamResult等價於在Servlet中直接輸出Stream流。這種Result被經常使用於輸出圖片、文檔等
二進位流到 客戶端。通過使用StreamResult,我們只需要在Action中準備好需要輸出的InputStream即可。
配置:
同時,StreamResult支持許多參數,對輸出的Stream流進行參數控制。
velocity
處理Velocity模板
1 | org.apache.struts2.dispatcher.VelocityResult |
隨著模板技術的越來越流行,使用
Freemarker或者Velocity模板進行View層展示的開發者越來越多。Struts2同樣為模板作為Result做出了支持。由於模板的顯示需要模板(Template)與數據(Model)的緊密配合,所以在Struts2中,這兩個Result的主要工作是為模板準備數據。
xslt
處理XML/XLST模板
1 | org.apache.struts2.views.xslt.XSLTResult |
plainText
顯示原始文件內容,例如文件源代碼
1 | org.apache.struts2.dispatcher.PlainTextResult |
chain
用來處理Action鏈
1 | com.opensymphony.xwork2.ActionChainResult |
chain其實只是在一個action執行完畢之後,forward到另外一個action,所以他們之間是共享HttpServletRequest的。在使用chain作為Result時,往往會配合使用ChainingInterceptor。ChainingInterceptor的作用是在Action直接傳遞數據。事實上,源Action中ValueStack的數據會被做一次Copy,這樣,2個Action中的數據都在ValueStack中,使得對於前台來說,通過ValueStack來取數據,是透明而共享的。比如說,一張頁面中,你可能有許多數據要顯示,而某些數據的獲取方式可能被很多不同的頁面共享(典型來說,“推薦文章”這個小欄目的數據獲取,可能會被很多頁面所共享)。這種情況下,可以把這部分邏輯抽取到一個獨立Action中,並使用chain,將這個Action與主Action串聯起來。這樣,最後到達頁面的時候,頁面始終可以得到每個Action中的數據。
從實戰上講,使用chain作為Result也的確存在著上面所說的許多問題,我個人也是非常不推崇濫用這種Result。尤其是,對於使用Spring和
Hibernate的朋友來說,如果你開啟OpenSessionInView模式,那麼Hibernate的session是跟隨HttpServletRequest的,所以session在整個action鏈中共享。這會為我們的編程帶來極大的麻煩。因為我們知道Hibernate的session會保留一份一級緩存,在action鏈中,共享一級緩存無疑會為你的調試工作帶來很大的不方便。
所以,謹慎使用chain作為你的Result,應該成為一條最佳實踐。
redirect
重定向到一個URL
1 | org.apache.struts2.dispatcher.ServletRedirectResult |
如果你在Action執行完畢后,希望執行另一個Action,有2種方式可供選擇。一種是forward,另外一種是redirect。有關forward和redirect的區別,這裡我就不再展開,這應該屬於Java程序員的基本知識。在Struts2中,分別對應這兩種方式的Result,就是chain和redirect。
先來談談redirect,既然是重定向,那麼源地址與目標地址之間是2個不同的HttpServletRequest。所以目標地址將無法通過ValueStack等Struts2的特性來獲取源Action中的數據。
同時,Redirect的Result支持在配置文件中,讀取並解析源Action中ValueStack的值,並成為參數傳遞到Redirect的地址中。
redirectAction
重定向到一個Action
1 | org.apache.struts2.dispatcher.ServletActionRedirectResult |
redirect和redirectAction chain的區別
struts2中關於result的返回類型一般我們是轉發到一個jsp頁面或者是html頁面等,但是struts2中的result的返回類型還有redirect,redirectAction,chain。對於這三種返回類型之間肯定是有區別的,下面我們來看看關於redirect redirectAction chain這三種struts2的返回類型之間的區別。當使用type=“redirectAction”或type=“redirect”提交到一個action並且需要傳遞一個參數時。這裡是有區別的:使用type=“redirectAction”時,結果就只能寫Action的配置名,不能帶有後綴:“.action”
Xml代碼
1 2 3 | User?u_id=${loginBean.u_id} |
使用type=“redirect”時,結果應是action配置名+後綴名
Xml代碼
1 2 3 | User.action?u_id=${loginBean.u_id} |
redirect:action處理完后重定向到一個視圖資源(如:jsp頁面),請求參數全部丟失,action處理結果也全部丟失。
redirect-action:action處理完后重定向到一個action,請求參數全部丟失,action處理結果也全部丟失。
chain:action處理完後轉發到一個action,請求參數全部丟失,action處理結果不會丟失。
曝出高危安全漏洞
Struts2曝出2個高危安全漏洞,一個是使用縮寫的導航參數前綴時的遠程代碼執行漏洞,另一個是使用縮寫的重定向參數前綴時的開放式重定向漏洞。這些漏洞可使黑客取得網站伺服器的“最高許可權”,從而使企業伺服器變成黑客手中的“肉雞”。
解決措施
Apache Struts團隊已發布了最新的Struts 2.3.15.1,修復了上述漏洞,建議採用Struts 2.0至Struts 2.3的網站開發者儘快升級至最新版。
帶來影響
據烏雲平台漏洞報告,淘寶、京東、騰訊等大型網際網路廠商均受此影響,而且漏洞利用代碼已經被強化,可直接通過瀏覽器的提交對伺服器進行任意操作並獲取敏感內容。Struts漏洞影響巨大,受影響站點以電商、銀行、門戶、政府居多,而且一些自動化、傻瓜化的利用工具開始出現,填入地址可直接執行伺服器命令,讀取數據甚至直接關機等操作。
瑞星安全專家介紹,本次曝出的2個漏洞是由於縮寫的導航和重定向前綴“action:”、 “redirect:”、 “redirectAction:”造成的。瑞星安全專家表示,由於這些參數前綴的內容沒有被正確過濾,導致黑客可以通過漏洞執行命令,獲取目標伺服器的信息,並進一步取得伺服器最高控制權。屆時,被攻擊網站的資料庫將面臨全面泄密的威脅,同時黑客還可以通過重定向漏洞的手段,對其他網民進行釣魚攻擊或掛馬攻擊。