1. 程式人生 > >【JavaEE筆記】Struts2 (三) ognl、值棧操作等

【JavaEE筆記】Struts2 (三) ognl、值棧操作等

一. ognl概述

1. 在web階段,學習過EL表示式,EL表示式在JSP中獲取域物件裡面的值

2. ognl是一種表示式,這個表示式功能更加強大

i.在struts2裡面操作值棧資料
ii. 一般把ognl在struts2操作,和struts2標籤一起使用操作值棧

3. OGNL不是struts2的一部分,單獨的專案,經常和struts2一起使用

i. 使用ognl時候首先要匯入jar包,struts2提供的jar包

二. ognl入門案例

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

支援物件方法的呼叫,例如 objName.methodName()
i. 在Java程式碼中呼叫字串 .length() 方法

2. 使用struts2標籤

i. 使用jstl時候,匯入jar包後,在jsp頁面中引入標籤庫

ii. 使用struts2標籤的時候,在jsp頁面中引入標籤庫

<%@ taglib uri="/struts-tag" prefix="s" %> <!--引入標籤庫   -->

iii. 使用struts2標籤 實現操作

<body>
	<!-- 使用ognl+struts2標籤實現字串長度
		value屬性值:ognl表示式
	 -->
	<s:property value="'abcdefg'.length()"/>
</body>

三. 值棧

1. 什麼是值棧?

i.  之前在web階段,在servlet裡面進行操作,把資料放到域物件裡面,在頁面中使用EL表示式獲取到,域物件在一定範圍內,存值和取值。

ii. 在struts2裡面提供本身一種儲存的機制,類似於域物件,是值棧,可以存值和取值

1) 在action裡面把資料放到值棧裡面,在頁面裡面獲取到值棧資料

iii. action和servlet區別?

1) servlet:預設在第一訪問時候建立,建立一次,單例項物件。
2) action:訪問時候建立,每次訪問action,都會建立action物件,建立多次,多例項物件。

iv. 值棧儲存位置

1) 每次訪問action時候,都會建立action物件。
2) 在每個action物件裡面都有一個值棧物件。

四. 如何獲取值棧物件

1. 獲取值棧物件有多種方式

i. 使用ActionContext類裡面的方法得到值棧物件。

//1.獲取ActionContext物件
ActionContext context = ActionContext.getContext();
//2.呼叫方法得到值棧物件
ValueStack stack1 = context.getValueStack();

ii. 每一個action物件中只有一個值棧物件

五. 值棧內部結構

1. 值棧分為兩部分

i. 第一部分 root,結構是 list集合

1) 一般操作都是 root裡面的資料

ii. 第二部分 context,結構是 map集合

2. struts2裡面標籤 s:debug 使用這個標籤可以檢視值棧結構和儲存值

i. 訪問action,執行action的方法有返回值,配置返回值到 jsp頁面中,在 jsp頁面中使用這個標籤

1) 點選超連結看到結構

ii. 在acion沒有做任何操作,棧頂元素是action 引用

1) action 物件裡面有值棧物件

2) 值棧物件裡面有action引用

六. 向值棧放資料

1. 向值棧放資料的多種方式

i. 獲取值棧物件,呼叫值棧物件裡面的 set 方法

//第一種 使用值棧物件裡面的set方法
//1.獲取值棧物件
ActionContext context = ActionContext.getContext();
ValueStack stack1 = context.getValueStack();
//2.呼叫方法set方法
stack1.set("username", "yangfan");

ii. 獲取值棧物件,呼叫值棧物件裡面的 push方法

//第一種 使用值棧物件裡面的set方法
//1.獲取值棧物件
ActionContext context = ActionContext.getContext();
ValueStack stack1 = context.getValueStack();
//2.呼叫方法set方法
stack1.set("username", "yangfan");
//3.呼叫方法push方法
stack1.push("abc");

iii. 在action 定義變數,生成變數的get方法(主要)

public class ValueStackAcion extends ActionSupport {
	//1.定義變數
	private String name;
	//2.生成變數get方法
	public String getName() {
		return name;
	}

	@Override
	public String execute() throws Exception {
		//在執行方法裡面向變數設定值 
		name = "hello";
		
		return "success";
	}
}

2. 向值棧放物件

i. 定義物件變數
ii. 生成變數的get方法
iii. 在執行的方法裡面向物件中設定值
import org.fan.entity.User;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

public class ObjectAcion extends ActionSupport {
	//1.定義物件變數
	private User user = new User();
	//2.生成get方法
	public User getUser() {
		return user;
	}
	@Override
	public String execute() throws Exception {
		//3.向值棧的User裡面放資料
		user.setUsername("yangfan");
		user.setPassword("123123");
		user.setAddress("西安");
		
		return "success";
	}
}

3. 向值棧放 list集合

i. 定義list集合變數
ii. 生成變數的get方法
iii. 在執行的方法裡面向list集合設定值
import java.util.ArrayList;
import java.util.List;

import org.fan.entity.User;

import com.opensymphony.xwork2.ActionSupport;

public class ListAction extends ActionSupport {
	
	//1.定義List變數
	private List<User> list = new ArrayList<>();
	//2.get方法
	
