Struts2 標(biāo)簽庫 [Tablib] (轉(zhuǎn))
2007-09-05 17:03:55
標(biāo)簽:
Struts2Struts標(biāo)簽庫Tablib [
推送到技術(shù)圈]
Struts2 標(biāo)簽庫 [Tablib] (轉(zhuǎn))
Struts2 Taglib抽象了不同表示技術(shù),現(xiàn)在Struts2主要支持三種表示技術(shù):JSP,FreeMarker和Velocity。但部分的Tag在三種表示技術(shù)下都可以使用,但是也有部分只能在某一種情況下使用。
Tab可以分為兩類:通用標(biāo)簽和UI標(biāo)簽。
4.1節(jié) 通用標(biāo)簽
通用標(biāo)簽用來在頁面表示的時候控制代碼執(zhí)行的過程,這些標(biāo)簽也允許從Action或者值堆棧中取得數(shù)據(jù)。例如地域,JavaBeans,URLs,和action。
控制標(biāo)簽控制程序執(zhí)行,例如:if,else,iterator
數(shù)據(jù)標(biāo)簽管理數(shù)據(jù)的取得和創(chuàng)建,例如:bean,push,i18n
控制標(biāo)簽
if標(biāo)簽
描述
If標(biāo)簽用來控制基本的條件處理流程,通常和else標(biāo)簽或者elseif標(biāo)簽連用。
參數(shù)
名字
是否必須
默認(rèn)值
可否使用表達(dá)式
類型
描述
id
否
是
String
用來表示該元素,對于UI和Form標(biāo)簽來說直接轉(zhuǎn)變?yōu)镠TML id屬性
test
是
是
Boolean
用來決定是否顯示標(biāo)簽內(nèi)部內(nèi)容的表達(dá)式
例子
<s:if test="%{false}">
<div>Will Not Be Executed</div>
</s:if>
<s:elseif test="%{true}">
<div>Will Be Executed</div>
</s:elseif>
<s:else>
<div>Will Not Be Executed</div>
</s:else>
elseIf 標(biāo)簽
參考if標(biāo)簽
else 標(biāo)簽
參考if標(biāo)簽
append標(biāo)簽
描述
用來做iterator標(biāo)簽的輔助,將不同iterator中的內(nèi)容合在一個iterator中。
參數(shù)
名字
是否必須
默認(rèn)值
可否使用表達(dá)式
類型
描述
id
否
是
String
用來保存結(jié)果iterator的對象在value context中的名字。
例子
Action類
public class AppendIteratorTagAction extends ActionSupport {
private List myList1;
private List myList2;
private List myList3;
public String execute() throws Exception {
myList1 = new ArrayList();
myList1.add("1");
myList1.add("2");
myList1.add("3");
myList2 = new ArrayList();
myList2.add("a");
myList2.add("b");
myList2.add("c");
myList3 = new ArrayList();
myList3.add("A");
myList3.add("B");
myList3.add("C");
return "done";
}
public List getMyList1() { return myList1; }
public List getMyList2() { return myList2; }
public List getMyList3() { return myList3; }
標(biāo)簽使用
<s:append id="myAppendIterator">
<s:param value="%{myList1}" />
<s:param value="%{myList2}" />
<s:param value="%{myList3}" />
</s:append>
<s:iterator value="%{#myAppendIterator}">
<s:property />
</s:iterator>
generator 標(biāo)簽(JSP Tag)
描述
從val屬性生成一個iterator。
參數(shù)
例子
例1:
生成一個簡單的iterator,并且使用iterator標(biāo)簽打印出內(nèi)容。
<s:generator val="%{'aaa,bbb,ccc,ddd,eee'}">
<s:iterator>
<s:property /><br/>
</s:iterator>
</s:generator>
例2:
生成一個iterator,使用count屬性。因為count屬性值為3,所以只有前三個內(nèi)容(aaa,bbb,ccc)在生成的iterator中。
Generate an iterator with count attribute
<s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="3">
<s:iterator>
<s:property /><br/>
</s:iterator>
</s:generator>
例3:
生成iterator,使用了id屬性,之后生成的對象放在pageContext中,可以通過指定的id來訪問。
<s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="4" separator="," id="myAtt" />
<%
Iterator i = (Iterator) pageContext.getAttribute("myAtt");
while(i.hasNext()) {
String s = (String) i.next();
%>
<%= s %> <br/>
<%
}
%>
例4:
生成iterator,使用converter屬性,這里的convertor僅僅將每一個對象添加了一個"converter-"前綴。
<s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" converter="%{myConverter}">
<s:iterator>
<s:property /><br/>
</s:iterator>
</s:generator>
public class GeneratorTagAction extends ActionSupport {
....
public Converter getMyConverter() {
return new Converter() {
public Object convert(String value) throws Exception {
return "converter-"+value;
}
};
}
...
}
iterator 標(biāo)簽
描述
迭代處理一個java.util.Connection或者java.util.Iterator對象
參數(shù)
名字
是否必須
默認(rèn)值
可否使用表達(dá)式
類型
描述
id
否
是
String
Id,
status
否
否
是
Boolean
如果指定,在循環(huán)的過程中會保留一個IteratorStatus類型的變量,該變量用來查詢當(dāng)前迭代的狀態(tài)
value
否
是
String
被迭代的對象
例子
例1:
<s:iterator value="days">
<p>day is: <s:property/></p>
</s:iterator>
例2:
<s:bean name="org.apache.struts2.example.IteratorExample" id="it">
<s:param name="day" value="'foo'"/>
<s:param name="day" value="'bar'"/>
</s:bean>
<p/>
<table border="0" cellspacing="0" cellpadding="1">
<tr>
<th>Days of the week</th>
</tr>
<p/>
<s:iterator value="#it.days" status="rowstatus">
<tr>
<s:if test="#rowstatus.odd == true">
<td style="background: grey"><s:property/></td>
</s:if>
<s:else>
<td><s:property/></td>
</s:else>
</tr>
</s:iterator>
</table>
例3:
<s:iterator value="groupDao.groups" status="groupStatus">
<tr
class="<s:if test="#groupStatus.odd == true ">odd</s:if><s:else>even</s:else>">
<td><s:property value="name" /></td>
<td><s:property value="description" /></td>
<td>
<s:iterator value="users" status="userStatus">
<s:property value="fullName" />
<s:if test="!#userStatus.last">,</s:if>
</s:iterator>
</td>
</tr>
</s:iterator>
merge 標(biāo)簽(同append?)
描述
參數(shù)
例子
sort 標(biāo)簽(JSP-Tag)
描述
對一個可以迭代的對象進(jìn)行排序操作。
參數(shù)
名字
是否必須
默認(rèn)值
可否使用表達(dá)式
類型
描述
Comparator
是
是
java.util.Comparator
排序用的比較器
Source
否
是
String
排序?qū)ο?div style="height:15px;">
例子
例1:
<s:sort comparator="myComparator" source="myList">
<s:iterator>
<!-- do something with each sorted elements -->
<s:property value="..." />
</s:iterator>
</s:sort>
例2:
<s:sort id="mySortedList" comparator="myComparator" source="myList" />
<%
Iterator sortedIterator = (Iterator) pageContext.getAttribute("mySortedList");
for (Iterator i = sortedIterator; i.hasNext(); ) {
// do something with each of the sorted elements
}
%>
subset
描述
遞歸iterator的一部分
參數(shù)
名字
是否必須
默認(rèn)值
可否使用表達(dá)式
類型
描述
count
False
是
Integer
Iterator中被遞歸的一部分的item的數(shù)量
Decider
否
是
org.apache.struts2.util.
SubsetIteratorFilter.Decider
用來判斷iterator中的item是否包含在最終的subset內(nèi)部
Source
否
是
String
Iterator的對象
Start
否
是
Integer
開始位置
例子
Java類
public class MySubsetTagAction extends ActionSupport {
public String execute() throws Exception {
l = new ArrayList();
l.add(new Integer(1));
l.add(new Integer(2));
l.add(new Integer(3));
l.add(new Integer(4));
l.add(new Integer(5));
return "done";
}
public Integer[] getMyArray() {
return a;
}
public List getMyList() {
return l;
}
public Decider getMyDecider() {
return new Decider() {
public boolean decide(Object element) throws Exception {
int i = ((Integer)element).intValue();
return (((i % 2) == 0)?true:false);
}
};
}
}
<!-- s: List basic -->
<s:subset source="myList">
<s:iterator>
<s:property />
</s:iterator>
</s:subset>
<!-- B: List with count -->
<s:subset source="myList" count="3">
<s:iterator>
<s:property />
</s:iterator>
</s:subset>
<!-- C: List with start -->
<s:subset source="myList" count="13" start="3">
<s:iterator>
<s:property />
</s:iterator>
</s:subset>
<!-- D: List with id -->
<s:subset id="mySubset" source="myList" count="13" start="3" />
<%
Iterator i = (Iterator) pageContext.getAttribute("mySubset");
while(i.hasNext()) {
%>
<%=i.next() %>
<% } %>
<!-- D: List with Decider -->
<s:subset source="myList" decider="myDecider">
<s:iterator>
<s:property />
</s:iterator>
</s:subset>
數(shù)據(jù)標(biāo)簽
@TODO 完成如下數(shù)據(jù)標(biāo)簽
數(shù)據(jù)標(biāo)簽包括
a
action
bean
date
debug
i18n
include
param
push
set
text
url
property
4.2節(jié) UI標(biāo)簽
UI標(biāo)簽主要是指Form相關(guān)的標(biāo)簽,UI標(biāo)簽又分為兩部分:form標(biāo)簽和構(gòu)成form內(nèi)部字段的其他標(biāo)簽。
每一個UI標(biāo)簽都是基于模板的,即:每一個標(biāo)簽都有一個對應(yīng)的模板用來生成UI標(biāo)簽的樣式,詳細(xì)內(nèi)容參看模板節(jié)。
所有的UI標(biāo)簽都有著共通的祖先UIBean,UIBean提供了這些UI標(biāo)簽的一系列共通的屬性,這些屬性可以分為三類:模版相關(guān)的屬性,JavaScript相關(guān)的屬性和其他通用屬性。
模版相關(guān)屬性:
屬性
主題
數(shù)據(jù)類型
說明
templateDir
n/a
String
定義模版目錄
theme
n/a
String
定義主題的名字
template
n/a
String
定義模版名字
JavaScript相關(guān)屬性:
屬性
主題
數(shù)據(jù)類型
說明
onclick
simple
String
html javascript onclick 屬性
ondbclick
simple
String
html javascript ondbclick屬性
onmousedown
simple
String
html javascript onmousedown屬性
onmouseup
simple
String
html javascript onmouseup屬性
onmouseover
simple
String
html javascript onmouseover屬性
onmouseout
simple
String
html javascript onmouseout屬性
onfocus
simple
String
html javascript onfocus屬性
onblur
simple
String
html javascript onblur屬性
onkeypress
simple
String
html javascript onkeypress屬性
onkeyup
simple
String
html javascript onkeyup屬性
onkeydown
simple
String
html javascript onkeydown屬性
onselect
simple
String
html javascript onselect屬性
onchange
simple
String
html javascript onchange屬性
Tooltip相關(guān)屬性:
屬性
數(shù)據(jù)類型
默認(rèn)值
說明
tooltip
String
none
為指定的組件設(shè)置Tooltip
jsTooltipEnabled
String
false
使用js表示tooltip
tooltipIcon
String
/struts/static/tooltip/tooltip.gif
指向tooltip圖表的URL
tooltipDelay
String
500
多長時間后顯示Tooltip
key
simple
String
這個輸入字段對應(yīng)的屬性,用來自動設(shè)置name,label和value
通用屬性:
屬性
主題
數(shù)據(jù)類型
說明
cssClass
simple
String
定義html class 屬性
cssStyle
simple
String
定義html style屬性
title
simple
String
定義html title屬性
disabled
simple
String
定義html disabled屬性
label
xhtml
String
定義form字段的標(biāo)簽
labelPosition
xhtml
String
定義標(biāo)簽在Form中的位置,從左從上計算
requiredPosition
xhtml
String
定義必須的標(biāo)簽在Form中的位置,從左從上計算
name
simple
String
定義form字段的name映射
required
xhtml
Boolean
在label上添加一個*
tabIndex
simple
String
定義 html tabIndex屬性
value
simple
Object
定義form字段的值
對于name和value的說明:
name用來說明Form字段的名字,和Action類的屬性對應(yīng)。
value用來記錄Form字段的值,和Action類中屬性的值對應(yīng)。
所以在修改一個字段的內(nèi)容的時候應(yīng)該使用如下的標(biāo)簽:
<s:form action="updateAddress">
<s:textfield label="Postal Code" name="postalCode" value="%{postalCode}"/>
...
</s:form>
但是,由于name和value的關(guān)系,struts2標(biāo)準(zhǔn)標(biāo)簽可以自動對應(yīng),所以也可以使用如下標(biāo)簽:
<s:form action="updateAddress">
<s:textfield label="Postal Code" name="postalCode" />
...
</s:form>
UI標(biāo)簽說明:
Form部分
autocompleter
checkbox
checkboxlist
combobox
datetimepicker
doubleselect
head
file
form
hidden
label
optiontransferselect
optgroup
password
radio
reset
select
submit
textarea
textfield
token
updownselect
非Form部分:
actionerror
actionmessage
component
div
fielderror
table
tabbedPanel
tree
treenode
4.3節(jié) 主題和模板
概念說明:
標(biāo)簽(tag):一小段代碼,在JSP,Velocity或者FreeMarker中執(zhí)行。程序開發(fā)的最小單位,用來生成HTML對應(yīng)的元素。
模板(template):一些代碼,通常使用FreeMarker寫成,可以被某些Tag表示出來(通常是UI Tag)。
主題(theme):一組模板打包在一起,提供通用功能的模版
主題和模板主要針對可視化的標(biāo)簽(Tag)而言,使用以下例子來說明三者之間的關(guān)系。
假如我們要開發(fā)如下的一個畫面:
我們使用如下的代碼:
<s:url action="login" id="loginUrl"></s:url>
<s:form action="%{loginUrl}">
<s:textfield label="Name" name="name"/>
<s:password label="Password" name="password" />
<s:submit></s:submit>
<s:reset></s:reset>
</s:form>
這里<s:form>,<s:textfield>,<s:password>,<s:submit>,<s:reset>每一個都是一個標(biāo)簽(tag)。
我們在看看這些標(biāo)簽在一起生成的HTML源代碼:
<form id="login" onsubmit="return true;"
action="/login/login/login.action" method="post">
<table class="wwFormTable">
<tr>
<td class="tdLabel">
<label for="login_name" class="label">
Name:
</label>
</td>
<td>
<input type="text" name="name"
value="" id="login_name" />
</td>
</tr>
<tr>
<td class="tdLabel">
<label for="login_password" class="label">
Password:
</label></td>
<td>
<input type="password"
name="password" id="login_password" />
</td>
</tr>
<tr>
<td colspan="2">
<div align="right"><input type="submit" id="login_0"
value="Submit" /></div>
</td>
</tr>
<tr>
<td colspan="2">
<div align="right"><input type="reset"
value="Reset" /></div>
</td>
</tr>
</table>
</form>
在由標(biāo)簽生成HTML代碼的時候,例如:
<s:textfield label="Name" name="name"/>
生成的代碼為:
<tr>
<td class="tdLabel">
<label for="login_name" class="label">
Name:
</label>
</td>
<td>
<input type="text" name="name" value="" id="login_name" />
</td>
</tr>
我們可以看到,<s:textfield>標(biāo)簽提供的有效信息只有Name和name,而其余的部分,例如<tr>,<td>,<label>等代碼都根據(jù)一個固定的模板文件生成,這個模板文件為:
標(biāo)簽使我們開發(fā)JSP畫面的時候使用的最小組件單元,我們根據(jù)客戶的需要組合各種Tag達(dá)到客戶的需求。模板是生成這些Tag時候使用的,使用模板可以定義Tag的基本形式,在使用tag的時候,我們只需要指定該Tag的不同屬性,即可根據(jù)Tag指定的特殊屬性,結(jié)合模板的基本屬性生成可視化的HTML元素。主題是不同tag結(jié)合在一起而形成的。
<input type="text"<#rt/>
name="${parameters.name?default("")?html}"<#rt/>
<#if parameters.get("size")?exists>
size="${parameters.get("size")?html}"<#rt/>
</#if>
<#if parameters.maxlength?exists>
maxlength="${parameters.maxlength?html}"<#rt/>
</#if>
<#if parameters.nameValue?exists>
value="<@s.property value="parameters.nameValue"/>"<#rt/>
</#if>
<#if parameters.disabled?default(false)>
disabled="disabled"<#rt/>
</#if>
<#if parameters.readonly?default(false)>
readonly="readonly"<#rt/>
</#if>
<#if parameters.tabindex?exists>
tabindex="${parameters.tabindex?html}"<#rt/>
</#if>
<#if parameters.id?exists>
id="${parameters.id?html}"<#rt/>
</#if>
<#if parameters.cssClass?exists>
class="${parameters.cssClass?html}"<#rt/>
</#if>
<#if parameters.cssStyle?exists>
style="${parameters.cssStyle?html}"<#rt/>
</#if>
<#if parameters.title?exists>
title="${parameters.title?html}"<#rt/>
</#if>
<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
<#include "/${parameters.templateDir}/simple/common-attributes.ftl" />
/>
我們考慮標(biāo)簽(Tag)使用模板(Template)生成HTML的過程,根據(jù)不同的模板,坑頂可以生成不同的HTML畫面,這樣我們可以把不同tag的,視覺效果一致的模板放在一起:
例如:
<s:form> TemplateForm_A, TemplateForm_B
<s:textfield> TemplateTextField_A, TemplateTextField_B
<s:password> TemplatePassword_A, TemplatePassword_B
<s:submit>, TemplateSubmit_A, TemplateSubmit_B
<s:reset> TemplateReset_A, TemplateReset_B
這樣將_A的模板放在一起叫做A主題(Theme),將_B的模板放在一起叫B主題。這樣我們在分別使用A主題,B主題的時候可以得到同一個Tag的不同的視覺效果。
模版和主題的概念處在Struts Tag的核心位置。
Struts2默認(rèn)提供了四種主題:
Simple 主題:最簡單的主題
XHTML 主題:默認(rèn)主題,使用常用的HTML技巧
CSS XHTML主題: 使用CSS實現(xiàn)的XHTML主題
AJAX 主題:基于XHTML主題,但是同工了AJAX功能
相關(guān)配置:
在struts.properties文件中有如下項目:
struts.ui.theme=xhtml
struts.ui.templateDir=template
struts.ui.templateSuffix=ftl
struts.ui.theme的值表示的是使用哪個主題,可選項位:xhtml,simple,css_html,ajax其中xhtml為默認(rèn)值。
struts.ui.templateDir的值表示模板的存放目錄。
struts.ui.templateSuffix的值表示模板文件明的后綴,因為Struts2默認(rèn)使用FreeMarker來編寫模板,所以這里我們基本使用ftl。 另外也可以使用vm(Velocity)和jsp(Java Server Page),但是所有的Template和Theme要我們自己開發(fā)。
關(guān)于模板文件的存放目錄我們需要詳細(xì)說明,如上述說明,模板文件的存放位置位template,那么系統(tǒng)在那里尋找template目錄呢,
首先,在web應(yīng)用程序中查找,如果應(yīng)用程序中存在一個叫做template的目錄(跟WEB-INF目錄平級),那么所有的文件從這個目錄中取得,具體的路徑還要加上主題的名字。
然后,如果在web應(yīng)用程序中沒有找到template目錄,那么struts2會在classpath中尋找,由于struts2-core-2.0.9.jar文件中存在template目錄,其中內(nèi)置了四種主題,所以會使用這里變的模板。
例如:
如果我們使用了ajax主題,那么會在如下位置超找<s:textfield>的主題
應(yīng)用程序
/template/ajax/textfield.ftl
classpath
/template/ajax/textfield.ftl
修改或者擴(kuò)展模板:
有些時候Struts提供的模板不一定能夠滿足我們的需求,這時候我們需要修改或者擴(kuò)展現(xiàn)有模板。重新做新的模板是不明智的,如果是在需要全新的模板,可以考慮基于simple擴(kuò)展。
修改:
根據(jù)模板的裝載機(jī)制,可以考慮將模板從struts2-core-2.0.9.jar文件中解壓縮到web項目目錄,之后修改對應(yīng)的文件。
包裝:
XHTML提供了一個很好的例子,simple主題提供了基本的功能,XHTML將它包括起來,例如:
以下是template/xhtml/xxx.ftl(xxx表示模板名字)文件內(nèi)容:
<#include "/${parameters.templateDir}/xhtml/controlheader.ftl" />
<#include "/${parameters.templateDir}/simple/xxx.ftl" />
<#include "/${parameters.templateDir}/xhtml/controlfooter.ftl" />
擴(kuò)展(extend):
使用棉線對象的特性可以擴(kuò)展一個主題,擴(kuò)展一個主題的時候不需要實現(xiàn)所有的模板,只需要實現(xiàn)需要變化的標(biāo)簽。
擴(kuò)展需要在目錄中新建一個叫做theme.properties的文件,這個文件只有一行,表明了繼承而來的主題的名字,例如:
/template/ajax/theme.properties文件內(nèi)容為:
parent = xhtml
4.4節(jié) AJAX標(biāo)簽(試驗階段)
Struts2內(nèi)置了Dojo 0.4 來提供對Ajax的支持。
想要使用AJAX標(biāo)簽需要做到兩點:
1 使用Ajax主題
2 在JSP畫面中使用了head標(biāo)簽配置Ajax屬性
AJAX標(biāo)簽主要有:
<s:div>
<s:submit>
<s:a>
<s:tabbedPanel>
<s:autocompleter>
AJAX標(biāo)簽的一些通用屬性:
屬性
說明
類型
href
請求使用的URL
String
listenTopic
使用逗號分割的一組主題列表,這個列表中的主題會導(dǎo)致這個Tag自己內(nèi)容(Div,Autocompleter)重新裝載或者執(zhí)行一個Action(Anchor,Submit)
String
notifyTopic
使用逗號分割的一組主題列表,向這個列表中的主題發(fā)布一些信息,例如:’data’,’type’,’request’,參看每個標(biāo)簽的詳細(xì)說明
String
showErrorTransportText
設(shè)置是否顯示錯誤消息(默認(rèn)顯示)
Boolean
indicator
請求過程中顯示的對象,通常位ProgressBar等
String
Indicator
<img style="display:none"
src="${pageContext.request.contextPath}/images/indicator.gif"
alt="Loading..."/>
Topic
監(jiān)聽一個Topic:
dojo.event.topic.subscribe("/refresh", function(param1, param2) {
//this function will be called everytime "/refresh" is published
});
向一個Topic發(fā)布內(nèi)容:
dojo.event.topic.publish("/refresh", "foo", "bar");
URL
Href屬性對應(yīng)的URL必須使用URL標(biāo)簽定義,例如:
<s:url id="ajaxTest" value="/AjaxTest.action" />
<s:div theme="ajax" href="%{ajaxTest}">
Initial Content
</s:div>
DIV標(biāo)簽:
Div主要用來異步的顯示數(shù)據(jù), PageLoad會出發(fā)Div中數(shù)據(jù)的顯示,除非把AutoStart設(shè)置為False。
另外,Div的數(shù)據(jù)顯示可以使用Topic來觸發(fā)。使用listenTopic來定義觸發(fā)器。
例如:
<s:url id="ajaxTest" value="/AjaxTest.action" />
<s:div theme="ajax" href="%{ajaxTest}" listenTopics="/refresh0,/refresh1"/>
每次想/refresh0,/refresh1發(fā)布內(nèi)容的時候,上面代碼定義的div都會刷新。
使用updateFreq可以讓Div周期性的觸發(fā),在autoStart設(shè)置位true的情況下,可以使用delay來延遲首次畫面加載的出發(fā)時間,例如:
<s:url id="ajaxTest" value="/AjaxTest.action" />
<s:div theme="ajax" href="%{ajaxTest}" updateFreq="2000" delay="3000"/>
上述代碼說明,每隔2秒該div觸發(fā)內(nèi)容更新一次,但是首次畫面加載完成之后3秒div出發(fā)內(nèi)容更新。
@todo 其他標(biāo)簽
4.5節(jié) OGNL
OGNL是Object Graph Navigation Language的簡稱,詳細(xì)相關(guān)的信息可以參考:
[url]http://www.ognl.org[/url]。這里我們只涉及Struts2框架中對OGNL的基本支持。
OGNL是一個對象,屬性的查詢語言。在OGNL中有一個類型為Map的Context(稱為上下文),在這個上下文中有一個根元素(root),對根元素的屬性的訪問可以直接使用屬性名字,但是對于其他非根元素屬性的訪問必須加上特殊符號#。
在Struts2中上下文為ActionContext,根元素位Value Stack(值堆棧,值堆棧代表了一族對象而不是一個對象,其中Action類的實例也屬于值堆棧的一個)。ActionContext中的內(nèi)容如下圖:
|
|--application
|
|--session
context map---|
|--value stack(root)
|
|--request
|
|--parameters
|
|--attr (searches page, request, session, then application scopes)
|
因為Action實例被放在Value Stack中,而Value Stack又是根元素(root)中的一個,所以對Action中的屬性的訪問可以不使用標(biāo)記#,而對其他的訪問都必須使用#標(biāo)記。
引用Action的屬性
<s:property value="postalCode"/>
ActionContext中的其他非根(root)元素的屬性可以按照如下的方式訪問:
<s:property value="#session.mySessionPropKey"/> or
<s:property value="#session["mySessionPropKey"]"/> or
<s:property value="#request["mySessionPropKey"]/>
Action類可以使用ActionContext中的靜態(tài)方法來訪問ActionContext。
ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);
OGNL與Collection(Lists,Maps,Sets)
生成List的語法為: {e1,e2,e3}.
<s:select label="label" name="name"
list="{'name1','name2','name3'}" value="%{'name2'}" />
上面的代碼生成了一個HTML Select對象,可選的內(nèi)容為: name1,name2,name3,默認(rèn)值為:name2。
生成Map的語法為:#{key1:value1,key2:value2}.
<s:select label="label" name="name"
list="#{'foo':'foovalue', 'bar':'barvalue'}" />
上面的代碼生成了一個HTML Select對象,foo名字表示的內(nèi)容為:foovalue,bar名字表示的內(nèi)容為:barvalue。
判斷一個對象是否在List內(nèi)存在:
<s:if test="'foo' in {'foo','bar'}">
muhahaha
</s:if>
<s:else>
boo
</s:else>
<s:if test="'foo' not in {'foo','bar'}">
muhahaha
</s:if>
<s:else>
boo
</s:else>
取得一個List的一部分:
– 所有滿足選擇邏輯的對象
^ - 第一個滿足選擇邏輯的對象
$ - 最后一個滿足選擇邏輯的對象
例如:
person.relatives.{? #this.gender == 'male'}
上述代碼取得這個人(person)所有的男性(this.gender==male)的親戚(relatives)
Lambda 表達(dá)式
OGNL支持簡單的Lambda表達(dá)式語法,使用這些語法可以建立簡單的lambda函數(shù)。
例如:
Fibonacci:
if n==0 return 0;
elseif n==1 return 1;
else return fib(n-2)+fib(n-1);
fib(0) = 0
fib(1) = 1
fib(11) = 89
OGNL的Lambda表達(dá)式如何工作呢?
Lambda表達(dá)式必須放在方括號內(nèi)部,#this表示表達(dá)式的參數(shù)。例如:
<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />
#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)]定義了一個Lambda表達(dá)式,
#fib(11) 調(diào)用了這個表達(dá)式。
所以上述代碼的輸出為:89
在JSP2.1中#被用作了JSP EL(表達(dá)式語言)的特殊記好,所以對OGNL的使用可能導(dǎo)致問題,
一個簡單的方法是禁用JSP2.1的EL特性,這需要修改web.xml文件:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>
4.6節(jié) Tag 語法
代碼示例:
表達(dá)式
含義
<p>Username: ${user.username}</p>
一個在標(biāo)準(zhǔn)上下文中的JavaBean對象,可以適用Freemarker,Velocity,JSTL EL等(不是OGNL)。
<s:textfield name="username"/>
在Value Stack中的一個username屬性。
<s:url id="es" action="Hello">
<s:param name="request_locale">
es
</s:param>
</s:url>
<s:a href="%{es}">Espanol</s:a>
引用Value Stack中屬性的另外一種方法。
<s:property
name="#session.user.username" />
Session中的user對象的username屬性。
<s:select
label="FooBar" name="foo"
list="#{'username':'trillian',
'username':'zaphod'}" />