轉自:http://blog.sina.com.cn/s/blog_6c9bac050100y9iw.html
在Web應用程序開發中,除了將請求參數自動設置到Action的字段中,我們往往也需要在Action里直接獲取請求(Request)或會話 (Session)的一些信息, 甚至需要直接對JavaServlet Http的請求(HttpServletRequest),響應(HttpServletResponse)操作。
我們需要在Action中取得request請求參數"username"的值:
ActionContext context = ActionContext.getContext(); Map params = context.getParameters(); String username = (String) params.get("username");
ActionContext(com.opensymphony.xwork.ActionContext)是Action執行時的上下文,上下文可以看作是一個容器(其實我們這里的容器就是一個Map而已),它存放放的是Action在執行時需要用到的對象
一般情況,我們的ActionContext都是通過:ActionContext context = (ActionContext) actionContext.get();來獲取的.
我們再來看看這里的actionContext對象的創建:
static ThreadLocal actionContext = new ActionContextThreadLocal();
ActionContextThreadLocal是實現ThreadLocal的一個內部類.ThreadLocal可以命名為"線程局部變量",它為每一個使用該變量的線程都提供一個變量值的副本,使每一個線程都可以獨立地改變自己的副本, 而不會和其它線程的副本沖突.這樣,我們ActionContext里的屬性只會在對應的當前請求線程中可見,從而保證它是線程安全的.
下面我們看看怎么通過ActionContext取得我們的HttpSession:
Map session = ActionContext.getContext().getSession();
再看看怎么通過ServletActionContext取得我們的HttpSession:
ServletActionContext(com.opensymphony.webwork. ServletActionContext),這個類直接繼承了我們上面介紹的ActionContext,它提供了直接與JavaServlet相關對象訪問的功能,它可以取得的對象有:
1, javax.servlet.http.HttpServletRequest:HTTPservlet請求對象
2, javax.servlet.http.HttpServletResponse;:HTTPservlet相應對象
3, javax.servlet.ServletContext:Servlet 上下文信息
4, javax.servlet.ServletConfig:Servlet配置對象
5, javax.servlet.jsp.PageContext:Http頁面上下文
下面我們看看幾個簡單的例子,讓我們了解如何從ServletActionContext里取得JavaServlet的相關對象:
1, 取得HttpServletRequest對象:
HttpServletRequest request = ServletActionContext. getRequest();
2, 取得HttpSession對象:
HttpSession session = ServletActionContext. getRequest().getSession();
ServletActionContext 和ActionContext有着一些重復的功能,在我們的Action中,該如何去抉擇呢?
我們遵循的原則是:
(1)如果ActionContext能夠實現我們的功能,那最好就不要使用ServletActionContext,讓我們的Action盡量不要直接去訪問JavaServlet的相關對象.
(2)在使用ActionContext時有一點要注意:不要在Action的構造函數里使用ActionContext.getContext(),因為這個時候ActionContext里的一些值也許沒有設置,這時通過ActionContext取得的值也許是null.
如果我要取得Servlet API中的一些對象,如request,response或session等,應該怎么做?
在Strutx 2.0你可以有兩種方式獲得這些對象:非IoC方式和IoC(控制反轉Inversion of Control)方式.
A、非IoC方式
要獲得上述對象,關鍵Struts 2.0中com.opensymphony.xwork2.ActionContext類.我們可以通過它的靜態方法getContext()獲取當前 Action的上下文對象. 另外,org.apache.struts2.ServletActionContext作為輔助類(Helper Class),可以幫助您快捷地獲得這幾個對象.
HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); HttpSession session = request.getSession();
例6 classes/tutorial/NonIoCServlet.java
1 package tutorial;
2
3 import javax.servlet.http.HttpServletRequest; 4 5 import javax.servlet.http.HttpServletResponse; 6 7 import javax.servlet.http.HttpSession; 8 9 import org.apache.struts2.ServletActionContext; 10 11 import com.opensymphony.xwork2.ActionContext; 12 13 import com.opensymphony.xwork2.ActionSupport; 14 15 Public class NonIoCServletextends ActionSupport { 16 17 private String message; 18 19 20 21 public String getMessage() { 22 23 return message; 24 25 } 26 27 HttpServletRequest request = ServletActionContext.getRequest(); 28 29 HttpServletResponse response = ServletActionContext.getResponse(); 30 31 HttpSession session = request.getSession(); 32 33 34 35 @Override 36 37 public String execute() { 38 39 ActionContext.getContext().getSession().put("msg", "Hello World from Session!");[A2] 40 41 42 43 StringBuffer sb =new StringBuffer("Message from request: "); 44 45 sb.append(request.getParameter("msg")); 46 47 48 49 sb.append("<br>Response Buffer Size: "); 50 51 sb.append(response.getBufferSize()); 52 53 54 55 sb.append("<br>Session ID: "); 56 57 sb.append(session.getId());[A3] 58 59 60 61 message = sb.toString(); //轉換為字符串。 62 63 return SUCCESS; 64 65 } 66 67 } //與LoginAction類似的方法。
如果你只是想訪問session的屬性(Attribute),你也可以通過ActionContext.getContext().getSession()獲取或添加session范圍(Scoped)的對象.[A1]
B、IoC方式
要使用IoC方式,我們首先要告訴IoC容器(Container)想取得某個對象的意願,通過實現相應的接口做到這點.具體實現,請參考例6 IocServlet.java.
例6 classes/tutorial/IoCServlet.java
1 package tutorial; 2 3 import java.util.Map; 4 5 import javax.servlet.http.HttpServletRequest; 6 7 import javax.servlet.http.HttpServletResponse; 8 9 import javax.servlet.http.HttpSession; 10 11 import org.apache.struts2.interceptor.ServletRequestAware; 12 13 import org.apache.struts2.interceptor.ServletResponseAware; 14 15 import org.apache.struts2.interceptor.SessionAware; 16 17 import com.opensymphony.xwork2.ActionContext; 18 19 import com.opensymphony.xwork2.ActionSupport; 20 21 public class IoCServlet extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware { 22 23 private String message; 24 25 private Map att; 26 27 private HttpServletRequest request; 28 29 private HttpServletResponse response; 30 31 32 33 public String getMessage() { 34 35 return message; 36 37 } 38 39 public void setSession(Map att) { 40 41 this.att = att; 42 43 }[A5] 44 45 publicvoid setServletRequest(HttpServletRequest request) { 46 47 this.request = request; 48 49 } 50 51 publicvoid setServletResponse(HttpServletResponse response) { 52 53 this.response = response; 54 55 }[A5] 56 57 58 59 @Override 60 61 public String execute() { 62 63 att [A6] .put("msg", "Hello World from Session!"); 64 65 66 67 HttpSession session = request.getSession(); 68 69 70 71 StringBuffer sb =new StringBuffer("Message from request: "); 72 73 sb.append(request.getParameter("msg")); 74 75 sb.append("<br>Response Buffer Size: "); 76 77 sb.append(response.getBufferSize()); 78 79 sb.append("<br>Session ID: "); 80 81 sb.append(session.getId()); 82 83 84 85 message = sb.toString(); 86 87 return SUCCESS; 88 89 } 90 91 }
例6 Servlet.jsp
<%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags"%> <html> <head> <title>Hello World!</title> </head> <body> <h2> <s:property value="message" escape="false"/> <br>Message from session: <s:property value="#session.msg"/> </h2> </body> </html>
例6 classes/struts.xml中NonIocServlet和IoCServlet Action的配置
<action name="NonIoCServlet" class="tutorial.NonIoCServlet"> <result>/Servlet.jsp</result> </action> <action name="IoCServlet" class="tutorial.IoCServlet"> <result>/Servlet.jsp</result> </action>
運行Tomcat,在瀏覽器地址欄中鍵入http://localhost:8080/Struts2_Action /NonIoCServlet.action?msg=Hello World! 或http://localhost:8080/Struts2_Action/IoCServlet.action?msg=Hello World!
在Servlet.jsp中,我用了兩次property標志,第一次將escape設為false為了在JSP中輸出<br>轉行,第二次的value中的OGNL為"#session.msg",它的作用與session.getAttribute("msg")等同.
附:ActionContext的常用方法(來自Struts2.0 API)
(一)get
Returns a value that is stored in the current ActionContext by doing a lookup using the value's key.
Parameters:
key- the key used to find the value.
Returns:
the value that was found using the key or null if the key was not found.
public void put(Object key, Object value)
Stores a value in the current ActionContext. The value can be looked up using the key.
Parameters:
key- the key of the value.
value- the value to be stored.
(三)getContext
public static ActionContext getContext()
Returns the ActionContext specific to the current thread.
Returns:
the ActionContext for the current thread, is never null.
(四)getSession
public Map getSession()
Gets the Map of HttpSession values when in a servlet environment or a generic session map otherwise.
Returns:
the Map of HttpSession values when in a servlet environment or a generic session map otherwise.
public void setSession(Map session)
Sets a map of action session values.
Parameters:
session- the session values.
Struts2的action類繼承
com.opensymphony.xwork2.ActionSupport類的常用方法
addFieldError //該方法主要用於驗證的方法之中
public void addFieldError(String fieldName, String errorMessage)
Description copied from interface: ValidationAware
Add an error message for a given field.
Specified by:
addFieldErrorin interface ValidationAware
Parameters:
fieldName- name of field
errorMessage- the error message
public void validate()
A default implementation that validates nothing. Subclasses should override this method to provide validations.
Specified by:
validatein interface Validateable
方法的來源,見后面補充的常用方法:
public void setSession(Map session)
Sets a map of action session values. 設置session值,
Parameters:
session- the session values.
常用於校驗登陸程序的賬號和密碼是否為空,可以加入addFieldError方法。例如public void validate() {
if (null == login.getUserID() || "".equals(login.getUserID())) { this.addFieldError("login.userID", "學號不能為空"); }
if (null == login.getUserPassword() ||"".equals(login.getUserPassword())) { this.addFieldError("login.userPassword", "密碼不能為空"); }
}