Struts2--Action詳述

action 和 Action類

1.action :代表一個struts2的請求

2.Action類 : 能夠處理struts2請求的類

>屬性的名字必須遵守與javabean屬性名相同的命名規則,屬性的類型可以是任意類型。從字符串到非字符串(基本數據類型)之間的數據轉換可以自動發生


>必須有一個不帶參的構造器


>至少有一個供struts在執行這個action時調用的方法


>同一個action類可以包含多個action方法


>struts2會爲每一個HTTP請求創建一個新的action實例,即Action不是單例的,是線程安全的

在action中訪問web資源

1.什麼是web資源?

HttpServletRequest , HttpSession , ServletContext 等原生的Servlet API

2.爲什麼訪問web資源

B/S的應用的Controller 中必然需要訪問WEB資源:向域對象中讀取屬性,讀寫Cookie,獲取realPath.......


3.如何訪問

1. 和Servlet API 解耦的方式

只能訪問有限的Servlet API對象,且只能訪問其有限的方法(讀取請求參數,讀取域對象屬性,使session失效.....)

>使用ActionContext
>實現XxxAware接口

>使用ActionContext
爲了避免與Servlet API 耦合在一起,方便Action做單元測試,Struts2對HttpServletRequest,HttpSession和ServletContext進行了封裝,
構造了3個Map對象來替代這3個對象,在Action中可以直接使用HttpServletRequest,HttpSession,ServletContext對應的Map對象來保存和讀取數據。
(原Servlet API中HttpServletRequest,HttpSession和ServletContext的核心方法即是使用了一個Map,在這Action直接使用該Map)

ActionContext是Action執行的上下文的對象,在ActionContext中保存了Action執行所需的所有對象,包括parameters,request,session,application等
獲取HttpSession對應的Map對象:
--public Map getSession();

獲取ServletContext對應的Map對象:
--public Map getApplication();

獲取請求參數對應的Map對象:
--public Map getParameters()
獲取HttpServletRequest對應的Map對象:
--public Object  get(Objectkey):ActionContext類中沒有提供類似getRequest()這樣的方法來獲取HttpServletRequest對應的Map對象。
要得到HttpServletRequest對應的Map對象,可以通過爲get()方法傳遞“request”參數實現。
TestActionContextAction.java
public class TestActionContextAction {
	
	public String execute(){
		//0.獲取ActionContext對象
		//ActionContext是Action的上下文對象,可以從中獲取到前Action需要的一切信息
		ActionContext actionContext = ActionContext.getContext();
		
		//1.獲取application對應的Map,並向其中添加一個屬性
		//通過調用ActionContext對象的getApplication()方法來獲取application對象
		//設置屬性
		Map<String,Object> applicationMap = actionContext.getApplication();
		applicationMap.put("applicationKey", "applicationValue");
		
		//獲取屬性
		Object date = applicationMap.get("date");
		System.out.println("application:date:"+date);
		
		
		//2.session
		Map<String,Object> sessionMap = actionContext.getSession();
		sessionMap.put("sessionKey", "sessionValue");
		
		Object date2 = sessionMap.get("date");
		System.out.println("session:date:"+date2);
		System.out.println(sessionMap.getClass());
		
		if(sessionMap instanceof SessionMap){
			SessionMap sm = (SessionMap) sessionMap;
			sm.invalidate();
			System.out.println("session 失效了");
		}
		
		//3.request
		//ActionContext中並沒有提供getRequest方法來獲取request對應的Map
		//需要手工調用get()方法,傳入字符串來獲取
		Map<String, Object> requestMap = (Map<String, Object>) actionContext.get("request");
		requestMap.put("requestKey", "requestValue");
		
		//4.獲取請求參數對應的Map,並獲取指定的參數值
		//鍵:請求參數的名字,值:請求參數值對應的字符串數組
		//注意:1.getParameters的返回值爲在Map<String,Object>,而不是Map<String,String[]>
		//	  2.parameters這個Map只能讀,不能寫入數據,如果寫入,不出錯也不起作用
		Map<String,Object> parameters = actionContext.getParameters();
		System.out.println("parameters:"+parameters.get("name"));
		//把值打印出來
		System.out.println(((String[])parameters.get("name"))[0]);
		
		
		return "success"; 
	}
}
注意:session對應的Map實際上是SessionMap類型的,強轉後調用其invalidate()方法,可以使其session失效
>實現XxxAware接口
TestAwareAction.java
public class TestAwareAction implements ApplicationAware,SessionAware,RequestAware,ParameterAware{
	
	private Map<String , Object> application1;


	@Override
	public void setApplication(Map<String, Object> application) {
		// TODO 自動生成的方法存根
		this.application1 = application;
	}
	
	@Override
	public void setSession(Map<String, Object> arg0) {
		// TODO 自動生成的方法存根
		
	}
	
	
	@Override
	public void setRequest(Map<String, Object> arg0) {
		// TODO 自動生成的方法存根
		
	}
	
	
	