	public List<User> getList() {
		return list;
	}

	@Override
	public String execute() throws Exception {
		//3.向list裡面放值
		User user1 = new User();
		user1.setUsername("Ying");
		user1.setPassword("123456");
		user1.setAddress("北京");
		
		User user2 = new User();
		user2.setUsername("yangfan");
		user2.setPassword("123123");
		user2.setAddress("西安");
		
		list.add(user1);
		list.add(user2);
		
		return "success";
	}
}

七. 從值棧獲取資料

使用struts2標籤+ognl表示式獲取值棧資料
<s:property value="ognl表示式"/>

1. 從值棧獲取字串

i. 向值棧中放字串

import com.opensymphony.xwork2.ActionSupport;

public class ValueStackAction extends ActionSupport {

	private String username;
	public String getUsername() {
		return username;
	}
	
	public String execute() throws Exception {
		username = "itcast";
		return "success";
	}
}
ii. 在jsp中使用struts2標籤+ognl表示式獲取
	<!-- 1.獲取字串的值 -->
		<s:property value="username"/>


2. 從值棧獲取物件

i. 向值棧中放物件

import org.fan.entity.User;

import com.opensymphony.xwork2.ActionSupport;

public class ObjectStackAction extends ActionSupport {

	private User u = new User();
	
	public User getU() {
		return u;
	}

	public String execute() throws Exception {
		u.setUsername("yang");
		u.setPassword("123123");
		u.setAddress("西安");
		return "success";
	}
}
ii. 在頁面中獲取
<!-- 2.獲取物件 -->
		<s:property value="u.username"/>
		<s:property value="u.password"/>
		<s:property value="u.address"/>


3. 從值棧獲取 list集合

i. action

import java.util.ArrayList;
import java.util.List;

import org.fan.entity.User;

import com.opensymphony.xwork2.ActionSupport;

public class ListStackAction extends ActionSupport {
	//1.定義list變數
	private List<User> list = new ArrayList<>();
	//2.get方法
	public List<User> getList() {
		return list;
	}
	
	public String execute() throws Exception {
		//3.向list放資料
		User user1 = new User();
		user1.setUsername("Ying");
		user1.setPassword("123456");
		user1.setAddress("北京");
		
		User user2 = new User();
		user2.setUsername("yangfan");
		user2.setPassword("123123");
		user2.setAddress("西安");
		
		list.add(user1);
		list.add(user2);
		return "success";
	}
}

ii. jsp

<!-- 3.獲取值棧中 list集合資料 -->
		第一種方式 <br>
			<s:property value="list[0].username"/>
			<s:property value="list[0].password"/>
			<s:property value="list[0].address"/><br>
			<s:property value="list[1].username"/>
			<s:property value="list[1].password"/>
			<s:property value="list[1].address"/><br>
		第二種方式 <br>
			<!-- 使用struts2裡面的標籤 類似JSTL裡面的 foreach標籤 -->
			<!--  遍歷list得到list裡面每個user物件-->
			<s:iterator value="list">
				<s:property value="username"/>
				<s:property value="password"/>
				<s:property value="address"/><br>
			</s:iterator>
		第三種方式 <br>
			<!--遍歷值棧list集合 得到每個物件 
				機制:把每次遍歷出來的user物件放到context裡面	
				獲取context裡面資料的特點:寫ognl表示式,使用特殊符號 # 
			-->
			<s:iterator value="list" var="user">
				<s:property value="#user.username"/>
				<s:property value="#user.password"/>
				<s:property value="#user.address"/><br>
			</s:iterator>

4.其他操作

i. 使用set方法向值棧放的資料的獲取


ii. 使用push方法向值棧放資料的獲取


1) 使用push方法設定值,沒有名稱,就只有設定的值。

2) 向值棧中放資料,把向值棧中放的資料存到陣列中,陣列名稱 top,根據陣列獲取值。


八. EL表示式獲取值棧資料(為什麼?)

1. EL表示式獲取域物件

2. 向域物件裡面放值使用setAttribute方法,獲取值使用getAttribut方法

3. 底層增強request物件裡面的方法getAttribute方法

i. 首先從request域獲取值,如果獲取到,直接返回。

ii. 如果從request域獲取不到值,到值棧中把值獲取出來,把值放到域物件裡面。

4. 關鍵性原始碼


九. ognl表示式 #、% 使用

1. # 的使用

i. 使用#獲取context裡面資料


ii. # 操作

1) java

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class ContextAction extends ActionSupport {
	@Override
	public String execute() throws Exception {
		//1.獲取request
		HttpServletRequest request = ServletActionContext.getRequest();
		request.setAttribute("req", "123123");
		return "success";
	}
}

2) jsp

	<!-- 獲取context裡面資料 寫ognl時候 首先新增符號 # 
		#context的key的名稱.域物件名稱
	-->
	<s:property value="#request.req"/>
	


2. % 的使用

i. 在struts2標籤中使用ognl表示式,如果直接在struts2表單標籤裡面使用ognl表示式不識別,只有 % 之後才會識別。

<s:textfield name="username" value="%{#request.req}"></s:textfield>