OGNL表達式語言介紹

技術要點
本節代碼對OGNL一些經常使用特性進行分析,用演示代碼演示這些特性。
   經常使用特性介紹。
   OGNL在Struts2中頁面中的應用。
   OGNL特殊符號介紹html

1.利用OGNL進行應用的頁面:java

 

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page import="com.opensymphony.xwork2.util.ValueStack"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>
	<head>
		<title><s:text name="bookPageTitle"/></title>
	</head>
	<body>
	session 中的User:<s:property value="#session.user" /><br/>
	request中的第一本書的書名:<s:property value="#request.bookList[0].bookName"/><br/>
<br/><br/>
	篩選id>2的書:<br/>
	<s:iterator value="bookList.{?#this.id > 2}" id="book">
		<s:property value="#book.bookName"/><br/>
	</s:iterator>
<br/><br/>
篩選第一本id>2的書:<br/>
	<s:iterator value="bookList.{^#this.id > 2}" id="book">
		<s:property value="#book.bookName"/><br/>
	</s:iterator>
<br/><br/>
篩選最後一本id>2的書:<br/>
	<s:iterator value="bookList.{$#this.id > 2}" id="book">
		<s:property value="#book.bookName"/><br/>
	</s:iterator>
<br/>

取出bookList中的書名是「DDD」的id:
<s:property value="bookList.{?#this.bookName=='DDD'}.{id}[0]"/>
<br/>
<br/>
<!--  OGNL新建Map類型數據集合,顯示子元素值  -->
<s:set name="newBook" value="#{'abcd':'efgh','bookName':'XXX','bookAuthor':'xxx'}"/><br/>
 OGNL新建Map類型數據集合,顯示子元素值 :<s:property value="#newBook.abcd"/>
	</body>
</html>

 

2. struts.xml文件的配置:數據庫

 

 

<action name="getBooks" class="struts2.action.GetBooksAction">
			 <result name="error">/error.jsp</result>
			<result name="success">/showbook.jsp</result> 
			<result name="login">/index.jsp</result>  
		</action>

 

3.BookService類提供模擬數據庫讀出:session

 

package struts2.action;

import struts2.biz.BookService;
import struts2.entity.Book;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;

public class GetBooksAction implements Action {
	private Book[] bookList;

	public Book[] getBookList() {
		return bookList;
	}
	public void setBookList(Book[] bookList) {
		this.bookList = bookList;
	}


	public String execute() throws Exception {
		// TODO Auto-generated method stub
		String name = (String)ActionContext.getContext().getSession().get("user");
		if(null != name && "123".equals(name)){
			setBookList(BookService.getBooks());
			return SUCCESS;
		}else{
			return LOGIN;
		}
	}

}

 

4.Book實體類:app

 

 

package struts2.entity;

public class Book {
	private String bookName;
	private String bookAuthor;
	private int id;
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public Book(int id,String bookName,String bookAuthor){
		this.id = id;
		this.bookAuthor = bookAuthor;
		this.bookName = bookName;
	}
	
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public String getBookAuthor() {
		return bookAuthor;
	}
	public void setBookAuthor(String bookAuthor) {
		this.bookAuthor = bookAuthor;
	}
}

 

4.Action代碼:jsp

 

 

package struts2.action;

import struts2.biz.BookService;
import struts2.entity.Book;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;

public class GetBooksAction implements Action {
	private Book[] bookList;

	public Book[] getBookList() {
		return bookList;
	}
	public void setBookList(Book[] bookList) {
		this.bookList = bookList;
	}


	public String execute() throws Exception {
		// TODO Auto-generated method stub
		String name = (String)ActionContext.getContext().getSession().get("user");
		if(null != name && "123".equals(name)){
			setBookList(BookService.getBooks());
			return SUCCESS;
		}else{
			return LOGIN;
		}
	}

}

 

 

 代碼解釋
(1)Struts2中將應用範圍裏的數據以及Action處理的數據都存儲在一個區域裏。在Struts2中叫作「valueStack」,中文名爲「值棧」。而OGNL就是從「值棧」取出數據,並在某些條件下進行數據過濾和計算的表達式語言。在Struts2中值棧做爲OGNL的根對象,從值棧中取出本身須要的數據,並且值棧存取數據是按照先入後出的概念。所以查詢數據時候每每是值棧中最頂部的數據先被查詢出來。更加須要指出的是在值棧中也可使用索引,能夠在指定的索引位置開始搜索數據。this