	@Override
	public void setParameters(Map<String, String[]> arg0) {
		// TODO 自動生成的方法存根
		
	}
	
	public String execute(){
		
		//1.向application中加入一個屬性:applicationKey2 - applicationValue2
		application1.put("applicationKey2", "applicationValue2");
		
		//2.從application中讀取一個屬性date,並打印。
		System.out.println("applicationValue2:"+application1.get("applicationKey2"));
		
		return "success";
	}

}
好處:使用ActionContext每個方法需要獲取多次getApplication,使用aware只用注入一次就可以了。

選用建議:若一個Action類中有多個action方法,且多個方法都需要使用域對象的Map或parameters,則建議使用aware接口方式


2.和Servlet API 耦合的方式

可以訪問更多Servlet API對象,且可以調用其原生的方法。直接訪問Servlet API 將使Action與Servlet環境耦合在一起
測試時需要有Servlet容器,不便於對Action的單元測試
>使用ServletActionContext
>實現ServletXxxAware接口
>使用ServletActionContext
ServletActionContext:可以從中獲取到當前Action,對象需要的一切Servlet API相關的對象。

1.直接獲取HttpServletRequest對象;
--ServletActionContext.getRequest();


2.直接獲取HttpSession對象
--ServletActionContext.getRequest().getSession();


       3.直接獲取ServletContext對象
--ServletActionContext.getServletContext();

TestServletActionContextAction.java
	public String execute(){
		
		HttpServletRequest request = ServletActionContext.getRequest();
		
//		HttpSession session = request.getSession();
		HttpSession session = ServletActionContext.getRequest().getSession();
		
		ServletContext servletContext = ServletActionContext.getServletContext();
		
		System.out.println("execute....");
		
		return "success";
	}
	
}

>實現ServletXxxAware接口
通過實現ServletXxxAware 接口的方式可以由struts2注入需要的Servlet相關的對象

ServletRequestAware:注入HttpServletRequest對象
ServletContextAware :注入ServletContext對象
ServletResponseAware:注入HttpServletResponse對象(不常用)
TestServletAwareAction.java

public class TestServletAwareAction implements ServletRequestAware,ServletContextAware{

	@Override
	public void setServletRequest(HttpServletRequest request) {
		// TODO 自動生成的方法存根
		System.out.println(request);
	}
		
	private ServletContext context;
	
	@Override
	public void setServletContext(ServletContext context) {
		// TODO 自動生成的方法存根
		System.out.println(context);
		this.context = context;
	}
	
	public String execute(){
		System.out.println("ServletContext: "+context);
		return "success";
	}

}

給出餘下完整代碼
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
   
    <package name="default" namespace="/" extends="struts-default">
        <action name="TestActionContext"
        	class="com.wul.struts2_4.action.TestActionContextAction">
            <result>/test-actionContext.jsp</result>
        </action>
        
        
          <action name="TestAware"
        	class="com.wul.struts2_4.action.TestAwareAction">
            <result>/test-aware.jsp</result>
        </action>

        
          <action name="TestServletActionContext"
        	class="com.wul.struts2_4.action.TestServletActionContextAction">
            <result>/success.jsp</result>
        </action>
        
        <action name="TestServletAware"
        	class="com.wul.struts2_4.action.TestServletAwareAction">
            <result>/success.jsp</result>
        </action>
        
    </package>

</struts>
index.jsp
<%@ page import="java.util.Date" %>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Insert title here</title>
</head>
<body>
	
	<a href="TestActionContext.action?name=wul">Test ActionContext</a>
	
	<br><br>
	
	<a href="TestAware.action?name=wul">Test Aware</a>
	
	<br><br>
	
	<a href="TestServletActionContext">TestServletActionContext</a>
	
	<br><br>
	
	<a href="TestServletAware">TestServletAware</a>
	
	<%
		if(application.getAttribute("date")==null)
			application.setAttribute("date",new Date());
		
		if(session.getAttribute("date")==null)
			session.setAttribute("date","123");
		
	%>
	
</body>
</html>


test-actionContext.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Insert title here</title>
</head>
<body>
	
	<h4>Test ActionContext Pages</h4>
	
	application : ${applicationScope.applicationKey }
	
	session : ${sessionScope.sessionKey }
	
	request : ${requestScope.requestKey }
</body>
</html> 



test-aware.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Insert title here</title>
</head>
<body>
	
	<h4>Test ActionContext Pages</h4>
	
	application : ${applicationScope.applicationKey }
	
	session : ${sessionScope.sessionKey }
	
	request : ${requestScope.requestKey }
</body>
</html> 

test-aware.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Insert title here</title>
</head>
<body>
	
	<h4>Test aware Pages</h4>
	
	application : ${applicationScope.applicationKey2 }
	
</body>
</html> 






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章