複習_Struts2

1.OGNL的用法詳解

Ognl表達式一般是結合struts2框架的標籤來使用的,最重要的作用,就是獲取值棧中存儲的數據。

在下面的示例,咱們將對ognl的各種用法進行測試,分析OGNL是如何使用的。

  1. 1.Java對象的直接訪問
    例如:’itcast’
  2. 實例方法調用
    語法:object.doSomething(),object是對象實例
    例如:’itcast’.toUpperCase()
  3. 靜態方法調用(類的靜態方法或靜態變量的訪問)–不常用
    語法:@[類全名(包括包路徑)]@[方法名|值名]
    例如:@java.lang.Math@max(10,20)
    注意:必須通過配置struts2的常量來開啓靜態方法調用功能:
    struts.ognl.allowStaticMethodAccess=true
  4. 賦值操作或表達式串聯。–可以運算
    如計算1+2或者2*2
  5. 對集合對象的操作
    <s:property value="#{‘上海’:‘浦東’,‘北京’:‘豐臺’}"/>
  6. Ognl對值棧的操作

示例:
搭建struts2的環境:導入jar、struts.xml、web.xml,引入struts標籤庫,編寫表達式代碼

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
    <title>$Title$</title>
</head>
<body>
<!-- s:property標籤中的value可以用來解析ognl表達式獲取各類數據 -->

<!-- ognl表達式的用法 -->

<!-- s:property標籤中的value 可以解析ognl表達式 -->
<s:property value="'itcast'"/><br>
<!-- 可以操作對象的實例方法 -->
<s:property value="'itcast'.toUpperCase()"/><br>
<!-- 可以操作靜態方法 -->
<s:property value="@java.lang.Math@max(1,20)"/><br>
<!-- 操作集合 -->
<s:property value="{'上海','北京'}"/><br>
<!-- 操作map集合 -->
<s:property value="#{'上海':'浦東','北京':'豐臺' }"/><br>
<!-- 操作表達式 -->
<s:property value="10%3"/><br>
</body>
</html>

應用ognl 表達式調用對象方法或者靜態方法,需要結合struts2的\<s:property > 標籤,其中提供的value屬性支持ognl。

2.值棧概述

2.1 值棧(ValueStack)是什麼

值棧(ValueStack),是Struts2的數據中轉站(類似於超市)

他自動保存了當前Action對象和其他相關對象(包括常用的Web對象的引用,如request、application、session等),也可以手動保存自己的數據對象,同時也可以隨時隨地將對象從值棧取出或操作(通過OGNL表達式)

最核心的作用:存值

值棧(ValueStack)的接口是ValueStack類,實現類是OgnlValueStack類,該對象是Struts2利用OGNL的基礎。只要我們用到ognl,那麼就需要依賴值棧。

在這裏插入圖片描述
Struts2框架將ValueStack對象保存在名爲“struts.valueStack”的請求(request)屬性中,即值棧是request中的一個對象,一個請求對應一個Action實例和一個值棧對象。

值棧的獲取方式:

  • request.getAttribute(“struts.valueStack”)
  • ActionContext.getContext().getValueStack()

該兩種方式獲取的值棧其實是同一個。


2.2 值棧的數據存儲結構的分析

【示例1】
目標:值棧對象的獲取,並證明兩種方式獲取的對象是同一個對象:
1)request.getAttribute(“struts.valueStack”)
2)ActionContext.getContext().getValueStack()

步驟一:編寫action
創建包和action
public class DemoAction extends ActionSupport{
	@Override
	public String demo(){
		//獲取值棧的第一種方式
		ValueStack valueStack1 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
		//獲取值棧的第二種方式
		ValueStack valueStack2 = ActionContext.getContext().getValueStack();
		System.out.println(valueStack1);
		System.out.println(valueStack2);
		
		return SUCCESS; 
	}
}
<struts>
	<!-- 配置開發者模式 -->
	<constant name="struts.devMode" value="true"></constant>
	<package name="p1" extends="struts-default">
	
		<action name="demo" class="cn.itcast.valueStack.DemoAction" method="demo">
			<result name="success">/demo.jsp</result>
		</action>
	</package>
</struts>

在這裏插入圖片描述

【值棧小結】:
值棧包括兩部分:root棧和map棧
1、root棧:繼承了List接口,又稱之爲對象棧
2、map棧:實現了Map接口,又可以稱之爲上下文棧(context)
在這裏插入圖片描述


3.值棧的操作(重點)

3.1 Root棧的存值和取值

Root棧的存值:
它按照先進後出的原則存儲數據,即先進入的數據被壓入棧底,最後進入的數據在棧頂,需要讀取數據的時候,從棧頂開始彈出數據(即最後一個數據被第一個讀出來)。
棧也被成爲先進後出表,可進行插入和刪除操作,插入稱之爲進棧(壓棧)(push),刪除稱之爲退棧(pop)

