Expresso表示层的深入使用研究

Expresso表示层的深入使用研究

 

 

修订历史记录

日期

版本

说明

作者

2005-08-19

1.0

初建

唐家平

2005-08-26

1.1

修改部分内容

唐家平

 

 

 

 

 

 

 

1     前言... 2

2     Struts tagExtended 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 Tags

Expresso Extended Struts Tags

Expresso Tag Library

前两种就不必说了,后三种其实是一种继承关系。如果说JSTL描述的是一个对象的定义的话(如<jsp:usebean property="controllerResponse">),则第三种和第四种则是着重描述对象的属性。最后一种,则是对Expresso对象的一种定制。

下文将着重描述Expresso Extended Struts TagsExpresso Tag Library,对于其他标签库,只是一笔带过,具体使用细节请读者查阅相关文档。

 

2       Struts tagExtended Struts tag思想

在我们编写Java bean时,我们采用get/set的命名模式来完成属性的定义。在这种模式里,我们采用'get''set'加上属性名称的首字母大写的方式来定义一个属性。例如,我们要读取一个对象的Name属性时,则实质是需要调用该对象的getName()方法。Struts tagExpresso Extended Struts tag的核心思想正是源自这种对对象属性的操作方法,但要记住的是,这里的属性并不是对象的属性本身,而是对象作为包含在别的对象之内使,该对象作为包含对象的属性看待。

Expresso Extended Struts tag针对Expresso的对象读取进行了定制,使用之来显示Expresso的对象变得更简单,它们之间的异同请看下表:

 

访问属性对象方式

嵌套

读取Output的属性*

Struts tag

id="" name="" property=""

.

attribute()

Extended Struts tag

id="" name="" property=""

/.

@

 

Id:定义在JSP页面的访问该对象的名称;

Name:标明访问的是哪个对象,该名称是非本标签内id所定义的;

Property:标明访问的是对象的哪个属性,属性有嵌套特性,相当于我们编写程序时使用“.”访问;Expresso Extended Struts tag里“/”表示对象嵌套,“.”表示对象本身属性的引用,通常可使用“.”引用的属性有labeldescriptiontypeurl等。

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"/>

 

Inputlabel值来自于它的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对象的强大表现力、采用结构上的包含关系表示嵌套关系。

缺点是:读取对象的属性、展现TransitionUrl等方面就没有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的对象嵌套OutputInput对象的显示,通常是采用如下方式:

  <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 tagindexId="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 Application

Expresso 5.5 Developer's Guide

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值