您的位置:首页 > 编程语言 > Java开发

Expresso表示层的深入使用研究

2005-11-28 09:05 459 查看
Expresso表示层的深入使用研究  
修订历史记录

日期
版本
说明
作者
2005-08-19
1.0
初建
唐家平
2005-08-26
1.1
修改部分内容
唐家平
 
 
 
 
  
 
1     前言... 2
2     Struts tag和Extended Struts tag思想... 2
3     Expresso Extended Struts Tags  2
3.1             读取Output对象    3
3.2             读取Input对象    3
3.3             创建一个输入form页面    4
3.4             产生一个Url连接    4
3.5             遍历Block对象内的对象    4
4     Expresso Tag Library. 5
4.1             读取Output对象    6
4.2             读取Input对象    6
4.3             创建一个输入form页面    6
4.4             遍历Block对象内的对象    6
4.5             显示错误信息    7
4.6             判断对象是否存在    7
5     表格隔行颜色显示原理... 8
6     总结... 8
7     参考资料... 8
 

1         前言

表示层的内容主要是描述标签库,在Expresso框架中网页的标签库主要包括如下5类:HyperText Markup Language (HTML)Java Standard Tag Library (JSTL)Struts TagsExpresso Extended Struts TagsExpresso Tag Library前两种就不必说了,后三种其实是一种继承关系。如果说JSTL描述的是一个对象的定义的话(如<jsp:usebean property="controllerResponse">),则第三种和第四种则是着重描述对象的属性。最后一种,则是对Expresso对象的一种定制。下文将着重描述Expresso Extended Struts Tags和Expresso Tag Library,对于其他标签库,只是一笔带过,具体使用细节请读者查阅相关文档。 

2       Struts tag和Extended Struts tag思想

在我们编写Java bean时,我们采用get/set的命名模式来完成属性的定义。在这种模式里,我们采用'get'或'set'加上属性名称的首字母大写的方式来定义一个属性。例如,我们要读取一个对象的Name属性时,则实质是需要调用该对象的getName()方法。Struts tag和Expresso Extended Struts tag的核心思想正是源自这种对对象属性的操作方法,但要记住的是,这里的属性并不是对象的属性本身,而是对象作为包含在别的对象之内使,该对象作为包含对象的属性看待。Expresso Extended Struts tag针对Expresso的对象读取进行了定制,使用之来显示Expresso的对象变得更简单,它们之间的异同请看下表:
 
访问属性对象方式嵌套读取Output的属性*
Struts tagid="" name="" property="".attribute()
Extended Struts tagid="" name="" property=""/和.@
 Id:定义在JSP页面的访问该对象的名称;Name:标明访问的是哪个对象,该名称是非本标签内id所定义的;Property:标明访问的是对象的哪个属性,属性有嵌套特性,相当于我们编写程序时使用“.”访问;Expresso Extended Struts tag里“/”表示对象嵌套,“.”表示对象本身属性的引用,通常可使用“.”引用的属性有label、description、type、url等。Type:定义在JSP页面的访问该对象的类型; 

3       Expresso Extended Struts Tags

在使用Expresso扩展Struts标签库时,需要在.jsp的页面头部申明如下:<%@ taglib uri="/WEB-INf/tld/expresso-logic.tld" prefix="logic"%><%@ taglib uri="/WEB-INF/tld/expresso-html.tld" prefix="html"%><%@ taglib uri="/WEB-INF/tld/expresso-bean.tld" prefix="bean"%>一个隐含的规则是:读取位于controllerResponse根下的对象,name="controllerResponse"项是省去不写的。 1)可用iterate访问的几类特殊的“属性”:outputs:在ControllerResponse 或Block对象里的所有Output对象;inputs:在ControllerResponse 或Block对象里的所有Input对象;transitions:在ControllerResponse 或Block对象里的所有Transition对象;blocks:在ControllerResponse 或Block对象里的所有Block对象;nested:在ControllerResponse 或Block对象里的所有嵌套的对象; 
2)嵌套访问:a/b 引用嵌套在"a"对象的"b"对象;a/b.label 引用嵌套在"a"对象的"b"对象的"label"属性,即调用getLabel()方法;a/b.@something 引用嵌套在"a"对象的"b"对象的"something"*attribute*。没有“/@”、或级联的“@”形式; 
3)存在判断:<logic:present property="@multiValued"></logic:present> 
4)定义一个对象引用:<bean:define id="url" name="oneTra" property="url" type="java.lang.String"/>该功能有点相当于我们熟悉的标签:<jsp:usebean id=”url” class=”xx.oneTra.url” scope="request" /> 

3.1       读取Output对象

读取一个名为“hello”的Output对象,我们可以使用如下标签:<bean:write property="hello"/><bean:write property="hello.@xx"/><bean:write property="hello.label"/> 

3.2       读取Input对象

根据输出的对象类型不同,分为以下几种形式:<html:text name="oneInput"/><html:select name="oneInput"/><html:checkbox name="oneInput"/><html:file name="oneInput"/><html:textarea name="oneInput" rows="7" cols="50"/> Input的label值来自于它的setLabel()方法设置的值。<label for="<%=inputName%>"><bean:write name="oneInput" property="label"/>:</label> 

3.3       创建一个输入form页面

本例包含对Input对象、Transition对象的读取。  <html:form action="/tags.do" method="post">    <html:text property="input1"/>    <html:submit property="process"/>  </html:form> 

3.4       产生一个Url连接

作为按钮请看上例,以下对Transition的另外2种读取方式。事实上,Transition对象有着一个url特殊属性(getUrl())。<html:exLink property="logout"/> <bean:define id="url" name="oneTra" property="url" type="java.lang.String"/><html:link page="<%= url %>"><bean:write name="oneTra" property="label"/></html:link> 

3.5       遍历Block对象内的对象

若我们要显示一个列表,则需要遍历显示Block对象里的内容,例子如下:  <logic:iterate id="eachPrisoner" property="aBlock"/>    <bean:write name="eachPrisoner"/>    <bean:write name="eachPrisoner" property="@CellNumber"/>  </logic:iterate>比较遗憾的是,该地方输出结果并不是我们意料的那样,而只显示了一个Output内容,其余信息丢失。 对于这种只有一层Block的对象嵌套Output对象的显示,通常是采用如下方式:  <bean:write property="aBlock/prisonHelloA"/>  <bean:write property="aBlock/prisonHelloA.@CellNumber"/><br/>  <bean:write property="aBlock/prisonHelloB"/>  <bean:write property="aBlock/prisonHelloB.@CellNumber"/><br/> 
对于这种只有一层Block的对象嵌套Transition对象的显示,则可采用上面的显示结构:<logic:iterate id="oneTra" property="details">   <bean:define id="det" name="oneTra" property="url" type="java.lang.String"/>   <html:link page="<%= det %>">     <bean:write name="oneTra" property="label"/>  </html:link></logic:iterate> 
通常情况下,Block用于传递一张表的数据,使用例子如下:<table border="1" cellspacing="0" cellpadding="1">  <tr bgcolor="#000099">    <td width="15%"><font color="#FFFFFF"> 1 </font></td>    <td><font color="#FFFFFF"> 2 </font></td>  </tr> 
  <logic:iterate id="oneRow" property="table" >     <tr>     <logic:iterate id="oneCol" name="oneRow" property="outputs">       <logic:present name="oneCol" property="/detail">         <bean:define id="url" name="oneCol" property="/detail.url"            type="java.lang.String"/>         <td>           <html:link page="<%= url %>">             <bean:write name="oneCol"/>           </html:link>         </td>       </logic:present>       <logic:notPresent name="oneCol" property="/detail">         <td>           <bean:write name="oneCol"/>         </td>       </logic:notPresent>     </logic:iterate>     </tr>  </logic:iterate></table> 
注:由于DBMaint所使用的标签90%都是Expresso Extended Struts tag,所以以上的大部分例子均来自于DBMaint的表示层,读者可到那里找到对应的影子。 

4         Expresso Tag Library

Expresso Tag是面对展现Expresso控制层输出对象的定制,进一步方便操作,相对于前面几类标签库,常用操作更简洁明了、更易理解。只是定制带来了限制,在得到优越性的同时,牺牲了灵活性。Expresso Tag最明显的优点是:对Input对象的强大表现力、采用结构上的包含关系表示嵌套关系。缺点是:读取对象的属性、展现Transition成Url等方面就没有Expresso Extended Struts tags好。我们通常需要对Input字段进行说明描述,可是Expresso Tag却没有提供读取description的标签。不能自由地定义一个用以在页面里操作的对象。可见Expresso Tag并不完善,希望在高版本的得到补充。 

4.1       读取Output对象

<expresso:OutputTag name="Hendrix" >  <expresso:ContentTag/>  <expresso:AttributeTag name="fullname" /></expresso:OutputTag> 

4.2       读取Input对象