【示例】
值棧數據的保存:向root棧存入數據,響應頁面根據不同的方式(通過ognl表達式)分別將值獲取出來。

1.Push方式壓入棧頂
push方法:將數據壓入root棧的棧頂。

public class DemoAction extends ActionSupport{
	@Override
	public String demo(){
		//獲取值棧的第一種方式
		ValueStack valueStack1 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
		//獲取值棧的第二種方式
		ValueStack valueStack2 = ActionContext.getContext().getValueStack();
		System.out.println(valueStack1);
		System.out.println(valueStack2);
		
		//將數據存入root棧,以push方法壓入棧頂
		valueStack2.push("zhangsan");
		//繼續將一個數據壓入棧頂
		valueStack2.push("lisi");
		
		return SUCCESS;
	}
}

Root棧分析:
在這裏插入圖片描述
步驟二:設置響應頁面利用ognl表達式從值棧取值
導入struts標籤:

<%@taglib uri="/struts-tags" prefix="s" %>
demo.jsp頁面內容:
<!-- 
		通過s:property標籤獲取數據 
		value:是一個ognl表達式,通過valu值可以到值棧中去查詢對應的數據
		[0].top:表示獲取root棧棧頂的數據
	-->
	獲取棧頂數據1:<s:property value="[0].top"/><br>
	獲取棧頂數據2:<s:property/><br>
	<s:debug></s:debug>
	執行成功!

步驟三:測試
在這裏插入圖片描述

2.Set方式壓入棧頂
set方法:
將數據壓入棧頂:會先創建一個map集合,讓後將數據存入到集合中,最後將map集合壓入棧頂。

步驟一:修改DemoAction :
public class DemoAction extends ActionSupport{
	
	public String demo(){
		//第一種獲取值棧的方式
		ValueStack valueStack1 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
		System.out.println(valueStack1);
		//第二種獲取值棧的方式
		ValueStack valueStack2 = ActionContext.getContext().getValueStack();
		System.out.println(valueStack2);
		
		//將數據存入root棧棧頂
		valueStack2.push("zhangsan");
		valueStack2.push("lisi");
		
		//set:創建一個map集合,將數據存入該集合中,最終將map集合壓入root棧棧頂
		valueStack2.set("name","wangwu");
		
		return SUCCESS;//相當於"none",表示不響應任何結果集視圖
	}
	
}
<%--
		如果棧頂是map集合:通過集合的key可以直接獲取value值
		通過name到值棧中從上往下進行查找,找到的第一個進行返回
	 --%>
	 獲取棧頂map中的數據:<s:property value="name"/><br>

3.通過action的成員變量將數據存入值棧
頁面的<s :debug>標籤會通過getName()方法從值棧中獲取數據並顯示在root棧中
步驟一:修改ValueStackAction
在action中添加成員變量,並設置成員變量的的getter和setter方法

3.2 Map棧的存值和取值

1.通過put方法將數據存入map棧

put方法:
將數據存入map棧,map棧是一個map,因此需要通過key來獲取對應的value.
如果需要直接從map棧獲取數據,建議在ognl表達式中添加一個#,表示直接從map棧查找,而不是從root棧棧頂開始從上往下查找。

如:<s:property value="#name"/>

修改DemoAction

public class DemoAction extends ActionSupport{
	private String name = "maliu";
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String demo(){
		//第一種獲取值棧的方式
		ValueStack valueStack1 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
		System.out.println(valueStack1);
		//第二種獲取值棧的方式
		ValueStack valueStack2 = ActionContext.getContext().getValueStack();
		System.out.println(valueStack2);
		
		//將數據存入root棧棧頂
		valueStack2.push("zhangsan");
		valueStack2.push("lisi");
		
		//set:創建一個map集合,將數據存入該集合中,最終將map集合壓入root棧棧頂
		valueStack2.set("name","wangwu");

		//將數據存入map棧
		//由於map棧本質就是一個集合,因此存儲方式和map一樣
		ActionContext.getContext().put("name", "tianqi");
		return SUCCESS;//相當於"none",表示不響應任何結果集視圖
	}
}

頁面獲取map棧數據

<%--
		從map棧獲取數據:在ognl表達式中使用#表示直接從map棧查找數據
	 --%>
	 
	 獲取map棧中的數據:<s:property value="#name"/>

3.3 值棧的存取小結

值棧的主要作用就是數據的保存和獲取
使用值棧的時候要思考:用什麼代碼存進去,然後再用什麼代碼取出來

3.4 值棧的創建過程源代碼分析(瞭解)

3.5 值棧的生命週期

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