Struts2------Result處理&獲取頁面請求參數&API ...
一、Result處理
1.1 說明
平常我們設置跳轉頁面,是在action標簽裡面加上 result標簽來控制,這種設置的頁面跳轉,稱之為 局部結果頁面;但是我們有時候在很多個action裡面,針對不同的結果進行跳轉時,也有可能跳轉同一個頁面,那麼這個時候就可以配置全局結果頁面。
1.2 局部結果配置eg
<action name="demo01_*" class="com.gaga.web.action.ActionDemo01" method="{1}">
<result name="error">/error.jsp</result>
</action>
1.3 全局結果配置eg(同一個包下)
<package name="test" extends="struts-default" namespace="/"> <global-results> <result name="error">/error.jsp</result> </global-results> .... </package>
1.4 全局結果配置eg(不同的包下)
<!--把全局的結果抽取到父包裡面 --> <package name="base" extends="struts-default" abstract="true"> <global-results> <!--全局的結果: 配置在package裡面的 特點:可以被當前包裡面所有的Action共用; 使用場景:不同的Action需要跳轉到相同的結果的時候eg: 錯誤頁面, msg頁面等 --> <result name="error">/msg.jsp</result> </global-results> </package> <package name="test" extends="base" namespace="/"> <action name="demo01_fun01" class="com.gaga.web.ActionDemo01" method="fun01"> </action> <action name="demo02_fun02" class="com.gaga.web.ActionDemo02" method="fun02"> </action> </package>
1.5 結果的類型
伺服器響應給瀏覽器的時候,有三種類型:response響應JSON數據&請求轉發 & 重定向。 對於Struts2而言,無非就是Action跳轉(轉發重定向)到頁面,Action跳轉到Action....
1.5.1 Action跳轉頁面
轉發(預設)
<result name="success" type="dispatcher">/index.jsp</result>
重定向
<result name="success" type="redirect">/index.jsp</result>
1.5.2 Action跳轉Action
轉發
<action name="demo01_*" class="com.gaga.web.action.ActionDemo01" method="{1}"> <result name="success" type="chain">demo02_fun02</result> </action> <action name="demo02_*" class="com.gaga.web.action.ActionDemo02" method="{1}"> </action>
重定向
<action name="demo01_*" class="com.gaga.web.action.ActionDemo01" method="{1}"> <result name="success" type="redirectAction">demo02_fun02</result> </action> <action name="demo02_*" class="com.gaga.web.action.ActionDemo02" method="{1}"> </action>
1.5.4 其它的結果(用得不多)
比如: 我們可以返回一個文件數據給客戶端 (比如文件下載).再比如: 我們可以返回一個json字元串給來請求的頁面,而不是重新打開新的頁面 (有點像之前的Ajax請求,返回json數據)
1.5.4.1 響應JSON數據
- java代碼
public class ActionDemo01 extends ActionSupport { private User json; public User getJson() { return json; } public String fun01(){ json = new User(); json.setName("張三"); json.setAge(18); json.setPassword("123456"); return "success"; } }
- 配置文件
<struts> <package name="test" extends="json-default" namespace="/"> <action name="demo01" class="com.itheima.web.action.ActionDemo01" method="fun01"> <result name="success" type="json"> <param name="root">json</param><!--這裡的name必須是root 至於這個json 是我們在action裡面的成員 變數 json(屬性) --> </result> </action> </package> </struts>
備註:
package需要繼承json-default
result的type值是json
param標簽中的內容必須為Action類中的Javabean屬性,該例子中,由於拿取User對象json的方法為getJson(),把get去掉,J變為小寫,即為json,那麼就有了<param name="root">json</param>
1.5.4.2 響應流(文件下載)
- java代碼
public class ActionDemo01 extends ActionSupport { private InputStream stream; public void setStream(InputStream stream) { this.stream = stream; } public InputStream getStream() { return stream; } public String fun01() throws Exception{ System.out.println("demo01 執行了..."); stream = new FileInputStream("E:/data/Desktop/a.jpg"); return "success"; } }
- 配置文件
<struts> <package name="test" extends="struts-default" namespace="/"> <action name="demo01" class="com.itheima.web.action.ActionDemo01" method="fun01"> <result name="success" type="stream"> <param name="contentType">image/jpeg</param> <param name="inputName">stream</param> <param name="contentDisposition">attachment;filename="b.jpg"</param> <param name="bufferSize">1024</param> </result> </action> </package> </struts>
說明
contentDisposition:下載到客戶端時,客戶端文件名稱
bufferSize:讀文件的緩存大小
inputName:對應要輸出到客戶端流聲明的名稱,也就是說需要和Action裡面聲明的變數名要一致
二、利用Struts2獲取頁面參數
1. 獲取零散數據(即封裝前的數據)
1.1 利用Struts2中的API
- 利用ActionContext(Action中的上下文)
//1.創建ActionContext對象 ActionContext context = ActionContext.getContext(); //2.獲得所有的請求參數 Map<String, Object> parameters = context.getParamters();
- 利用ServletActionContext
//1.獲得request對象 HttpServletRequest request = ServletActionContext.getRequest();
//獲取具體參數 requet.getParameter(String key); requet.getParameterValues(String key); requet.getParameterMap();
1.2 利用屬性驅動
- 頁面
<h1>01使用屬性驅動</h1> <form method="post" action="${pageContext.request.contextPath }/demo01"> 用戶名:<input type="text" name="username"/><br/> 密 碼:<input type="password" name="password"/><br/> <input type="submit"/> </form>
- Action.java
public class ActionDemo01 extends ActionSupport { private String username;//和表單裡面的name屬性值要一致,並且提供set方法 private String password;//和表單裡面的name屬性值要一致,並且提供set方法 public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public String fun01(){ System.out.println(username+":"+password); return NONE; } }
2. 直接獲取封裝後的數據(即直接獲取對象)
2.1 屬性驅動
- 頁面
<h1>01使用屬性驅動方式</h1> <form method="post" action="${pageContext.request.contextPath }/demo01"> 用戶名:<input type="text" name="user.username"/><br/> 密 碼:<input type="password" name="user.password"/><br/> <input type="submit"/> </form>
- Action類
public class ActionDemo01 extends ActionSupport { //1. User類裡面的欄位屬性需要和表單裡面的name屬性一致, 且提供無參構造 //2. user需要set和get方法 private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String fun01(){ System.out.println(user.toString()); return NONE; } }
2.2 模型驅動
- 頁面
<h1>02使用模型驅動方式</h1> <form method="post" action="${pageContext.request.contextPath }/demo02"> 用戶名:<input type="text" name="username"/><br/> 密 碼:<input type="password" name="password"/><br/> <input type="submit"/> </form>
- Action類
public class ActionDemo02 extends ActionSupport implements ModelDriven<User> { private User user; public String fun02(){ System.out.println(user.toString()); return NONE; } @Override public User getModel() { if(user == null){ user = new User(); } return user; } }
經驗:實際開發中,
如果要獲得單個(零散)的數據,我們通常用屬性驅動
如果要獲得封裝後的數據, 我們通常用模型驅動
2.3 封裝到List集合(用得不多)
- 頁面
<h1>01封裝到list</h1> <form method="post" action="${pageContext.request.contextPath }/demo01"> 用戶名:<input type="text" name="list[0].username"/><br/> 密 碼:<input type="password" name="list[0].password"/><br/> 用戶名:<input type="text" name="list[1].username"/><br/> 密 碼:<input type="password" name="list[1].password"/><br/> <input type="submit"/> </form>
- Action類
public class ActionDemo01 extends ActionSupport { private List<User> list; public List<User> getList() { return list; } public void setList(List<User> list) { this.list = list; } public String fun01(){ System.out.println(list.toString()); return NONE; } }
2.4 封裝到Map中
- 頁面
<h1>02封裝到map</h1> <form method="post" action="${pageContext.request.contextPath }/demo02"> 用戶名:<input type="text" name="map['user1'].username"/><br/> 密 碼:<input type="password" name="map['user1'].password"/><br/> 用戶名:<input type="text" name="map['user2'].username"/><br/> 密 碼:<input type="password" name="map['user2'].password"/><br/> <input type="submit"/> </form>
- Action類
public class ActionDemo02 extends ActionSupport { private Map<String, User> map; public Map<String, User> getMap() { return map; } public void setMap(Map<String, User> map) { this.map = map; } public String fun02(){ Set<Entry<String, User>> entrySet = map.entrySet(); for (Entry<String, User> entry : entrySet) { System.out.println(entry.getKey()+":"+entry.getValue().toString()); } return NONE; }
三、補充:Struts2中的API訪問
3.1 用ActionContext
ActionContext是Action的上下文,Struts2自動在其中保存了一些在Action執行過程中所需的對象,比如session, parameters等。Struts2會根據每個執行HTTP請求的線程來創建對應的ActionContext,即一個線程有一個唯一的ActionContext。
- 創建對象
ActionContext context = ActionContext.getContext();
- 獲取請求參數
Map<String, Object> parameters = context.getParamters();
3.2 用ServletActionContext
ServletActionContext繼承ActionContext,因此比ActionContext功能要強大。ServletActionContext提供了多個靜態方法。
//獲得Request對象 HttpServletRequest request = ServletActionContext.getRequest(); //獲得Response對象 HttpServletResponse response = ServletActionContext.getResponse(); //獲得ServletContext ServletContext servletContext = ServletActionContext.getServletContext();
3.3 通過實現介面
有如下介面可選
ServletRequestAware
ServletResponseAware
SessionAware
ApplicationAware
eg:
public class ActionDemo03 extends ActionSupport implements ServletRequestAware { private HttpServletRequest request; public String fun03() throws IOException{ HttpServletRequest request = ServletActionContext.getRequest(); String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println(username+":"+password); return NONE; } @Override public void setServletRequest(HttpServletRequest request) { this.request = request; } }