Java Web开发的轻便架构Tapestry5---页面渲染一

来源:互联网 发布:四川广电网络怎么缴费 编辑:程序博客网 时间:2024/05/20 23:03
     因为tapestry5是一个基于MVC和Freemarker的web框架,web框架少不了页面渲染,今天就介绍一下tapestry5的页面渲染是如何做的. 

1. 基本概念

     首先,我们回顾一下jsp是如何渲染出一个HTML文档的。当一个请求到达jsp页面时,jsp擎会解析jsp文件,生成一个servlet类。文件中静态的部分会原样输出,而动态的部分则作为程序代码看待。
那么Tapestry的渲染思路呢?
     本质上,Tapestry还是遵循了这一思路,静态的文本原样输出,而动态的部分则视为组件。
那么组件又是什么呢?
 
     Tapestry的组件是UI、数据和事件这三者有机的统一,使用组件只需要考虑如何提供数据,并处理响应事件即可。对于如何生成HTML片段,如何处理HTTP请求细节,如何接收用户输入等等都不必考虑。为了能更好的支持这三者的统一,Tapestry将其分别划分到渲染和事件着两个阶段完成。我们也可以拿jsp与着两个阶段做类比,回想下写过的jsp程序,其中有一部分代码我们是用来做显示的,而有一部分是在用户触发一些事件后,响应用户请求的。Tapestry将其划分为两个阶段正好有效的分离的这两部分的代码。

2.职责划分

     渲染需要处理的问题相当多,比方说生成各类HTML标签用于显示页面,生成用于响应用户事件的URL以便能将请求传回给组件处理,处理其它页面传入的参数,自动引入组件使用到的js或者css文件,等等。那么,如此多的问题都要如何处理呢?换句话说,哪些职责由组件需要负责?哪些职责又由框架提供呢?
     简单的说,框架承担了调度和管理者的职责,而组件负责执行与实施的职责。详细点讲,框架需要提供资源管理的机制,提供URL生成、编码与解编码的方式,提供组件渲染所需的生命周期的支持,等底层细节操作。而组件则是负责在框架的调度下,使用这些服务,生成对应HTML标签。

3.组件职责

     对于使用Tapestry进行Web开发而言,最重要的,最频繁接触的是组件,而最终展示给用户的页面也是一个特殊的组件。所以,要了解页面渲染的过程,首先需要了解组件的职责。我们先回忆一下曾经写过的页面,里面除了正常的HTML标签外,还有很多用于做循环和选择的控制逻辑。因为页面很多情况下并不是一成不变的,而是根据不同的状态,有选择性的展现出不同的样式,比如显示table的时候总会循环的生成tr,再比如对于等于用户我们需要显示用户名,而对于非登录用户我们需要显示登录框。所以,组件按期职责可以分为两类:显示组件和控制组件。显示组件负责生成一段与这个组件相关的HTML代码片段,而控制组件则类似于程序的控制逻辑,控制选择和循环操作。实际上,还可以分出一类交互性组件,但交互性组件和显示组件在渲染时的行为是相似的,只是多了一个事件处理,可以看作一类特殊的显示组件。不过,很多时候组件的界限并不一定非常明显,它可能即会生成一段HTML代码,又会控制页面的逻辑,我们这种划分只是为了能更好的说明组件的职责。通过这样的划分不难看出,组件的主要职责是生成HTML代码与控制渲染流程。

3.1生命周期
     Tapestry框架为组件定义了一个标准的生命周期,所以要了解组件是如何履行其职责的,就必须先了解组件的生命周期。因为,不论是哪一类组件,实现上并没有明显的区别。它们都会按照一定的生命周期执行,所不同的是,渲染组件会在生命周期执行过程中生成HTML代码,而控制组件只会在生命周期中改变它所包含组件的渲染流程。

组件渲染生命周期


     上图给出了一个组件的标准渲染过程,定义了10个主要的执行阶段,可以看出每个阶段都有两条边输出边,分别对应着true和false两个选择。组件执行过程中,每个阶段都可以返回一个boolean值,决定下一步的执行路径(对于返回值为void的函数,默认为true)。我们再回头看看显示组件,它们一般不会改变组件生命周期的顺序,每个阶段都会选择true的那条边往下走,并在适当的阶段输出HTML代码片段。
     比如一个PageLink组件(用于生成指向其它页面的链接的组件),它会在BeginRender阶段输出一段类似于"<a href='page link'>"的代码,并在AfterRender阶段输出结束标签“</a>”,从而形成一个完整的<a>标签。而在<a>标签之间的文字或图片则是在RenderBody阶段完成。有一点值得注意, href 属性值是通过调用到Tapestry服务实现的,并非组件自己构造。
     对于控制组件则恰好相反,它们会在不同的阶段通过返回不同的值来控制页面的显示流程,但并不会生成HTML代码片段。
     比如 If组件(用于控制其所包含组件是否显示的组件),如果允许其内嵌的组件显示,则会在Begin Render阶段返回true,这样最终就会进入RenderBody阶段,显示其内嵌的组件。再比如Loop组件(用于循环显示的组件),如果循环没有结束,它会在AfterRender阶段返回false,这样该组件又会重新回到BeginRender阶段,并重新经过Render Body阶段,使得其内嵌的组件可以循环的被执行。总的来说,组件实现其职责的大致思路是分阶段的处理整个渲染流程。
下面我们看看最重要的几个阶段:SetupRender, Begin Render, Render Template, Render Body,After Render,和     CleanupRender。
     Setup Render 阶段主要用于渲染前的准备操作,比如初始化一些数据;
     Begin Render 主要用于生成一个HTML的开始标签,或者控制渲染流程;
     Render Template 主要用于渲染模板中的内容(页面和组件都可以具有模板)。这个阶段一般会有多个组件需要渲染,每进入一个组件,都会依次调用这个组件的各个生命周期阶段,也就是说,此处是一个从上层组件到其下层组件的一个递归入口,只有其下层组件渲染结束,该组件才会继续其后续阶段的操作。
     Render Body 与Render Template相似,也是渲染一段模板中的内容,所不同的是模板是组件和页面所具有的tml文件,而是组件被使用时,内嵌在组件中的一小段模板片段。比如对于pagelink组件(<a t:type="pagelink" page="index">thisis body</a>),它的body是“this is body”这几个文字。虽然对于模板的概念与RenderTamplate略有区别,但是它同样也是一个递归的入口。
     After Render 阶段一般用于生成一个结束标签,或者控制其内嵌组件的执行流程。
     Cleanup Render 这个阶段一般用于清除数据,但是由于框架会自动的清空页面的属性,所以一般不需要自己清除状态。除非你使用了一些特殊的资源需要清除。
     其它几个阶段并非经常用到,更多是保证生命周期的完整性,必要情况下,也可以生成HTML代码或修改组件的执行流程。
 
这是简单的介绍来一下关于tapestry5的页面渲染,接下来我将进一步介绍,请关注.
0 0
原创粉丝点击