struts系列学习(tiles标签库二)

Tiles的使用(二)- -

                                      

Tiles定义
          
我们需要一种方法,在一个单独的可复用文件中定义所有的attributes和properties,当参数改变时能够重载这个文件,这就是Tiles Definitions要做的事情。好,下面就来吧!
1.)声明Definitions
          所需信息:模板路径,零个或多个属性(属性名和值对),唯一标示符。
          如你所见,Definitions和<tiles:insert> 标记间真正的不同在于Definition 可以命名。尽管只加入了一个标识符,却拥有了新的特性:
  1. 可以通过传递附加或替换属性而重载
  2. 可以通过父类Definitions扩展为其他Definitions
  3. 可以通过存储在一个JSP 中的Definitions或者从一个XML 文档中装载而重用
  4. 可以是Struts ActionForward 的目标


          有两种方法来声明Definitions:JSP和XML文档。
2.)JSP声明
          
这是个简单快速的方法。它不能减少你模板文件的数量,但可以通过重载来复用。在运行时需要用一个存根(stub)文件来部署Definitions。在下一节,我们将看到将这些相同的Definitions将放入到一个XML 文档,然后直接从Struts ActionForward 中进行部署,基本的流程都是一样的。过程是:声明-部署-重载-复用。

用一个JSP声明一个Definitions:

 <%@ taglib uri="/tags/tiles" prefix="tiles" %>
<tiles:definition id="definitionName" page="/layouts/myLayout.jsp">
<tiles:put name="title" value="Hello World" />
<tiles:put name="header" value="/tiles/header.jsp" />
<tiles:put name="footer" value="/tiles/footer.jsp" />
<tiles:put name="menu" value="/tiles/menu.jsp" />
<tiles:put name="body" value="/tiles/helloBody.jsp" />
</tiles:definition>
这段代码上一篇已经看到过,但使用了Definition.。作为一个Bean中保存在JSP中,用id 作为属性标识。<tiles:definition>标签支持scope属性,默认为page。这个Definitions只对该JSP余下的部分有效。

部署声明的Definition:
<%@ taglib uri="/tags/tiles" prefix="tiles" %>
<tiles:definition id="definitionName" page="/layouts/myLayout.jsp">
<tiles:put name="title" value="Hello World" />
<tiles:put name="header" value="/tiles/header.jsp" />
<tiles:put name="footer" value="/tiles/footer.jsp" />
<tiles:put name="menu" value="/tiles/menu.jsp" />
<tiles:put name="body" value="/tiles/helloBody.jsp" />
</tiles:definition>
<tiles:insert beanName="definitionName" flush="true/> 
要使用声明的Definition,可以用<tiles:insert>标记,通过id名称来调用上面声明的Definition。
启动时,Tiles 使用XML 元素的id definitionName 创建一个Definition对象(或bean)。
运行时,<tiles:insert> 标记通过beanName 属性引用定义id。

重载:可以重载某些或全部属性。重载时,只需要一个新的属性值。要创建一个新的属性,包含一个新的属性名称和值就可以了。
 <%@ taglib uri="/tags/tiles" prefix="tiles" %>
<tiles:definition id="definitionName" page="/layouts/myLayout.jsp">
<tiles:put name="title" value="Hello World" />
<tiles:put name="header" value="/tiles/header.jsp" />
<tiles:put name="footer" value="/tiles/footer.jsp" />
<tiles:put name="menu" value="/tiles/menu.jsp" />
<tiles:put name="body" value="/tiles/helloBody.jsp" />
</tiles:definition>
<tiles:insert beanName="definitionName" flush="true" >
<tiles:put name="title" value="New PageTitle" />
<tiles:put name="body" value="/tiles/anotherBody.jsp" />
<tiles:put name="extra" value="/extra.jsp" />
</tiles:insert>
这段代码可以看到,body使用了一个新的属性值。还新增加了extra属性,这就意味着布局(layout)没有管理到这个tile,但如果提供也可以显示。布局时可以使用ignore标签,当ingore设置为true时,如果属性不存在将不会报告错误。父类Definition继承来的myLayout.jsp怎样要添加一个extra tile::

 <tiles:insert attribute="extra" ignore="true" />

 
复用Definition:在上面的例子中看到,我们在重载某些属性前不得不重复的Definitions,这当然是非常不实际的方法。有一种更加简单的好方法,看下面的例子:
 <%@ taglib uri="/tags/tiles" prefix="tiles" %>
<%@ include file="definitionsConfig.jsp" %>
<tiles:insert beanName="definitionName" beanScope="request" />
<tiles:put name="title" value="Another Page" />
<tiles:put name="body" value="/tiles/anotherBody.jsp" />
</tiles:insert>
使用标准的JSP include标签把Definition引入,你能够想平常一样使用Definition。在例子中,也重载了title和body属性。这种复用的方法对于拥有少量Definition来说是好的。但有个缺点,每次文件被include的时候,会把Definitions重新创建执行,这就影响了性能。在开发过程中这仍是个好方法,因为对Definition的修改在下次页面装载时就会体现出来。通常可以这样使用,在一个工作区中创建一个带有scope属性的Definition,再用Structs的<logic:notPresent>块来包含:
 <%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/tiles" prefix="tiles" %>
