一下純屬個人總結摘抄,總結一起方便查看,解決疑問,有遺漏或錯誤,還請指出.
- a).JSTL標簽有什么用?
- b).什么是JSTL標簽?
JSP標准標簽庫(JSTL)是一個JSP標簽集合,它封裝了JSP應用的通用核心功能。
JSTL支持通用的、結構化的任務,比如迭代,條件判斷,XML文檔操作,國際化標簽,SQL標簽。 除了這些,它還提供了一個框架來使用集成JSTL的自定義標簽。
根據JSTL標簽所提供的功能,可以將其分為5個類別。
- 核心標簽
- 格式化標簽
- SQL 標簽
- XML 標簽
- JSTL 函數
- c).JSTL標簽怎么用?
Apache Tomcat安裝JSTL 庫步驟如下:
- 從Apache的標准標簽庫中下載的二進包(jakarta-taglibs-standard-current.zip)。下載地址:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/
- 下載jakarta-taglibs-standard-1.1.1.zip 包並解壓,將jakarta-taglibs-standard-1.1.1/lib/下的兩個jar文件:standard.jar和jstl.jar文件拷貝到/WEB-INF/lib/下。
核心標簽
核心標簽是最常用的JSTL標簽。引用核心標簽庫的語法如下:
<span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);"><%@</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> taglib prefix</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"c"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> uri</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"http://java.sun.com/jsp/jstl/core"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> %></span>
標簽 | 描述 |
---|---|
<c:out> | 用於在JSP中顯示數據,就像<%= ... > |
<c:set> | 用於保存數據 |
<c:remove> | 用於刪除數據 |
<c:catch> | 用來處理產生錯誤的異常狀況,並且將錯誤信息儲存起來 |
<c:if> | 與我們在一般程序中用的if一樣 |
<c:choose> | 本身只當做<c:when>和<c:otherwise>的父標簽 |
<c:when> | <c:choose>的子標簽,用來判斷條件是否成立 |
<c:otherwise> | <c:choose>的子標簽,接在<c:when>標簽后,當<c:when>標簽判斷為false時被執行 |
<c:import> | 檢索一個絕對或相對 URL,然后將其內容暴露給頁面 |
<c:forEach> | 基礎迭代標簽,接受多種集合類型 |
<c:forTokens> | 根據指定的分隔符來分隔內容並迭代輸出 |
<c:param> | 用來給包含或重定向的頁面傳遞參數 |
<c:redirect> | 重定向至一個新的URL. |
<c:url> | 使用可選的查詢參數來創造一個URL |
格式化標簽
JSTL格式化標簽用來格式化並輸出文本、日期、時間、數字。引用格式化標簽庫的語法如下:
<span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);"><%@</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> taglib prefix</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"fmt"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> uri</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"http://java.sun.com/jsp/jstl/fmt"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> %></span>
標簽 | 描述 |
---|---|
<fmt:formatNumber> | 使用指定的格式或精度格式化數字 |
<fmt:parseNumber> | 解析一個代表着數字,貨幣或百分比的字符串 |
<fmt:formatDate> | 使用指定的風格或模式格式化日期和時間 |
<fmt:parseDate> | 解析一個代表着日期或時間的字符串 |
<fmt:bundle> | 綁定資源 |
<fmt:setLocale> | 指定地區 |
<fmt:setBundle> | 綁定資源 |
<fmt:timeZone> | 指定時區 |
<fmt:setTimeZone> | 指定時區 |
<fmt:message> | 顯示資源配置文件信息 |
<fmt:requestEncoding> | 設置request的字符編碼 |
SQL標簽
JSTL SQL標簽庫提供了與關系型數據庫(Oracle,MySQL,SQL Server等等)進行交互的標簽。引用SQL標簽庫的語法如下:
<span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);"><%@</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> taglib prefix</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"sql"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> uri</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"http://java.sun.com/jsp/jstl/sql"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> %></span>
標簽 | 描述 |
---|---|
<sql:setDataSource> | 指定數據源 |
<sql:query> | 運行SQL查詢語句 |
<sql:update> | 運行SQL更新語句 |
<sql:param> | 將SQL語句中的參數設為指定值 |
<sql:dateParam> | 將SQL語句中的日期參數設為指定的java.util.Date 對象值 |
<sql:transaction> | 在共享數據庫連接中提供嵌套的數據庫行為元素,將所有語句以一個事務的形式來運行 |
XML 標簽
JSTL XML標簽庫提供了創建和操作XML文檔的標簽。引用XML標簽庫的語法如下:
<span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);"><%@</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> taglib prefix</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"x"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> uri</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"http://java.sun.com/jsp/jstl/xml"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> %></span>
在使用xml標簽前,你必須將XML 和 XPath 的相關包拷貝至你的<Tomcat 安裝目錄>\lib下:
-
<li
下載地址: http://www.apache.org/dist/xerces/j/
- xalan.jar:
標簽 | 描述 |
---|---|
<x:out> | 與<%= ... >,類似,不過只用於XPath表達式 |
<x:parse> | 解析 XML 數據 |
<x:set> | 設置XPath表達式 |
<x:if> | 判斷XPath表達式,若為真,則執行本體中的內容,否則跳過本體 |
<x:forEach> | 迭代XML文檔中的節點 |
<x:choose> | <x:when>和<x:otherwise>的父標簽 |
<x:when> | <x:choose>的子標簽,用來進行條件判斷 |
<x:otherwise> | <x:choose>的子標簽,當<x:when>判斷為false時被執行 |
<x:transform> | 將XSL轉換應用在XML文檔中 |
<x:param> | 與<x:transform>共同使用,用於設置XSL樣式表 |
JSTL函數
JSTL包含一系列標准函數,大部分是通用的字符串處理函數。引用JSTL函數庫的語法如下:
<span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);"><%@</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> taglib prefix</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"fn"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> uri</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"http://java.sun.com/jsp/jstl/functions"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> %></span>
函數 | 描述 |
---|---|
fn:contains() | 測試輸入的字符串是否包含指定的子串 |
fn:containsIgnoreCase() | 測試輸入的字符串是否包含指定的子串,大小寫不敏感 |
fn:endsWith() | 測試輸入的字符串是否以指定的后綴結尾 |
fn:escapeXml() | 跳過可以作為XML標記的字符 |
fn:indexOf() | 返回指定字符串在輸入字符串中出現的位置 |
fn:join() | 將數組中的元素合成一個字符串然后輸出 |
fn:length() | 返回字符串長度 |
fn:replace() | 將輸入字符串中指定的位置替換為指定的字符串然后返回 |
fn:split() | 將字符串用指定的分隔符分隔然后組成一個子字符串數組並返回 |
fn:startsWith() | 測試輸入字符串是否以指定的前綴開始 |
fn:substring() | 返回字符串的子集 |
fn:substringAfter() | 返回字符串在指定子串之后的子集 |
fn:substringBefore() | 返回字符串在指定子串之前的子集 |
fn:toLowerCase() | 將字符串中的字符轉為小寫 |
fn:toUpperCase() | 將字符串中的字符轉為大寫 |
fn:trim() | 移除首位的空白符 |
2,EL表達式
- a).EL表達式的好處和JSTL好處差不多,這里不再做介紹
- b).什么是EL表達式?
E L(Expression Language) 目的:為了使JSP寫起來更加簡單。表達式語言的靈感來自於 ECMAScript 和 XPath 表達式語言,它提供了在 JSP 中簡化表達式的方法。
- c).EL表達式怎么用?
true 和 false
|
與 Java 類似。可以包含任何正數或負數,例如 24、-45、567
|
與 Java 類似。可以包含任何正的或負的浮點數,例如 -1.8E-45、4.567
|
任何由單引號或雙引號限定的字符串。對於單引號、雙引號和反斜杠,使用反斜杠字符作為轉義序列。必須注意,如果在字符串兩端使用雙引號,則單引號不需要轉義。
|
null
|
術語
|
定義
|
---|---|
算術型
|
+、-(二元)、*、/、div、%、mod、-(一元)
|
邏輯型
|
and、&&、or、||、!、not
|
關系型
|
==、eq、!=、ne、lt、gt、<=、le、>=、ge。可以與其他值進行比較,或與布爾型、字符串型、整型或浮點型文字進行比較。
|
空
|
empty 空操作符是前綴操作,可用於確定值是否為空。
|
條件型
|
A ?B :C。根據 A 賦值的結果來賦值 B 或 C。
|
pageContext
|
JSP 頁的上下文。它可以用於訪問 JSP 隱式對象,如請求、響應、會話、輸出、servletContext 等。例如,${pageContext.response} 為頁面的響應對象賦值。
|
術語
|
定義
|
---|---|
param
|
將請求參數名稱映射到單個字符串參數值(通過調用 ServletRequest.getParameter (String name) 獲得)。getParameter (String) 方法返回帶有特定名稱的參數。表達式 ${param . name}相當於 request.getParameter (name)。
|
paramValues
|
將請求參數名稱映射到一個數值數組(通過調用 ServletRequest.getParameter (String name) 獲得)。它與 param 隱式對象非常類似,但它檢索一個字符串數組而不是單個值。表達式 ${paramvalues. name} 相當於 request.getParamterValues(name)。
|
header
|
將請求頭名稱映射到單個字符串頭值(通過調用 ServletRequest.getHeader(String name) 獲得)。表達式 ${header. name} 相當於 request.getHeader(name)。
|
headerValues
|
將請求頭名稱映射到一個數值數組(通過調用 ServletRequest.getHeaders(String) 獲得)。它與頭隱式對象非常類似。表達式 ${headerValues. name} 相當於 request.getHeaderValues(name)。
|
cookie
|
將 cookie 名稱映射到單個 cookie 對象。向服務器發出的客戶端請求可以獲得一個或多個 cookie。表達式 ${cookie. name .value} 返回帶有特定名稱的第一個 cookie 值。如果請求包含多個同名的 cookie,則應該使用 ${headerValues. name} 表達式。
|
initParam
|
將上下文初始化參數名稱映射到單個值(通過調用 ServletContext.getInitparameter(String name) 獲得)。
|
術語
|
定義
|
---|---|
pageScope
|
將頁面范圍的變量名稱映射到其值。例如,EL 表達式可以使用 ${pageScope.objectName} 訪問一個 JSP 中頁面范圍的對象,還可以使用 ${pageScope .objectName. attributeName} 訪問對象的屬性。
|
requestScope
|
將請求范圍的變量名稱映射到其值。該對象允許訪問請求對象的屬性。例如,EL 表達式可以使用 ${requestScope. objectName} 訪問一個 JSP 請求范圍的對象,還可以使用 ${requestScope. objectName. attributeName} 訪問對象的屬性。
|
sessionScope
|
將會話范圍的變量名稱映射到其值。該對象允許訪問會話對象的屬性。例如:
${sessionScope. name}
|
applicationScope
|
將應用程序范圍的變量名稱映射到其值。該隱式對象允許訪問應用程序范圍的對象。
|
特別強調
舉例說明
3,JSTL與EL的區別
JSTL(JSP Standard Tag Library,JSP標准標簽庫)是一個不斷完善的開放源代碼的JSP標簽庫,是由apache的jakarta小組來維護的。JSTL只能運行在支持JSP1.2和Servlet2.3規范的容器上,如tomcat 4.x。在JSP 2.0中也是作為標准支持的。
JSTL(JavaServerPages Standard Tag Library)JSP標准標簽庫
JSTL標准標簽庫包括核心標簽庫和SQL標簽庫,核心標簽庫常用的是if和forEach
EL即Expression Language(表達式語言)
EL的語法:${ EL exprission }
${ bean.name } 或 ${ bean['name'] }
說白了,EL是用來顯示數據的,功能跟<%=表達式%> 一樣,EL是不需要引入什么東西的
4, Struts2常用標簽總結
一 介紹1.Struts2的作用
Struts2標簽庫提供了主題、模板支持,極大地簡化了視圖頁面的編寫,而且,struts2的主題、模板都提供了很好的擴展性。實現了更好的代碼復用。Struts2允許在頁面中使用自定義組件,這完全能滿足項目中頁面顯示復雜,多變的需求。
Struts2的標簽庫有一個巨大的改進之處,struts2標簽庫的標簽不依賴於任何表現層技術,也就是說strtus2提供了大部分標簽,可以在各種表現技術中使用。包括最常用的jsp頁面,也可以說Velocity和FreeMarker等模板技術中的使用
2.Struts2分類
(1)UI標簽:(User Interface, 用戶界面)標簽,主要用於生成HTML元素標簽,UI標簽又可分為表單標簽非表單標簽
(2)非UI標簽,主要用於數據訪問,邏輯控制等的標簽。非UI標簽可分為流程控制標簽(包括用於實現分支、循環等流程控制的標簽)和數據訪問標簽(主要包括用戶輸出ValueStack中的值,完成國際化等功能的)
(3)ajax標簽
3.Struts2標簽使用前的准備:
(1)在要使用標簽的jsp頁面引入標簽庫:
<%@ taglib uri="/struts-tags" prefix="s"%>
(2)在web.xml中聲明要使用的標簽 這樣是struts2 2.3.1.2版本的引入方式
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter>
(1)property標簽
用於輸出指定的值:
<s:property value="%{@cn.csdn.hr.domain.User@Name}"/><br/> <s:property value="@cn.csdn.hr.domain.User@Name"/><Br/><!-- 以上兩種方法都可以 --> <s:property value="%{@cn.csdn.hr.domain.User@study()}"/>
以上可以訪問某一個包的類的屬性的集中方式,study()是訪問方法的方法,並輸出。
以下用java代碼代替的,訪問某一個范圍內的屬性
<%
//采用pageContext對象往page范圍內存入值來 驗證#attr搜索順序是從page開始的 ,搜索的順序為:page,reques,session,application。
set存值的時候存到的是request中,在jsp頁面中訪問的時候不用加任何的標識符,即可直接訪問,如果不同的作用域不一樣了,
pageContext.setAttribute("name", "laoowang", PageContext.PAGE_SCOPE); %> <s:property value="#attr.name" />
假設在action中設置了不同作用域的類
不同的作用域的標簽的訪問:<h3>獲取的是requet中的對象值</h3>
第一種方式:<s:property value="#request.user1.realName"/>
<br/>
第二種方式:<s:property value="#request.user1['realName']"/>
<br/>
第三種方式:<s:property value="#user1.realName"/>
<br/>
第四種方式:<s:property value="#user1['realName']"/>
<br/>
第五種方式:${requestScope.user1.realName } || ${requestScope.user1['realName'] }
第六種:<s:property value="#attr.user1.realName"/>
attr對象按page==> request sessionapplictio找的
<h3>獲取session中的值</h3>
第一種方式:<s:property value="#session.user1.realName"/>
<br/>
第二種方式:<s:property value="#session.user1['realName']"/>
第五種方式:${sessionScope.user1.realName } || ${sessionScope.user1['realName'] }
<h3>獲取application中的對象的值</h3>
第一種方式:<s:property value="#application.user1.realName"/>
<br/>
第二種方式:<s:property value="#application.user1['realName']"/>
第五種方式:${applicationScope.user1.realName } || ${applicationScope.user1['realName'] }
(2)iterator標簽的使用
第一種:list集合 <!-- 設置set集合 value--> <!-- status 可選屬性,該屬性指定迭代時的IteratorStatus實例 --> <!-- value="#attr.list" list存放到了request中 可以value="#request.list" statu.odd返回當前被迭代元素的索引是否是奇數 --> <s:set name="list" value="{'a','b','c','d'}"></s:set> <s:iterator var="ent" value="#request.list" status="statu"> <s:if test="%{#statu.odd}"> <font color="red"><s:property value="#ent" /> </font> </s:if> <s:else> <s:property value="#ent" /> </s:else> </s:iterator>
第二種:map集合中的使用
<h3>Map集合</h3> <!-- map集合的特點: 語法格式:# {key:value,key1:value1,key2:value2,.....} 以上的語法中就直接生成了一個Map類型的集合,該Map對象中的每個key-value對象之間用英文的冒號隔開 ,多個元素之間用逗號分隔。 --> </div> <s:set var="map" value="#{'1':'laowang','2':'老王','3':'猩猩'}"></s:set> 遍歷Map: <br /> <s:iterator value="#map"> <s:property value="key" />:::<s:property value="value" /> <Br /> </s:iterator>\
第三種:集合的變量
<h3>遍歷集合:::</h3>
<div> <!-- 遍歷出價格大於3000的 --> <s:iterator var="user" value="#session['users']"> <s:if test="%{#user['price']>3000}"> <s:property value="#user['price']"/> </s:if> </s:iterator> <hr color="blue"/><!-- $是取出價格 大於3000的最后一個值 --> <s:iterator var="u" value="#session.users.{$(#this['price']>3000)}"> <s:property value="price"/> </s:iterator> </div>
注:users是User的對象,price是User中的一個屬性
簡述一下iterator的介紹:
iterator標簽用於對集合進行迭代,這里的集合包含List、Set和數組。
<s:set name="list" value="{'zhangming','xiaoi','liming'}" /> <s:iterator value="#list" status="st"> <font color=<s:if test="#st.odd">red</s:if><s:else>blue</s:else>> <s:property /></font><br> </s:iterator>
value:可選屬性,指定被迭代的集合,如果沒有設置該屬性,則使用ValueStack棧頂的集合。
id:可選屬性,指定集合里元素的id。status:可選屬性,該屬性指定迭代時的IteratorStatus實例。該實例包含如下幾個方法:
int getCount(),返回當前迭代了幾個元素。
int getIndex(),返回當前迭代元素的索引。
boolean isEven(),返回當前被迭代元素的索引是否是偶數
boolean isOdd(),返回當前被迭代元素的索引是否是奇數
boolean isFirst(),返回當前被迭代元素是否是第一個元素。
boolean isLast(),返回當前被迭代元素是否是最后一個元素。
(3)if else語句的使用
<s:set name="age" value="21" /> <s:if test="#age==23"> 23 </s:if> <s:elseif test="#age==21"> 21 </s:elseif> <s:else> 都不等 </s:else>
(4)URL標簽
<!-- 聲明一個URL地址 --> <s:url action="test" namespace="/tag" var="add"> <s:param name="username">laowangang</s:param> <s:param name="id">12</s:param> </s:url> <s:a href="%{add}">測試URL</s:a> <s:a action="test" namespace="/tag"></s:a>
以上的兩個<s:a>標簽的作用是一樣的。
(5)data標簽
<% pageContext.setAttribute("birth",new Date(200,03,10),PageContext.REQUEST_SCOPE); %> <s:date name="#request.birth" format="yyyy年MM月dd日"/> <s:date name="#request.birth" nice="true"/>
這個標簽是按照format的格式去輸出的。
(6)表單
<h1>from表單</h1> <s:form action="test" namespace="/tag"> <s:textfield label="用戶名" name="uname" tooltip="你的名字" javascriptTooltip="false"></s:textfield> <s:textarea name="rmake" cols="40" rows="20" tooltipDelay="300" tooltip="hi" label="備注" javascriptTooltip="true"></s:textarea> <s:password label="密碼" name="upass"></s:password> <s:file name="file" label="上傳文件"></s:file> <s:hidden name="id" value="1"></s:hidden> <!-- <select name="edu"> <option value="listKey">listValue</option> --> <s:select list="#{'1':'博士','2':'碩士'}" name="edu" label="學歷" listKey="key" listValue="value"></s:select> <s:select list="{'java','.net'}" value="java"></s:select><!-- value是選中的 --> <!-- 必須有name --> <s:checkbox label="愛好 " fieldValue="true" name="checkboxFiled1"></s:checkbox> <!-- 多個checkbox --> <s:checkboxlist list="{'java','css','html','struts2'}" label="喜歡的編程語言" name="box" value="{'css','struts2'}"></s:checkboxlist> <!-- map集合前要加# --> <s:checkboxlist list="#{1:'java',2:'css',3:'html',4:'struts2',5:'spring'}" label="喜歡的編程語言" name="boxs" value="{1,2}"></s:checkboxlist> <!-- listKey listValue <input type="text" name="boxs" value="listKey">顯示值listValue --> <!-- radio --> <% //從服務器傳過來值 pageContext.setAttribute("sex","男",PageContext.REQUEST_SCOPE); pageContext.setAttribute("sex1","男",PageContext.REQUEST_SCOPE); %> <s:radio list="{'男','女'}" name="sex" value="#request.sex"></s:radio> <s:radio list="#{1:'男',2:'女'}" name="sex1" listKey="key" listValue="value" value="#request.sex1"></s:radio> <!-- 防止表單提交的方式 --> <s:token></s:token> <s:submit value="提交"></s:submit> </s:form>
5,ognl表達式
OGNL全名Object Graph Navigation Language,可認為是更完美EL表達式。
它可以真正意義上代替個傳統jsp服務器腳本(<%%>)。本文不闡述OGNL的優勢,志在為幫助大家理解並學習OGNL。
以下是struts2中的OGNL。
OGNL的表達式的資料確實不少,但幾乎都是同一個版本,並且筆者真的有懷疑此版本的作者在一些關鍵問題上要么就是自己也沒弄清楚,要么就是表達有問題,總之很容易就把簡單的東西放到雲里霧里。
下面讓我來給大家理理思路。
1. OGNL有什么內容。
OGNL的標准結構包含OGNL Context和ValueStack兩部分。
其中OGNL Context與傳統的EL表達式大徑相同,包含有parameterMap,requestAttributeMap,sessionAttributeMap,applicationAttributeMap
而struts2 OGNL的ValueStack被指定為ActionContext。ActionContext是stack(先進后出的結構)的根節點,而Action中的屬性成員則是stack的頂節點(第一層)。
2. 我們先要明白OGNL能實現到什么程度的功能。
第一,OGNL是JSP腳本的替代品,又是EL,那么它一定是運行在服務器之上的。
第二,OGNL可以page,request,session,application的attribute,request的parameter范圍的數據,與一般的EL一致
第三,OGNL可以訪問Struts2中Action的屬性。非常實用的數據綁定效果。
第四,OGNL可以創建對象,並且定制對象的數據。一般EL沒有的功能呢個,彌補一大缺陷
3. OGNL的格式。
Struts2的OGNL表達式主要涉及#%$三個特殊符號。這里我們需要強調的是實際上OGNL的范疇中只有#%兩個特殊符號,而$並不屬於OGNL。這是許多OGNL資料中造成誤解的主要地方。下面筆者具體說明它們的用法。
# 是OGNL查找符,當目標對象在根部或頂部,也就是根部的第一層樹節點時,可直接使用對象名,並且必須只寫對象名,不可使用#以作為區分。
struts2 OGNL的查找范圍為OGNL context和ActionContext,其包含下面是頂節點:
名稱 作用 例子
parameters 包含當前HTTP請求參數的Map #parameters.id[0]作用相當於request.getParameter("id")
request 包含當前HttpServletRequest的屬性(attribute)的Map #request.userName相當於request.getAttribute("userName")
session 包含當前HttpSession的屬性(attribute)的Map #session.userName相當於session.getAttribute("userName")
application 包含當前應用的ServletContext的屬性(attribute)的Map #application.userName相當於application.getAttribute("userName")
attr 用於按request > session > application順序訪問其屬性(attribute) #attr.userName相當於按順序在以上三個范圍(scope)內讀取userName屬性,直到找到為止 (value Stack) Action類的屬性 #login.name相當於對應的Action類的name屬性訪問,可省略#如name但要求其actionName為login
其中parameters,request,session,application屬於OGNL context范疇,而valuestack屬於ActionContext范疇。
也就是說當使用parameters,request,session,application以及Action類的屬性時#可省略,但這些非根非頂節點是必須完整給出#符號。
值得注意的是:除了ValueStack可以按照javaBean的getter/setter原則展開對象視圖OG,也就是Action類的成員屬性可按照getter方式查找;其余頂節點都是Map數據,只能查找自身所含的數據。我們說parameters是requestParameterMap;request是requestAttributeMap;session是sessionAttributeMap;application是applicationAttributeMap;attr是page,request,session,application的attributeMap
另外#在集合中可以作為篩選元素的條件,如books.{?#this.price<100} //其中books是Action類的集合元素
格式#{數據1,數據2...}可以創建集合對象並引用其值
這里我們需要深入的去理解什么是頂節點和非頂節點?
其實非常簡單以javaBean的getter/setter訪問規則取到的對象就是棧頂頂節點,而非棧頂節點就是非頂節點。
而OGNL巧妙的用#符號標識了頂節點和非頂節點,如上述所說頂節點可不寫#而且必須不寫,非頂節點必須寫#;
當然struts2已經預設了parameters,request,session,application和Action屬性成員這么些頂節點供直接訪問。
這就可以讓OGNL知道查找對象的規則了。
請看下列表達式:
user.name 訪問路徑為Action成員getUser().getName();棧頂節點
#user.name 訪問路徑為Action成員getUser().iterator().........
其實OGNL數據視圖原理是基於對象數量級關系比所展開的視圖,也就是說1:1的情況是javaBean的getter/setter,也就是OGNL稱之的"頂節點",而1:n的情況時1為頂訪問n則需要注明非頂節點#。從上面的例子不難看出,OGNL的視圖中只有集合/集合的元素與非集合兩種類型,所以使用OGNL時我們僅需要記住一點集合屬性或集合元素都要使用#
解釋為何OGNL訪問根不用#,而頂節點也不用#呢?實際上頂節點對應的只是根節點的getter方法,也就訪問的只是根節點。
另外我還要強調一點,parameters,request,session,application並不是出自ActionContext,原因是request沒有getter方法,實際上他是另外加入的。
% 將字符串變量的值按照OGNL表達式解析。也就是說字符串中#將按照特殊字符處理,僅此作用。
以上是OGNL的內容,接下來我們說說$的用法。
需要注意的是OGNL目前只能運行在標簽中取值處,筆者認為未來的OGNL一定可以脫離標簽項EL表達式的寫法那樣,這已經是大勢所趨了
$ {}實際上傳統EL的寫法,是告知服務器在后台運行.
OGNL需要聯合<s:property/>等標簽庫使用就擁有了OGNL表達式的運行環境,但離開標簽庫表達式只是普通的字符串,所以${}目前尚未提供OGNL表達式的運行環境。以往Struts的EL以后能完善此項功能。
這里簡單的介紹EL:
struts的EL與OGNL的概念上有重復,其操作符號為. 並且預設了page,request,sesion等AtrributeMap,parameterMap對象限定只能查詢Map所包含的內容,僅提供pageContext對象可使用javaBean的getter;操作上不分層必須以預設對象開始
總結:OGNL實際上最終發揮作用的是#,而%按照字符串轉換#(省略#是頂節點),${}是傳統的EL表達式