1. 程式人生 > >Struts2_day03---OGNL、值棧中存、取資料

Struts2_day03---OGNL、值棧中存、取資料

一、OGNL(Object-Graph Navigation Language)

OGNL是一種功能更加強的表示式語言。

理解:類似於EL表示式。EL應用在jsp中,OGNL多用在struts2中。

主要作用:在struts2裡面操作值棧資料(通常和struts2中property標籤配合使用)

注:OGNL不是struts2的一部分,是單獨的專案,但經常和struts2標籤一起使用。

在這裡插入圖片描述

1.1 OGNL入門案例

使用ognl+struts2標籤實現計算字串長度

使用步驟:
	1)導包  --struts2中已經提供jar包
	2)配置過濾器
	3)匯入struts標籤庫 
		<%@ taglib uri="/struts-tags" prefix="s" %>  
	4)在struts標籤中使用ognl表示式
		在struts使用property標籤,在value值中寫入ognl表示式 
	
程式碼案例:
jsp頁面首行:
	<!-- 1.在jsp頁面中引入struts標籤庫 -->
	<%@ taglib uri="/struts-tags" prefix="s" %>   
<body>中:
	<body>
		<!-- 
			struts標籤與ognl標籤的配合:
			在struts使用property標籤,在 property的value值中寫入ognl表示式  
		-->
		<s:property value="'haha'.length()" />
	</body>

1.2 OGNL的#、%的使用

#作用:
	1)#可獲取context域中資料
	2)#可獲取request域中資料
		<s:property value="#request.Key"/>

%作用:
	知識點:struts2中的表單標籤:<s:textfield>  相當於 <input/>
	
	背景:<s:textfield>內直接使用ognl表示式將不被識別
	
	解決:加入 %{} 使ognl表示式被識別
		<s:textfield name="" value="%{ ognl表示式 }"></s:textfield>
		
	示例:
		<s:textfield name="" value="%{#request.req}"></s:textfield>

二、值棧

是struts提供的儲存結構。 類似於Servlet中的域

儲存位置:在每個action物件內部有且僅有一個值棧物件。

使用場景:在action裡存資料到值棧,在頁面中取值棧中資料

獲取值棧物件:使用ActionContext類裡面的getValueStack()方法得到值棧物件

/**
 * 得到值棧演示
 * @author 一萬年行不行
 *
 */
public class ValueStackDebug extends ActionSupport {
	@Override
	public String execute() throws Exception {
		//得到context
		ActionContext context = ActionContext.getContext();
		
		//得到值棧
		ValueStack stack = context.getValueStack();
		return "good";
	}
}

2.2 值棧內部結構:

分為兩部分:
	1)root部分。結構是list集合
	2)context部分。結構map集合

在這裡插入圖片描述

2.3 檢視值棧結構

步驟:
	1)訪問action,配置返回值到jsp頁面中,在頁面中<s:debug>標籤
	2)點選超連結看到結構

	注:在action沒有做任何操作時,root部分棧頂元素是action的引用
			- action物件裡面有值棧物件
			- 值棧物件裡面也有action引用

root結構圖示: 在這裡插入圖片描述 context結構圖示(部分): 在這裡插入圖片描述

三、向值棧放資料

3.1 放資料和map

向值棧放資料(三種方式)
	1)set方法
		作用:存放鍵值對資料
		步驟:
			 1)獲取值棧物件。
			 2)呼叫值棧物件裡面的 set 方法
		內部機制:會在值棧中root部分開闢出Map空間。

	2)push方法
		作用:存放String資料
		步驟:
			 1)獲取值棧物件。
			 2)呼叫值棧物件裡面的 push 方法
		內部機制:會在值棧中root部分開闢出陣列空間。
		
		
	3)get方法
		作用:存放變數
		步驟:
			 1)在action定義變數。
			 2)生成變數的get方法
			 3)給變數賦值
		內部機制:在root部分已有的action引用中,開闢出變數名屬性,然後存放資料值。
	
	程式碼演示:
	/**
	 * 向值棧中存資料演示(三種方式)
	 * @author 一萬年行不行
	 *
	 */
	public class ValueStackDebug extends ActionSupport {
		
		/**
		 * get方法向值棧存資料演示
		 */
		
		//1)定義變數
		private String name;
		
		//2)生成變數的get方法
		public String getName() {
			return name;
		}
		
		/**
		 * set / push 方法向值棧放資料演示
		 */
		@Override
		public String execute() throws Exception {
			
			//3)get方法--給變數賦值
			name="Value";
			
			//1)獲取值棧物件
			ActionContext context = ActionContext.getContext();  //得到context
			ValueStack stack = context.getValueStack();  //通過context得到值棧
			
			//2)呼叫set方法
			stack.set("username", "ywnxbx");
			
			//2)呼叫push方法
			stack.push("ywnxbx");
			return "good";
		}
	}