<logic:notPresent name="definitionName" scope="application">
<tiles:definition id="definitionName" page="/layouts/myLayout.jsp">
<tiles:put name="title" value="Hello World" />
<tiles:put name="header" value="/tiles/header.jsp" />
<tiles:put name="footer" value="/tiles/footer.jsp" />
<tiles:put name="menu" value="/tiles/menu.jsp" />
<tiles:put name="body" value="/tiles/helloBody.jsp" />
</tiles:definition>
<%-- … other definitions … --%>
</logic:notPresent>
这样做就不会重新创建Definitions了。每个页面仍然需要包含Definition并检查是否存在,但至少它们不需要再被不断创建了。
       Tiles提供一个更好的方法来一次性装载和复用Definition:使用XML文档。Definition直接用来ActionFrowards。这是个管理Tiles Definitions的好方法,请看下面的内容。
 
3.)使用配置文件声明
        
在一个XML 配置文件中声明你的Definition,应用程序在启动时装载这个文件,并创建一个包含Definition的"Definition factory"。每个Definition用其属性名称来标识,并且要是唯一的。其他组件如ActionForward,就可以通过这个名称来引用Definition。在一个XML 配置文件中声明Tiles Definition需要一些额外的设置,以允许在应用程序初始化时可以读取并装载配置文件。《Structs in action》第4 章中,可以得到关于如何在Struts 1.1 中安装Tiles。应用程序初始化时,XML 配置文件被读取,然后解析到一个"Definition factory"中,该工厂包含了每个声明过的Definition的实例。每个Definition应该有其唯一的名称,以便它可以被JSP 标记或者StrutsActionForward 引用。定义的名称及用作内部引用。它不是一个URI,不能直接被客户端引用。使用XML 文档的定义宣称的流程和使用JSP 的处理并没有什么太大的不同。主要的不同点是他们如何被创建,如何被扩展,以及Definition如何可以被Struts ActionForward 使用。

创建配置文件:
       XML 配置文件的总体格式有点类似于Struts 配置文件。令人惊讶的是,XML 配置文件文件之中使用的语法和Tiles <definition>标记相似:
 
 <!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
"
http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd">
<tiles-definitions>
<definition name="definitionName" page="/layouts/myLayout.jsp">
<put name="title" value="Hello World" />
<put name="header" value="/tiles/header.jsp" />
<put name="footer" value="/tiles/footer.jsp" />
<put name="menu" value="/tiles/menu.jsp" />
<put name="body" value="/tiles/helloBody.jsp" />
</definition>
<!-- ... more definitions ... -->
</tiles-definitions>
 
扩展Definitions:一个Definition能够被声明为另一个Definition的子类。新的Definition继承了父类Definitions的所以东西。
 <definition name="portal.page" extends="portal.masterPage">
<put name="title" value="Tiles 1.1 Portal" />
<put name="body" value="portal.body" />
</definition>
这种继承能力允许我们声明一个父Definition(设置缺省的属性),然后以特定的属性来扩展Definition(如title 和body)。如果你的所有定义都是从一个父Definition中扩展而来,那么在父Definition中的修改就会影响到所有从它扩展的Definition。这和重载很相似但增加了持久性。重载描述了我们在哪里标识了Definition,并且传递给他新的参数(或者属性), 就象调用一个方法,并传递给它参数。但重载不能在一个<tiles:insert>标签中调用另一个<tiles:insert>,所以重载Definitions是不能被引用和复用的。通过使用extend 属性就可以创建一个新的Definition。这个新的Definition可以被插入和重载,甚至被其他Definition扩展,它通过继承关系仍然指向它们的祖先Definition。重载或扩展一个Definitions能显著的减少页面多余的信息。每个标签,导航栏和内容组件在你的web站点中只要声明一次。这些组件就能被复用到任何你想要的地方了。
       这非常的酷!但我们需要一个额外的页面来放置Definition,意思是说要添加一个新内容的页面(content page),就要新增一个页面,然后再用一个页面来插入这个标识新内容的Definition。如果一个普通的应用程序有60个内容页面,就会有60个页面,那一个模板应用程序就至少会有120个页面来包含所有内容。模板页面比其常规页面要小巧而简单,但文件的管理还是个问题。一个好的解决放方案是用Structs ActionFrowards来放置Definition。
 
将Definitions作为ActionForwards:
       在Structs应用程序中,大多数的页面不会被直接引用,而是封装到ActionForward对象中。ActionForward给出一个唯一的逻辑名称对应实际的URL,Action选择和返回一个ActionForward给servlet控制器,ActionServlet通过ActionForward的路径值控制转发到指定的URL上。Tiles包包含一个ActionServlet的子类来检查和Definitions有关的路径值。如果Definitions的id和ActionForward的path匹配,Definitions bean被放置在request中,控制器会转发到布局,你组装好的模板就会显示。
