Structs2(2訪問web資源)耦合和解耦兩種方式

Structs2.xml介紹

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

Action

struts.xml文件中

<include file="example.xml"/>

將其他的struct.xml放進該.xml文件中

action VS Action類

1). action: 代表-一個Struts2 的請求。
2). Action類:能夠處理Struts2 請求的類.

屬性的名字必須遵守與JavaBeans 屬性名相同的命名規則.
屬性的類型可以是任意類型。從字符串到非字符串(基本數據庫類型)之間的數據轉換可以自動發生
必須有一個不帶參的構造器:通過反射創建實例
至少有-個供struts 在執行這個action 時調用的方法
同一個Action 類可以包含多個action 方法。
Struts2 會爲每一個 HTTP請求創建一個新的 Action實例,即Action不是單例的,是線程安全的。

在Action 中訪問WEB資源

l). 什麼是WEB資源?
HttpServletRequest, HttpSession, ServletContext 等原生的Servlet API.
II).爲什麼訪問WEB資源?
B\S的應用的Controller中必然需要訪問WEB資源:向域對象中讀寫屬性,讀寫Cookie,獲取realPath …

III).如何訪問?
1.和Servlet API解耦的方式:只能訪問有限的Servlet API對象,且只能訪問其有限的方法(讀取請求參數,讀寫域對象的屬性,使session銷燬>

使用ActionContext
實現XxxAware接口
選用的建議:若-一個Action類中有多個action 方法,且多個方法都需要使用城對象的Map或parameters, 則建議使用Aware接口的方式
session對應的Map實際上是Sess ionMap 類型的!強轉後若調用其invalidate() 方法,可以使其session失效!

2.和Servlet API耦合的方式:可以訪問更多的Servlet API對象,且可以調用其原生的方法●

使用 ServletActionContext
實現ServletXxxAware 接口

代碼:
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=a">Test ActionContext</a>
	
	<br><br>
	
	<a href="TestAware.do?name=123">Test Aware</a>

	<br><br>
	
	<a href="testActionSupport.do">Test ActionSupport</a>

	<br><br>
	
	<a href="testResult.do?number=4">Test Result</a>

	<br><br>
	
	<a href="testDynamicMethodInvocation.do">Test DynamicMethodInvocation</a>

	<% 
		if(application.getAttribute("date") == null)
			application.setAttribute("date", new Date());
	
		request.setAttribute("req", "reqvalue");
	%>
	
</body>
</html>

與 Servlet API 解耦的訪問方式

通過ActionContext訪問
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(Object key): ActionContext 類中沒有提供類似 getRequest() 這樣的方法來獲取 HttpServletRequest 對應的 Map 對象. 要得到 HttpServletRequest 對應的 Map 對象, 可以通過爲 get() 方法傳遞 “request” 參數實現

TestActionContextAction.java

package product;

import java.util.Map;

import org.apache.struts2.dispatcher.SessionMap;

import com.opensymphony.xwork2.ActionContext;

public class TestActionContextAction {

	public String execute(){
		
		//0. 獲取 ActionContext 對象
		//ActionContext 是 Action 的上下文對象. 可以從中獲取到當往 Action 需要的一切信息
		ActionContext actionContext = ActionContext.getContext();
		
		//1. 獲取 application 對應的 Map, 並向其中添加一個屬性
		//通過調用 ActionContext 對象的 getApplication() 方法來獲取 application 對象的 Map 對象
		Map<String, Object> applicationMap = actionContext.getApplication();
		//設置屬性
		applicationMap.put("applicationKey", "applicationValue");
		
		//獲取屬性
		Object date = applicationMap.get("date");
		System.out.println("date: " + date);
		
		//2. session
		Map<String, Object> sessionMap = actionContext.getSession();
		sessionMap.put("sessionKey", "sessionValue");
		
		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() 方法, 傳入 request 字符串來獲取. 
		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(((String[])parameters.get("name"))[0]);
		
		parameters.put("age", 100);
		
		return "success";
	}
	
}

通過 Action 實現接口
Action 類通過可以實現某些特定的接口, 讓 Struts2 框架在運行時向 Action 實例注入 parameters, request, session 和 application 對應的 Map 對象:
在這裏插入圖片描述
TestAwareAction.java

package product;

import java.util.Map;

import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

public class TestAwareAction implements ApplicationAware, SessionAware, RequestAware,
	ParameterAware{
	
	public String execute(){
		
		//1. 向 application 中加入一個屬性: applicationKey2 - applicationValue2
		application.put("applicationKey2", "applicationValue2");
		
		//2. 從 application 中讀取一個屬性 date, 並打印. 
		System.out.println(application.get("date"));
		
		return "success";
	}
	
	public String save(){
		
		return null;
	}

	private Map<String, Object> application;
	
	@Override
	public void setApplication(Map<String, Object> application) {
		this.application = application;
	}

	@Override
	public void setParameters(Map<String, String[]> parameters) {
		
	}

	@Override
	public void setRequest(Map<String, Object> request) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setSession(Map<String, Object> session) {
		// TODO Auto-generated method stub
		
	}
	
}

與 Servlet 耦合的訪問方式

直接訪問 Servlet API 將使 Action 與 Servlet 環境耦合在一起, 測試時需要有 Servlet 容器, 不便於對 Action 的單元測試.
使用ServletActionContext
直接獲取 HttpServletRequest 對象:
ServletActionContext.getRequest()
直接獲取 HttpSession 對象
ServletActionContext.getRequest().getSession()
直接獲取 ServletContext 對象
ServletActionContext.getServletContext()

package product;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

public class ouhe {
	public String execute(){
		HttpServletRequest a=ServletActionContext.getRequest();
		HttpSession b=a.getSession();
		ServletContext c=ServletActionContext.getServletContext();
		System.out.println("run");
		return "success";
	}
}

通過實現 ServletRequestAware, ServletContextAware 等接口的方式

package product;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.*;
import org.apache.struts2.util.ServletContextAware;

public class ouhejiekou implements ServletRequestAware,ServletContextAware,ServletResponseAware{

	@Override
	public void setServletRequest(HttpServletRequest arg0) {
		// TODO Auto-generated method stub
		System.out.println("nihao");
	}
	public String execute(){
		
		return "success";
	}
	@Override
	public void setServletContext(ServletContext arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setServletResponse(HttpServletResponse arg0) {
		// TODO Auto-generated method stub
		
	}

}

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 Page</h4>
	
	application : ${applicationScope.applicationKey }
	<br><br>
	
	session: ${sessionScope.sessionKey }
	<br><br>
	
	request: ${requestScope.requestKey }
	<br><br>
	
	age: ${parameters.age }
	
</body>
</html>

struts2.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>

	<!-- 配置 Struts 可以受理的請求的擴展名 -->
	<constant name="struts.action.extension" value="action,do,"></constant>
	
	<!-- 打開允許動態方法調用的開關, 默認是 false -->
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	
    <package name="default" namespace="/" extends="struts-default">

		<action name="TestActionContext" 
			class="product.TestActionContextAction">
			<result  name="success">/test-actionContext.jsp</result>	
		</action>
		
		<action name="TestAware" 
			class="product.TestAwareAction">
			<result>/test-aware.jsp</result>	
		</action>
		
		<action name="testActionSupport">
			<result>/testActionSupport.jsp</result>
		</action>

		<action name="testResult" class="com.atguigu.struts2.action.TestResultAction">
			<result name="success" type="dispatcher">/success.jsp</result>
			<result name="login" type="redirect">/login.jsp</result>
			
			<!-- 重定向到一個 Action -->
			<!--  
			<result name="index" type="redirectAction">
				<param name="actionName">testAction</param>
				<param name="namespace">/atguigu</param>
			</result>
			-->
			
			<!-- 通過 redirect 的響應類型也可以便捷的實現 redirectAction 的功能! -->
			<result name="index" type="redirect">/atguigu/testAction.do</result>
			
			<!-- 轉發到一個 Action -->
			<!--  
			<result name="test" type="chain">
				<param name="actionName">testAction</param>
				<param name="namespace">/atguigu</param>
			</result>
			-->
			
			<!-- 不能通過 type=dispatcher 的方式轉發到一個 Action -->
			<result name="test">/atguigu/testAction.do</result>
			
			
		</action>
		
		<action name="testDynamicMethodInvocation"
			class="product.TestDynamicMethodInvocationActoin"
			method="save">
			<result>/success.jsp</result>	
		</action>

    </package>
    
    <package name="testPackage" namespace="/atguigu" extends="struts-default">
    	<action name="testAction" 
    		class="product.TestAction">
    		<result>/success.jsp</result>
    	</action>
    </package>


</struts>

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