4.處理結果
Struts2的Action處理完用戶請求後,將返回一個普通字符串,整個普通字符串就是一個邏輯視圖名。Struts2通過配置邏輯視圖名和物理視圖資源之間的映射關係,一旦系統收到Action返回的某個邏輯視圖名,系統就會把對應的物理視圖資源呈現給瀏覽者。
4.1.配置處理結果:
Struts2的Action處理用戶請求結束後,返回一個普通字符串-邏輯視圖名,必須在struts.xml文件中完成邏輯視圖和物理視圖資源的映射,纔可讓系統轉到實際的視圖資源。
Struts2通過在struts.xml文件中使用<result …/>元素來配置結果。Struts2提供了兩種結果。
l 局部結果:將<result …/>作爲<action …>元素的子元素配置。
l 全局結果:將<result …/>作爲<global-results …>元素的子元素配置。
在package元素中配置<global-results>子元素:
<global-results> <result name="error">/Error.jsp</result> <result name="invalid.token">/Error.jsp</result> <result name="login" type="redirect-action">Logon!input</result> </global-results> |
4.2.處理結果類型:
Struts2提供了對不同種類返回結果的支持,常見的有JSP,FreeMarker,Velocity等。
Struts2支持的不同類型的返回結果爲:
名字 | 說明 |
chain | 用來處理Action鏈 |
dispatcher | 用來轉向頁面,通常處理JSP,這是默認的結果類型 |
freeMarker | 處理FreeMarker模板 |
httpHeader | 用來控制特殊的Http行爲 |
redirect | 重定向到一個URL |
redirect-action | 重定向到一個Action |
stream | 向瀏覽器發送InputSream對象,通常用來處理文件下載 |
velocity | 處理Velocity模板 |
xslt | 處理XML/XLST模板 |
plaintext | 顯示原始文件內容,例如文件源代碼 |
tiles | 結合Tile使用 |
另外第三方的Result類型還包括JasperReports Plugin,專門用來處理JasperReport類型的報表輸出;Jfreechart Plugin;JSF Plugin。
4.3.動態返回結果
有些時候,只有當Action執行完畢的時候我們才知道要返回哪個結果,這個時候我們可以在Action內部定義一個屬性,這個屬性用來存儲Action執行完畢之後的result值,例如:
private String nextAction; public String getNextAction() { return nextAction; } |
在strutx.xml配置文件中,我們可以使用${nextAction}來引用到Action中的屬性,通過${nextAction}表示的內容來動態的返回結果,例如:
<action name="fragment" class="FragmentAction"> <result name="next" type="redirect-action">${nextAction}</result> </action> |
上述Action的execute方法返回next的時候,還需要根據nextAction的屬性來判斷具體定位到哪個Action。
5.屬性驅動和模型驅動
不管屬性驅動還是模型驅動,Struts2框架都是通過攔截器負責提取請求參數,並將請求數據封裝到相應的Action實例的屬性或專門的模型的屬性。
5.1.屬性驅動:
屬性驅動就是屬性(property)作爲貫穿MVC流程的信息攜帶者。簡單的說,就是使用Action實例來封裝請求參數和處理結果信息。前面我們做的示例都屬於屬性驅動模式。
5.2.模型驅動:
模型驅動就是使用單獨的javaBean作爲貫穿整個MVC流程的信息攜帶者。也就是說,使用單獨的VO(值對象)來封裝請求參數和處理結果信息。
示例:繼續修改用戶登錄驗證:
1.新增一用戶域模型對象:User.java
package org.qiujy.domain; publicclass User { private String userName; private String password; /** *@returntheuserName */ public String getUserName() { returnuserName; } /** *@paramuserNametheuserNametoset */ publicvoid setUserName(String userName) { this.userName = userName; } /** *@returnthepassword */ public String getPassword() { returnpassword; } /** *@parampasswordthepasswordtoset */ publicvoid setPassword(String password) { this.password = password; } } |
2.業務控制器:UserAction.java
package org.qiujy.web.struts2.action; import org.qiujy.domain.User; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; publicclass UserAction extends ActionSupport{ //定義用於封裝請求參數的模型對象 private User user = new User(); private String msg; //結果信息屬性 /** *@returntheuser */ public User getUser() { returnuser; } /** *@paramusertheusertoset */ publicvoid setUser(User user) { this.user = user; } /** *@returnthemsg */ public String getMsg() { returnmsg; } /** *@parammsgthemsgtoset */ publicvoid setMsg(String msg) { this.msg = msg; } /** *處理用戶請求的login()方法 *@return結果導航字符串 *@throwsException */ public String login() throws Exception{ String userName = user.getUserName(); String password = user.getPassword(); if("test".equals(userName) && "test".equals(password)){ msg = "登錄成功,歡迎" + userName; //獲取ActionContext實例,通過它來訪問Servlet API ActionContext context = ActionContext.getContext(); //看session中是否已經存放了用戶名,如果存放了:說明已經登錄了;否則說明是第一次登錄成功 if(null != context.getSession().get("uName")){ msg = userName + ":你已經登錄過了!!!"; }else{ context.getSession().put("uName", userName); } returnthis.SUCCESS; }else{ msg = "登錄失敗,用戶名或密碼錯"; returnthis.ERROR; } } public String regist() throws Exception{ //將用戶名,密碼添加到數據庫中 //... msg = "註冊成功。"; returnthis.SUCCESS; } } |
3.配置文件:struts.xml
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="my" extends="struts-default" namespace="/manage"> <action name="userOpt" class="org.qiujy.web.struts2.action.UserAction"> <result name="success">/success.jsp</result> <result name="error">/error.jsp</result> </action> </package> </struts> |
4.頁面:
index.jsp
<%@ page language="java" pageEncoding="UTF-8"%> <html> <head> <title>用戶登錄頁面</title> </head> <body> <h2>用戶入口</h2> <hr> <form action="manage/userOpt!login.action" method="post"> <table border="1"> <tr> <td>用戶名:</td> <td><input type="text" name="user.userName"/></td> </tr> <tr> <td>密碼:</td> <td><input type="password" name="user.password"/></td> </tr> <tr> <td colspan="2"> <input type="submit" value=" 確定 "/> </td> </tr> </table> </form> </body> </html> |
其它頁面略。
5.運行效果:同以前一樣。
6.源代碼:
6.Struts2的異常處理機制:
任何成熟的MVC框架都應該提供成就的異常處理機制。Strut2也不例外。Struts2提供了一種聲明式的異常處理方式。Struts2也是通過配置的攔截器來實現異常處理機制的。
Struts2的異常處理機制通過在struts.xml文件中配置<exception-mapping …>元素完成的,配置該元素時,需要指定兩個屬性:
exception:此屬性指定該異常映射所設置的異常類型。
result:此屬性指定Action出現該異常時,系統轉入result屬性所指向的結果。
6.1.異常映射也分爲兩種:
l 局部異常映射:<exception-mapping…>元素作爲<action…>元素的子元素配置。
l 全局異常映射:<exception-mapping…>元素作爲<global-exception-mappings>元素的子元素配置。
6.2.輸出異常信息:
使用Struts2的標籤來輸出異常信息:
l <s:property value="exception.message"/> : 輸出異常對象本身。
l <s:property value="exceptionStack"/> : 輸出異常堆棧信息。
6.3.示例:
還是修改用戶登錄示例:
1)把UserAciton.java中的regist方法改成:
public String regist() throws Exception{ //將用戶名,密碼添加到數據庫中 //... //msg = "註冊成功。"; if(true){ throw new java.sql.SQLException("沒有數據庫驅動程序"); } return this.SUCCESS; } |
2)修改struts.xml文件:
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="my" extends="struts-default" namespace="/manage"> <!-- 定義全局處理結果 --> <global-results> <!-- 邏輯名爲sql的結果,映射到/exception.jsp頁面 --> <result name="sql">/exception.jsp</result> </global-results> <global-exception-mappings> <!-- 當Action拋出SQLException異常時,轉入名爲sql的結果 --> <exception-mapping exception="java.sql.SQLException" result="sql"/> </global-exception-mappings> <action name="userOpt" class="org.qiujy.web.struts2.action.UserAction"> <result name="success">/success.jsp</result> <result name="error">/error.jsp</result> </action> </package> </struts> |
3)新增一頁面:exception.jsp
<%@ page language="java" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <html> <head> <title>異常信息</title> </head> <body> <h2> 出現異常啦 </h2> <hr/> <h3 style="color:red"> <!-- 獲得異常對象 --> <s:property value="exception.message"/> </h3> <br/> <!-- 異常堆棧信息 --> <s:property value="exceptionStack"/> </html> |
4)運行regist.jsp進行調試: