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>