Struts推薦使用功能更加強大的Ognl表達式。El可以完成的功能,Ognl也可以,El不能完成的功能,Ognl也可以。
但是有些程序員,已經(jīng)習慣了jsp中結(jié)合jstl和el表達式,我們可以有兩種解決方案:
1.使用struts2自帶的標簽庫,jsp中使用ognl進行操作。
2.不是用struts2自帶的標簽庫,jsp直接結(jié)合jstl+el進行操作。
jsp2.0中默認啟動對el表達式的支持的。但從Struts2.0.11起,Struts2標簽庫將不再支持El表達式。
struts2.0.11版本不支持el,因而以前在低版本下寫和程式將不能正常運行:
下面是一段分頁所用的循環(huán): <c:forEach var="i" begin="1" end="${requestScope.page.afterPage}" step="1"> <c:if test="${requestScope.page.indexPage<requestScope.page.totalPage && requestScope.page.indexPage+i<requestScope.page.totalPage}"> <s:url id="afterUrl" value="/photoItemsList.html"> <s:param name="indexPage" value="${requestScope.page.indexPage+i}" /><!-- struts2.0.11中已不支持el,因而<s:url>將取不到相關(guān)值--> </s:url> <s:a theme="ajax" href="%{afterUrl}" indicator="indicator" showLoadingText="false" targets="pageItems"> <c:out value="${requestScope.page.indexPage+i}" /> </s:a> </c:if> </c:forEach> 修改成如下:
<c:forEach var="i" begin="1" end="${requestScope.page.afterPage}" step="1"> <c:set value="${i}" var="var"/> <c:if test="${requestScope.page.indexPage<requestScope.page.totalPage && requestScope.page.indexPage+i<requestScope.page.totalPage}"> <s:url id="afterUrl" value="/photoItemsList.html"> <s:param name="indexPage" value="#request.page.indexPage+#attr.var" /> </s:url> <s:a theme="ajax" href="%{afterUrl}" indicator="indicator" showLoadingText="false" targets="pageItems"> <c:out value="${requestScope.page.indexPage+i}" /> </s:a> </c:if> </c:forEach> 但我們使用第二種方式時,el可以訪問struts2,valuestack中的值。
El表達式使用,還是像以前一樣的,但是struts2中添加了一個值棧對象,所以有些小小的變動,搜索的順序是Page,Reqeust,ValueStack,Session,Application。
值棧中存儲的是Action類中的全局變量(在servlet,struts中是不支持直接讀取Action類中的值得,要設置到Request,Session等中,進行值得傳遞)。
測試程序(服務器端):
package com.helloweenvsfei.struts2.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class OgnlElAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
private int i;//來自客戶端,能取得
private String j;//額外定義,能取得
private String c="C";//沒有get,set方法,EL不能獲取
public String getJ() {
j="J";
return j;
}
public void setJ(String j) {
this.j = j;
}
@Override
public String execute() throws Exception {
i=i+100;
String a="wla";//不能獲取,除非設值到request等范圍
String b="wlb";//不能獲取,除非設值到request等范圍
HttpServletRequest request=ServletActionContext.getRequest();
// request.setAttribute("a", "locala");
// HttpSession session=request.getSession();
// session.setAttribute("b", "localb");
//要是在取值是沒有響應的屬性,就是默認值。
request.setAttribute("f", "localf");
request.setAttribute("d", "four local");
HttpSession session=request.getSession();
session.setAttribute("d", "locald");
// 以上三句說明,是按照順序進行查找的。
//request.setAttribute("j", "action");
//session.setAttribute("j", "action");
//總結(jié)出EL的訪問順序,Page,Request,ValueStack,Session,Application
return SUCCESS;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
客戶端:
<body>
<%-- <% String j="page"; %>
<% pageContext.setAttribute("j","MLDN") ;
%>
--%>
This is my JSP page. <br>
Action:${i};<br/>
Action:${j};<br/>
Action:${c};<br/>
Execute:${requestScope.a};<br/>
Execute:${sessionScope.b};<br/>
Execute:$a0kmigi;<br/>
Execute:${f};<br/>
<!-- Execute:${requestScope.a};
Execute:${sessionScope.b}; -->
<!--<s:property value="#session.i"/>-->
</body>
關(guān)于OGNL:
OGNL全稱為Object-Graph Navigation Language,是一種表達式語言(EL)。
EL的支持者認為,在JSP頁面中應盡可能地避免 <% %> 這樣的標記,而代之以Tag,以使頁面更簡潔,并體現(xiàn)頁面與后臺代碼分離的設計原則。對此我持保留意見,因為我并不認為使用Tag后的頁面的可讀性要高于使用<% %>。
Struts 2支持如下幾種EL:
· OGNL(Object-Graph Navigation Language): 可以方便地操作對象屬性的開源表達式語言
· JSTL(JSP Standard Tag Library): JSP 2.0集成的標準的表達式語言
· Groovy: 基于Java平臺的動態(tài)語言,它具有時下比較流行的動態(tài)語言(如Python、Ruby和Smarttalk等)的一些新特性
· Velocity: 嚴格來說不是表達式語言,它是一種基于Java的模板匹配引擎,據(jù)說其性能要比JSP好
Struts 2默認的表達式語言是OGNL,原因是它相對其它表達式語言具有下面幾大優(yōu)勢:
· 支持對象方法調(diào)用,如xxx.doSomeSpecial();
· 支持類靜態(tài)的方法調(diào)用和值訪問,表達式的格式為@[類全名(包括包路徑)]@[方法名 | 值名],例如: @java.lang.String@format('foo %s', 'bar')或 @tutorial.MyConstant@APP_NAME;
· 支持賦值操作和表達式串聯(lián),如price=100, discount=0.8, calculatePrice(),這個表達式會返回80;
· 訪問OGNL上下文(OGNL context)和ActionContext;
· 操作集合對象。
OGNL是通常要結(jié)合Struts 2的標志一起使用,如<s:property value="xx" />等。大家經(jīng)常遇到的問題是#、%和$這三個符號的使用。下面我講述這個問題:
4.1 “#”的用途
訪問OGNL上下文和Action上下文
#相當于ActionContext.getContext();下表有幾個ActionContext中有用的屬性:
· parameters:包含當前HTTP請求參數(shù)的Map,#parameters.id[0]作用相當于request.getParameter("id")
· request:包含當前HttpServletRequest的屬性(attribute)的Map,#request.userName相當于request.getAttribute("userName")
· session:包含當前HttpSession的屬性(attribute)的Ma, #session.userName相當于session.getAttribute("userName")
· application:包含當前應用的ServletContext的屬性(attribute)的Map,#application.userName相當于application.getAttribute("userName")
· attr:用于按request > session > application順序訪問其屬性(attribute),#attr.userName相當于按順序在以上三個范圍(scope)內(nèi)讀取userName屬性,直到找到為止
過濾和投影(projecting)集合
如books.{?#this.price<100}
構(gòu)造Map
如#{'foo1':'bar1', 'foo2':'bar2'}
4.2 %的用法
“%”符號的用途是在標志的屬性為字符串類型時,計算OGNL表達式的值。例如在Ognl.jsp中加入以下代碼:
<h3>%的用途</h3><p><s:url value="#foobar['foo1']" /></p><p><s:url value="%{#foobar['foo1']}" /></p>
刷新頁面,顯示以下內(nèi)容
%的用途#foobar['foo1']bar1
4.3 $的用法
“$”有兩個主要的用途:
1. 用于在國際化資源文件中,引用OGNL表達式
2. Struts 2配置文件中,引用OGNL表達式,如
<action name="AddPhoto" class="addPhoto"> <interceptor-ref name="fileUploadStack" /> <result type="redirect">ListPhotos.action?albumId=${albumId}</result></action>
|
|
來自: champion999 > 《javaweb》