<action
path="/tutorial/testAction2"
type="org.apache.struts.example.tiles.tutorial.ForwardExampleAction">
<forward
name="failure"
path=".forward.example.failure.page"/>   //这边可以使用斜杠代替圆点:path="/forward/example/failure.page"
<forward
name="success"
path=".forward.example.success.page"/>
</action> 
然而,用斜杠的方式可能和与Action 和页面URI 相关的标识符相冲突。推荐在Tile 定义中使用点号,而在ActionForward 中使用斜杠语法,确保名称是会冲突。Action类常会忽略ActionFrom路径,而是通过它的名称来处理。所以用Tiles Definition来代替URL,大部分Action类不需要重新构建。你可以混合使用常规的ActionForwards和Tiles-Definition-ActionForwards,这样模板页面的数量会明显的下降。对需拥有60个页面的应用程序,我们只需要60个内容页面加上少量提供标准的导航和布局的工具tile 。但是创建第61 个页面时,只需要再创建一个提供内容的JSP 和一个XML Definition,而后者只不过是简单的一行文字。
 
Tiles属性
1.)useAttribute
        
<tiles:useAttribute>标签,使某个Tiles 的属性在整个页面中有效。其它标签(像Struts <bean:write>)能引用的名称用来传递参数。
<tiles:useAttribute name="myAttribute" />
<tiles:useAttribute attributeName="anAttribute" name="myAttribute" />  //标识另外一个属性名称
<bean:write name="myAttribute" />   //Struts bean 标记既可以引用这个信息
------------------------------------------------------------------------------------------------------------------------------------------
也可以用来声明一个脚本变量供JSP scriptlet使用:
<tiles:useAttribute id="list" name="myAttribute" classname="java.util.List" />
<useAttribute> 标记与<useBean> 动作和Struts <bean:define> 标记相对应,允许访问Tiles中的属性。
每个tile 都是一个不同的"页面",每一个都有自己的页面范围。如果你想避免tile间的属性冲突,可以使用page scope。如果你想一个属性被另一个tile 共享,你可以使用request scope:
<tiles:useAttribute name="myAttribute" scope="request"/>
<useAttribute>的操作是按顺序。页面中后面tile也许可以使用某个属性,而先前的tile也许不能使用它,因为它还不存在。
2.)inportAttribute
         
<tiles:importAttribute>标签,和<useAttribute>不一样,它不支持重命名和作为脚本变量使用。
<tiles:importAttribute/> //把所有的tile属性导入到页面作用域中
<tiles:importAttribute name="myAttribute" scope="request"/>  //指定某个属性的scope,scope默认值是page
3.)put
        
<tiles:put>标签,被用来联系属性和属性值,name属性用字符串来指定,属性值分三种:tag property,tag body,JavaBean。
4.)putList and add
            
 
 
 
<tiles:insert page="menu.jsp" >
<tiles:putList name="items">
<tiles:add value="home" />
<tiles:add value="documentation"/>
</tiles:putList>
</tiles:insert>   // 两个标签联合使用,指定一个列对象作为单一属性进行传递。
------------------------------------------------------------------------------------------------------------------------------------------
<tiles:importAttribute/>
<TABLE>
<logic:iterate id="item" name="items" >
<TR>
<TD>
<bean:write name="item">
</TD>
</TR>
</logic:iterate>
</TABLE> //<putList>标签常和<useAttribute>或<importAttribute>一起使用,以便能在一个页面访问别的标签。

<tiles:put name="title" value="My first page" />
或:<tiles:put name="title" value="<%=myObject%>" />   // 是运行时的表达式
------------------------------------------------------------------------------------------------------------------------------------------
<tiles:put name="title">My first page</tiles:put>
或:<tiles:put name="title"><bean:write message="first.pageTitle"/></tiles:put>  // 是标记体
------------------------------------------------------------------------------------------------------------------------------------------
<tiles:put name="title" beanName="myBean" beanScope="session" />  /* 获取beanName标识的对象,然后其值被用作为属性值。beanScope用来搜索bean的作用域,如果没指定会调用pageContext.findAttribute()方法,这边添加了Tiles中专有的"tiles"的作用域(支持page,request,application),用来在tiles中搜索bean。*/
------------------------------------------------------------------------------------------------------------------------------------------
<tiles:put name="title" beanName="myBean" beanProperty="myProperty"/>  // 相当于调用myBean.getMyProperty()来
                                                                                                            // 指定tile的属性值
------------------------------------------------------------------------------------------------------------------------------------------
<tiles:put name="footer" value="/tiles/footer.jsp" type="page"/> //type有三种:string -- value值做为字符串输出; 
                                                                                          //                    page-- value值做为一个URL;
                                                                                          //                    definition-- value值做为Definition名称 
------------------------------------------------------------------------------------------------------------------------------------------
<tiles:put name="title" value="myValue" role="myManager"/> 
 /* 当使用基于容器的安全认证时,你也可以为一个tile指定role,如果用户不是指定的role,value值就不会被设置,这允许你为每个安全角色指定一个tile,而让框架为当前的用户选择相应的Tile。 如果<put>用在<tiles:insert>标签中,role立即被验证,用在<tiles:definition>中,role在Tiles内容初始化时被验证。      */

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值