在OGNL中若是搜索的數據不是值棧裏存儲的數據,並且其餘對象中,特別是Struts2的ActionContext中的對象,則在訪問這些對象時候,前面要加「#」。好比ognl.jsp中訪問session和request對象時候代碼中在request和session以前就有「#」。spa


對於數據集合類型,若是根據條件查詢該集合裏的數據,造成子集合的時候,經常使用的OGNL還有「?」、「^」、「$」。此三個符號中「?」是取得全部符合條件的數據時使用。「^」是取這些符合條件的數據中索引中第一個或第一條數據。而「$」則正好相反,是取得最後一個或最後一條數據。code


在OGNL中,還有lamuda表達式和不少計算公式的表達式,筆者認爲若是堅持鬆耦合理念的話,最好不要使用。畢竟OGNL更多使用在MVC模式中view和comtrol兩層,而計算公式等OGNL知識更多的和業務邏輯聯繫關聯比較大,因此本書就不作過多介紹。xml


(2)本示例中,首先建立了建築材料的模型對象。其中有材料名、材料價格、材料庫存量三個屬性。在OgnlExampleAction中作了兩件事情,一件事情是在request、session中各放入key爲「materialName」的值。另外一件事情是初始化三個材料對象,將這些對象放在 List類型的數據集合中。


而後在struts.xml中對OgnlExampleAction作定義,將其導航到ognl.jsp中。在該jsp中,讀者參看其代碼。首先將request、session中「materialName」的值用OGNL取出。由於request、session都不是值棧,因此在它們名字以前都以「#」開頭。在代碼中將以前List類型的數據集合中全部材料價格小於50的數據顯示出來。這裏用了「?」也就是以前所說去取符合條件的數據集時使用。


在取材料名爲「人造石臺面」的材料庫存量時候,OGNL先利用條件過濾獲得符合條件的材料對象集而後用「{}」去取庫存量屬性,再取該子集中第一個索引,這裏索引次序和Java中相同,也是從「0」開始代表集合中第一個元素。


在ognl.jsp中,OGNL也新建了一個Map對象,而後定義了該對象中的key和value。OGNL對於顯示Map對象中某個key的值採起ognl.jsp代碼中所示。「[]」中寫key的名字,並用‘’包含。


(3)OGNL中常常會有「#」、「%」、「$」三個符號。通常「#」都是像前文所述表明那些非值棧的對象。還有就是ognl.jsp中建立 Map對象時候用到。而「%」則是顯示對象中的值。至於「$」則是用來顯示屬性文件中定義的值。好比某屬性文件中定義了「kkk=10」則在 Struts2的struts.xml或者JSP文件中用「${kkk}」則系統會讀取「10」這個值做爲顯示值。

 

 (4)Struts2還提供了一些命名對象,這些命名對象與根對象無關,它們只是存在於Stack Context中。因此,訪問這些對象時須要使用#前綴來指明。


1.parameters對象:用於訪問HTTP請求參數。例如#parameters['foo']或#parameters.foo,用於返回調用HttpServletRequest的getParameter("foo")方法的返回值。
2.request對象:用於訪問HttpServletRequest的屬性。例如# request ['foo']或# request.foo,用於返回調用HttpServletRequest的getAttribute("foo")方法的返回值。
3.session對象:用於訪問HttpSession的屬性。例如# session ['foo']或# session.foo,用於返回調用HttpSession的getAttribute("foo")方法的返回值。
4.application對象:用於訪問ServletContext的屬性。例如# application ['foo']或# application.foo,用於返回調用ervletContext的getAttribute("foo")方法的返回值。
5.attr對象:該對象將依次搜索以下對象:PageContext、HttpServletRequest、HttpSession、ServletContext中的屬性。
注意:當系統建立了Action實例後,該Action實例已經被保存到ValueStack中,故無需書寫#便可訪問Action屬性。

相關文章
相關標籤/搜索