struts2標(biāo)簽
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)簽用來(lái)在頁(yè)面表示的時(shí)候控制代碼執(zhí)行的過(guò)程,這些標(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)簽用來(lái)控制基本的條件處理流程,通常和else標(biāo)簽或者elseif標(biāo)簽連用。
參數(shù)
名字 | 是否必須 | 默認(rèn)值 | 可否使用表達(dá)式 | 類型 | 描述 |
id | 否 | 是 | String | 用來(lái)表示該元素,對(duì)于UI和Form標(biāo)簽來(lái)說(shuō)直接轉(zhuǎn)變?yōu)镠TML id屬性 | |
test | 是 | 是 | Boolean | 用來(lái)決定是否顯示標(biāo)簽內(nèi)部?jī)?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)簽
描述
用來(lái)做iterator標(biāo)簽的輔助,將不同iterator中的內(nèi)容合在一個(gè)iterator中。
參數(shù)
名字 | 是否必須 | 默認(rèn)值 | 可否使用表達(dá)式 | 類型 | 描述 |
id | 否 | 是 | String | 用來(lái)保存結(jié)果iterator的對(duì)象在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屬性生成一個(gè)iterator。
參數(shù)
例子
例1:
生成一個(gè)簡(jiǎn)單的iterator,并且使用iterator標(biāo)簽打印出內(nèi)容。
<s:generator val="%{'aaa,bbb,ccc,ddd,eee'}">
<s:iterator>
<s:property /><br/>
</s:iterator>
</s:generator>
例2:
生成一個(gè)iterator,使用count屬性。因?yàn)閏ount屬性值為3,所以只有前三個(gè)內(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屬性,之后生成的對(duì)象放在pageContext中,可以通過(guò)指定的id來(lái)訪問(wèn)。
<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僅僅將每一個(gè)對(duì)象添加了一個(gè)"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)簽
描述
迭代處理一個(gè)java.util.Connection或者java.util.Iterator對(duì)象
參數(shù)
名字 | 是否必須 | 默認(rèn)值 | 可否使用表達(dá)式 | 類型 | 描述 |
id | 否 | 是 | String | Id, | |
status | 否 | 否 | 是 | Boolean | 如果指定,在循環(huán)的過(guò)程中會(huì)保留一個(gè)IteratorStatus類型的變量,該變量用來(lái)查詢當(dāng)前迭代的狀態(tài) |
value | 否 | 是 | String | 被迭代的對(duì)象 |
例子
例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)
描述
對(duì)一個(gè)可以迭代的對(duì)象進(jìn)行排序操作。
參數(shù)
名字 | 是否必須 | 默認(rèn)值 | 可否使用表達(dá)式 | 類型 | 描述 |
Comparator | 是 | 是 | java.util.Comparator | 排序用的比較器 | |
Source | 否 | 是 | String | 排序?qū)ο?/p> |
例子
例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 | 用來(lái)判斷iterator中的item是否包含在最終的subset內(nèi)部 | |
Source | 否 | 是 | String | Iterator的對(duì)象 | |
Start | 否 | 是 | Integer | 開(kāi)始位置 |
例子
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)簽。
每一個(gè)UI標(biāo)簽都是基于模板的,即:每一個(gè)標(biāo)簽都有一個(gè)對(duì)應(yīng)的模板用來(lái)生成UI標(biāo)簽的樣式,詳細(xì)內(nèi)容參看模板節(jié)。
所有的UI標(biāo)簽都有著共通的祖先UIBean,UIBean提供了這些UI標(biāo)簽的一系列共通的屬性,這些屬性可以分為三類:模版相關(guān)的屬性,JavaScript相關(guān)的屬性和其他通用屬性。
模版相關(guān)屬性:
屬性 | 主題 | 數(shù)據(jù)類型 | 說(shuō)明 |
templateDir | n/a | String | 定義模版目錄 |
theme | n/a | String | 定義主題的名字 |
template | n/a | String | 定義模版名字 |
JavaScript相關(guān)屬性:
屬性 | 主題 | 數(shù)據(jù)類型 | 說(shuō)明 |
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)值 | 說(shuō)明 |
tooltip | String | none | 為指定的組件設(shè)置Tooltip |
jsTooltipEnabled | String | false | 使用js表示tooltip |
tooltipIcon | String | /struts/static/tooltip/tooltip.gif | 指向tooltip圖表的URL |
tooltipDelay | String | 500 | 多長(zhǎng)時(shí)間后顯示Tooltip |
key | simple | String | 這個(gè)輸入字段對(duì)應(yīng)的屬性,用來(lái)自動(dòng)設(shè)置name,label和value |
通用屬性:
屬性 | 主題 | 數(shù)據(jù)類型 | 說(shuō)明 |
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中的位置,從左從上計(jì)算 |
requiredPosition | xhtml | String | 定義必須的標(biāo)簽在Form中的位置,從左從上計(jì)算 |
name | simple | String | 定義form字段的name映射 |
required | xhtml | Boolean | 在label上添加一個(gè)* |
tabIndex | simple | String | 定義 html tabIndex屬性 |
value | simple | Object | 定義form字段的值 |
對(duì)于name和value的說(shuō)明:
name用來(lái)說(shuō)明Form字段的名字,和Action類的屬性對(duì)應(yīng)。
value用來(lái)記錄Form字段的值,和Action類中屬性的值對(duì)應(yīng)。
所以在修改一個(gè)字段的內(nèi)容的時(shí)候應(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)簽可以自動(dòng)對(duì)應(yīng),所以也可以使用如下標(biāo)簽:
<s:form action="updateAddress">
<s:textfield label="Postal Code" name="postalCode" />
...
</s:form>
UI標(biāo)簽說(shuō)明:
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é) 主題和模板
概念說(shuō)明:
標(biāo)簽(tag):一小段代碼,在JSP,Velocity或者FreeMarker中執(zhí)行。程序開(kāi)發(fā)的最小單位,用來(lái)生成HTML對(duì)應(yīng)的元素。
模板(template):一些代碼,通常使用FreeMarker寫(xiě)成,可以被某些Tag表示出來(lái)(通常是UI Tag)。
主題(theme):一組模板打包在一起,提供通用功能的模版
主題和模板主要針對(duì)可視化的標(biāo)簽(Tag)而言,使用以下例子來(lái)說(shuō)明三者之間的關(guān)系。
假如我們要開(kāi)發(fā)如下的一個(gè)畫(huà)面:
我們使用如下的代碼:
<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>每一個(gè)都是一個(gè)標(biāo)簽(tag)。
我們?cè)诳纯催@些標(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代碼的時(shí)候,例如:
<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ù)一個(gè)固定的模板文件生成,這個(gè)模板文件為:
標(biāo)簽使我們開(kāi)發(fā)JSP畫(huà)面的時(shí)候使用的最小組件單元,我們根據(jù)客戶的需要組合各種Tag達(dá)到客戶的需求。模板是生成這些 Tag時(shí)候使用的,使用模板可以定義Tag的基本形式,在使用tag的時(shí)候,我們只需要指定該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的過(guò)程,根據(jù)不同的模板,坑頂可以生成不同的HTML畫(huà)面,這樣我們可以把不同tag的,視覺(jué)效果一致的模板放在一起:
例如:
<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主題。這樣我們?cè)诜謩e使用A主題,B主題的時(shí)候可以得到同一個(gè)Tag的不同的視覺(jué)效果。
模版和主題的概念處在Struts Tag的核心位置。
Struts2默認(rèn)提供了四種主題:
Simple 主題:最簡(jiǎn)單的主題
XHTML 主題:默認(rèn)主題,使用常用的HTML技巧
CSS XHTML主題: 使用CSS實(shí)現(xiàn)的XHTML主題
AJAX 主題:基于XHTML主題,但是同工了AJAX功能
相關(guān)配置:
在struts.properties文件中有如下項(xiàng)目:
struts.ui.theme=xhtml
struts.ui.templateDir=template
struts.ui.templateSuffix=ftl
struts.ui.theme的值表示的是使用哪個(gè)主題,可選項(xiàng)位:xhtml,simple,css_html,ajax其中xhtml為默認(rèn)值。
struts.ui.templateDir的值表示模板的存放目錄。
struts.ui.templateSuffix的值表示模板文件明的后綴,因?yàn)镾truts2默認(rèn)使用 FreeMarker來(lái)編寫(xiě)模板,所以這里我們基本使用ftl。 另外也可以使用vm(Velocity)和jsp(Java Server Page),但是所有的Template和Theme要我們自己開(kāi)發(fā)。
關(guān)于模板文件的存放目錄我們需要詳細(xì)說(shuō)明,如上述說(shuō)明,模板文件的存放位置位template,那么系統(tǒng)在那里尋找template目錄呢,
首先,在web應(yīng)用程序中查找,如果應(yīng)用程序中存在一個(gè)叫做template的目錄(跟WEB-INF目錄平級(jí)),那么所有的文件從這個(gè)目錄中取得,具體的路徑還要加上主題的名字。
然后,如果在web應(yīng)用程序中沒(méi)有找到template目錄,那么struts2會(huì)在classpath中尋找,由于struts2-core-2.0.9.jar文件中存在template目錄,其中內(nèi)置了四種主題,所以會(huì)使用這里變的模板。
例如:
如果我們使用了ajax主題,那么會(huì)在如下位置超找<s:textfield>的主題
應(yīng)用程序 | /template/ajax/textfield.ftl |
classpath | /template/ajax/textfield.ftl |
修改或者擴(kuò)展模板:
有些時(shí)候Struts提供的模板不一定能夠滿足我們的需求,這時(shí)候我們需要修改或者擴(kuò)展現(xiàn)有模板。重新做新的模板是不明智的,如果是在需要全新的模板,可以考慮基于simple擴(kuò)展。
修改:
根據(jù)模板的裝載機(jī)制,可以考慮將模板從struts2-core-2.0.9.jar文件中解壓縮到web項(xiàng)目目錄,之后修改對(duì)應(yīng)的文件。
包裝:
XHTML提供了一個(gè)很好的例子,simple主題提供了基本的功能,XHTML將它包括起來(lái),例如:
以下是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):
使用棉線對(duì)象的特性可以擴(kuò)展一個(gè)主題,擴(kuò)展一個(gè)主題的時(shí)候不需要實(shí)現(xiàn)所有的模板,只需要實(shí)現(xiàn)需要變化的標(biāo)簽。
擴(kuò)展需要在目錄中新建一個(gè)叫做theme.properties的文件,這個(gè)文件只有一行,表明了繼承而來(lái)的主題的名字,例如:
/template/ajax/theme.properties文件內(nèi)容為:
parent = xhtml
4.4節(jié) AJAX標(biāo)簽(試驗(yàn)階段)
Struts2內(nèi)置了Dojo 0.4 來(lái)提供對(duì)Ajax的支持。
想要使用AJAX標(biāo)簽需要做到兩點(diǎn):
1 使用Ajax主題
2 在JSP畫(huà)面中使用了head標(biāo)簽配置Ajax屬性
AJAX標(biāo)簽主要有:
<s:div>
<s:submit>
<s:a>
<s:tabbedPanel>
<s:autocompleter>
AJAX標(biāo)簽的一些通用屬性:
屬性 | 說(shuō)明 | 類型 |
href | 請(qǐng)求使用的URL | String |
listenTopic | 使用逗號(hào)分割的一組主題列表,這個(gè)列表中的主題會(huì)導(dǎo)致這個(gè)Tag自己內(nèi)容(Div,Autocompleter)重新裝載或者執(zhí)行一個(gè)Action(Anchor,Submit) | String |
notifyTopic | 使用逗號(hào)分割的一組主題列表,向這個(gè)列表中的主題發(fā)布一些信息,例如:’data’,’type’,’request’,參看每個(gè)標(biāo)簽的詳細(xì)說(shuō)明 | String |
showErrorTransportText | 設(shè)置是否顯示錯(cuò)誤消息(默認(rèn)顯示) | Boolean |
indicator | 請(qǐng)求過(guò)程中顯示的對(duì)象,通常位ProgressBar等 | String |
Indicator
<img style="display:none"
src="${pageContext.request.contextPath}/images/indicator.gif"
alt="Loading..."/>
Topic
監(jiān)聽(tīng)一個(gè)Topic:
dojo.event.topic.subscribe("/refresh", function(param1, param2) {
//this function will be called everytime "/refresh" is published
});
向一個(gè)Topic發(fā)布內(nèi)容:
dojo.event.topic.publish("/refresh", "foo", "bar");
URL
Href屬性對(duì)應(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主要用來(lái)異步的顯示數(shù)據(jù), PageLoad會(huì)出發(fā)Div中數(shù)據(jù)的顯示,除非把AutoStart設(shè)置為False。
另外,Div的數(shù)據(jù)顯示可以使用Topic來(lái)觸發(fā)。使用listenTopic來(lái)定義觸發(fā)器。
例如:
<s:url id="ajaxTest" value="/AjaxTest.action" />
<s:div theme="ajax" href="%{ajaxTest}" listenTopics="/refresh0,/refresh1"/>
每次想/refresh0,/refresh1發(fā)布內(nèi)容的時(shí)候,上面代碼定義的div都會(huì)刷新。
使用updateFreq可以讓Div周期性的觸發(fā),在autoStart設(shè)置位true的情況下,可以使用delay來(lái)延遲首次畫(huà)面加載的出發(fā)時(shí)間,例如:
<s:url id="ajaxTest" value="/AjaxTest.action" />
<s:div theme="ajax" href="%{ajaxTest}" updateFreq="2000" delay="3000"/>
上述代碼說(shuō)明,每隔2秒該div觸發(fā)內(nèi)容更新一次,但是首次畫(huà)面加載完成之后3秒div出發(fā)內(nèi)容更新。
@todo 其他標(biāo)簽
4.5節(jié) OGNL
OGNL是Object Graph Navigation Language的簡(jiǎn)稱,詳細(xì)相關(guān)的信息可以參考:http://www.ognl.org。這里我們只涉及Struts2框架中對(duì)OGNL的基本支持。
OGNL是一個(gè)對(duì)象,屬性的查詢語(yǔ)言。在OGNL中有一個(gè)類型為Map的Context(稱為上下文),在這個(gè)上下文中有一個(gè)根元素(root),對(duì)根元素的屬性的訪問(wèn)可以直接使用屬性名字,但是對(duì)于其他非根元素屬性的訪問(wèn)必須加上特殊符號(hào)#。
在Struts2中上下文為ActionContext,根元素位Value Stack(值堆棧,值堆棧代表了一族對(duì)象而不是一個(gè)對(duì)象,其中Action類的實(shí)例也屬于值堆棧的一個(gè))。ActionContext中的內(nèi)容如下圖:
|
|--application
|
|--session
context map---|
|--value stack(root)
|
|--request
|
|--parameters
|
|--attr (searches page, request, session, then application scopes)
|
因?yàn)锳ction實(shí)例被放在Value Stack中,而Value Stack又是根元素(root)中的一個(gè),所以對(duì)Action中的屬性的訪問(wèn)可以不使用標(biāo)記#,而對(duì)其他的訪問(wèn)都必須使用#標(biāo)記。
引用Action的屬性
<s:property value="postalCode"/>
ActionContext中的其他非根(root)元素的屬性可以按照如下的方式訪問(wèn):
<s:property value="#session.mySessionPropKey"/> or
<s:property value="#session["mySessionPropKey"]"/> or
<s:property value="#request["mySessionPropKey"]/>
Action類可以使用ActionContext中的靜態(tài)方法來(lái)訪問(wèn)ActionContext。
ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);
OGNL與Collection(Lists,Maps,Sets)
生成List的語(yǔ)法為: {e1,e2,e3}.
<s:select label="label" name="name"
list="{'name1','name2','name3'}" value="%{'name2'}" />
上面的代碼生成了一個(gè)HTML Select對(duì)象,可選的內(nèi)容為: name1,name2,name3,默認(rèn)值為:name2。
生成Map的語(yǔ)法為:#{key1:value1,key2:value2}.
<s:select label="label" name="name"
list="#{'foo':'foovalue', 'bar':'barvalue'}" />
上面的代碼生成了一個(gè)HTML Select對(duì)象,foo名字表示的內(nèi)容為:foovalue,bar名字表示的內(nèi)容為:barvalue。
判斷一個(gè)對(duì)象是否在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>
取得一個(gè)List的一部分:
? – 所有滿足選擇邏輯的對(duì)象
^ - 第一個(gè)滿足選擇邏輯的對(duì)象
$ - 最后一個(gè)滿足選擇邏輯的對(duì)象
例如:
person.relatives.{? #this.gender == 'male'}
上述代碼取得這個(gè)人(person)所有的男性(this.gender==male)的親戚(relatives)
Lambda 表達(dá)式
OGNL支持簡(jiǎn)單的Lambda表達(dá)式語(yǔ)法,使用這些語(yǔ)法可以建立簡(jiǎn)單的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á)式必須放在方括號(hào)內(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)]定義了一個(gè)Lambda表達(dá)式,
#fib(11) 調(diào)用了這個(gè)表達(dá)式。
所以上述代碼的輸出為:89
在JSP2.1中#被用作了JSP EL(表達(dá)式語(yǔ)言)的特殊記好,所以對(duì)OGNL的使用可能導(dǎo)致問(wèn)題,
一個(gè)簡(jiǎn)單的方法是禁用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 語(yǔ)法
代碼示例:
表達(dá)式 | 含義 |
<p>Username: ${user.username}</p> | 一個(gè)在標(biāo)準(zhǔn)上下文中的JavaBean對(duì)象,可以適用Freemarker,Velocity,JSTL EL等(不是OGNL)。 |
<s:textfield name="username"/> | 在Value Stack中的一個(gè)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對(duì)象的username屬性。 |
<s:select label="FooBar" name="foo" list="#{'username':'trillian', 'username':'zaphod'}" /> | 一個(gè)簡(jiǎn)單 |
posted on 2013-01-18 13:38 楊軍威 閱讀(791) 評(píng)論(0) 編輯 收藏