<expresso:LabelTag name="input1" type="input"/><br/><expresso:InputTag name="input1" /><br/><!--由于Expresso的一个Bug,此处type="INPUT"的Input必须大写--><expresso:AttributeTag name="desc" controllerElement="input1" type="INPUT"/><br/> 

4.3       创建一个输入form页面

  <form action="/Demo.do?cmd=button" method="post">    <expresso:LabelTag name="input1" type="input"/><br/>    <expresso:InputTag name="input1" /><br/>    <expresso:TransitionTag name="process" />  </form> 

4.4       遍历Block对象内的对象

对于这种只有一层Block的对象嵌套Output、Input对象的显示,通常是采用如下方式:  <expresso:Block name="aBlock">    <expresso:ElementCollection type="output">      <expresso:ElementIterator>          <expresso:OutputTag name="xxx">            <expresso:ContentTag />---            <expresso:AttributeTag name="CellNumber" /><br/>          </expresso:OutputTag>      </expresso:ElementIterator>    </expresso:ElementCollection>  </expresso:Block>   <expresso:Block name="inputBlock">    <expresso:ElementCollection type="input">      <expresso:ElementIterator>          <expresso:LabelTag name="xx" type="input"/><br/>          <expresso:InputTag name="xxx"/><br/>      </expresso:ElementIterator>    </expresso:ElementCollection>  </expresso:Block> 
显示一张表格:  <table border="1" cellspacing="0" cellpadding="1">    <expresso:TableHead value="1|2|3"/> 
    <expresso:Block name="table">      <expresso:ElementCollection type="block">        <expresso:ElementIterator>          <tr>            <expresso:ElementCollection type="output">              <expresso:ElementIterator>                <expresso:OutputTag name="xxx">                  <td><expresso:ContentTag /></td>                </expresso:OutputTag>              </expresso:ElementIterator>            </expresso:ElementCollection>            <expresso:ElementCollection type="transition">              <expresso:ElementIterator>                <form                  action="/Demo.do?cmd=button"                  method="get">                <td><expresso:TransitionTag name="detail" /></td>                </form>              </expresso:ElementIterator>            </expresso:ElementCollection>          </tr>        </expresso:ElementIterator>      </expresso:ElementCollection>    </expresso:Block>  </table> 

4.5       显示错误信息

可以智能地显示由页面传来的ErrorCollection对象所包含的错误信息。<expresso:ErrorTag /> 

4.6       判断对象是否存在

  <expresso:IfElementExists name="inputBlock" type="block">  …  </expresso:IfElementExists> 

5         表格隔行颜色显示原理

简单的方法可以编写如下代码实现,这里主要是使用了Expresso Extend Struts tag的indexId="rowCount"。<logic:iterate id="oneRow" property="table" indexId="rowCount" >  <tr bgcolor="<%= (rowCount.intValue()) % 2 == 1 ? "white" : "#FFFFCC"%>">   …  </tr></logic:iterate> 在DBMaint的实现中,其实是牵涉到一个风格的实现,原理如下:1)在Expresso系统表Setup表里,存在着风格的设置:defaultCSS;2)在ROOT/expresso/style/目录下则存在着各种各样的风格CSS文件;3)在JSP页面有<expresso:stylesheet/>引用该映射表;4)在每一个<TR >等标签有形如<TR class="jc-row-alt">的引用。 

6         总结

各种标签库都有着自己的优势和缺点,我们需要结合着使用。有时候,我们找遍了已有标签库,就是找不到我们想要的功能,也许只有我们自己开发了。若开发,则带来一个如何开发的问题,怎样开发既扩展了我们想要的功能,又不破坏Expresso框架的封装性?原则上,我们不开发标签库,而需要总结出一套适合我们表达习惯的标签使用方法,满足我们展现页面的需要,也规范了我们的界面设计人员。一般情况下,Expresso Extended Struts Tag是灵活性和智能性结合点较好的一个标签库,也许这也正是DBMaint大部分使用该标签库的一个主要原因吧。本次研究侧重于Expresso的研究,对于Struts标签库部分则是轻描淡写。事实上,由于Expresso是对Struts进行了一次封装,我们面对还没能得到解决的问题,也许使用Struts标签库已可以很好解决了。因此,我们还是建议对Struts进行一些必要的研究。作为一个副产品,本人发现如下标签和本地化、国际化有关,该问题需要得到继续研究:<label for=""></label><html:submit name="oneTransition"/> 

7         参考资料

Orange Trader Example Web ApplicationExpresso 5.5 Developer's Guide  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息