效果圖示: 在這裡插入圖片描述

3.2 放物件與集合:

向值棧放物件
步驟:
	1)定義物件變數
	2)生成變數的get方法
	3)在執行方法裡面向物件中設定值


向值棧放list集合
步驟:
	1)定義list集合變數
	2)生成變數的get方法
	3)在執行方法裡面向list集合設定值
	
程式碼示例:
	/**
	 * 演示:向值棧中存放 物件/list集合 
	 * @author 一萬年行不行
	 *
	 */
	public class InValueStack extends ActionSupport {
		//1)定義物件變數
		private User user = new User();
		//1)定義list變數
		private List<User> list = new ArrayList<User>();
		
		
		//2)生成變數的get方法
		public User getUser() {
			return user;
		}
		//2)生成list集合的get方法
		public List<User> getList() {
			return list;
		}
		
		@Override
		public String execute() throws Exception {
			
			//3)在執行的方法裡面向物件中設定值
			user.setUsername("zhangsan");
			user.setPassword("123456");
			user.setAddress("shanxi");
			
			//3)向list集合中設定值
			User user1 = new User();
			user1.setUsername("111");
			user1.setPassword("111");
			user1.setAddress("111");
			
			list.add(user1);
			
			return "good";
		}
	}

效果圖示: 在這裡插入圖片描述

四、從值棧獲取資料

思想:在jsp使用struts2標籤+ognl表示式獲取

程式碼示例:
<body>

1)	<!-- 獲取get存放 字串的值 -->
	<s:property value="username"/>
	
2)	<!-- 獲取set存放 鍵值對 -->
	<s:property value="name"/>
	
3)	<!-- 獲取push存放的值(根據陣列下標獲取值)
	機制:push方式會把資料存到名為top的數組裡面,以陣列形式放進值棧中,
	-->
	<s:property value="[0].top"/>    <!-- 根據陣列下標獲取 -->
	
4)	<!-- 獲取物件中的值 -->
	<s:property value="user.username"/>
	<s:property value="user.password"/>
	
5)	<!-- 獲取集合 (方式1) -->
	<s:property value="list[0].username"/>
	<s:property value="list[0].password"/>
	
6)	<!-- 獲取集合 (方式2) -->
	<s:iterator value="list">
		<!-- 遍歷list,得到每個user物件 -->
		<s:property value="username"/>
		<s:property value="password"/>
	</s:iterator>
	
7)	<!-- 獲取集合 (方式3) -->
	<s:iterator value="list" var="user">
		<!-- 
			遍歷list集合,得到每個user
			機制:將每次遍歷到的user放進context中
			獲取context中資料:寫ognl表示式  使用 “#” 獲取  
		 -->
		<s:property value="#user.username"/>
		<s:property value="#user.password"/>
	</s:iterator>
	
8)	<!-- 使用EL表示式 + foreach 獲取值棧中集合資料 -->
	<c:forEach items="${list }" var="user" >
		${user.username }
		${user.password }
	</c:forEach>
	
</body>


EL可獲取到值棧資料原因:
	背景:EL表示式用來獲取域物件值
	原因:底層增強了request物件裡面的getAttribute方法
			1)EL首先從request域獲取值,如果獲取到,直接返回
			2)獲取不到值,則會到值棧中找值,找到後把值放到域物件裡面