简介
Apache Tapestry是一个使用Java语言创建web应用的面向组件的开发框架。Tapestry应用建立在根据组件构建的页面的基础上。这个框架能够提供输入验证(inputvalidation)、本地化/国际化(localization/internationalization)、状态/持续性(state/persitency)管理、URL构建/参数映射(parametermapping)等功能。为什么Tapestry值得推荐呢?一部分原因是:它便于终端用户使用。Tapestry在设计最初就考虑到了应用的安全和伸缩性,有内嵌的Ajax、输入验证、国际化以及异常报告功能。它便于开发人员使用。Tapestry独一无二的类重加载(class-reloading)特性大大地推动了开发人员的开发效率。借助于Tapestry,对源代码的修改立马就可以看到结果,不需要重新部署和启动应用!它的异常报告也极为具体,甚至提供可能的修正建议。它便于web设计者使用。Tapesry页面是有效的HTML(或XHTML)文件!你可以用自己喜欢的浏览器打开这些页面。它封装了最佳实践:REST风格的URL、可降解的JavaScript、没有XML的配置等等。
在本项目的web.xml文件中有如下配置:
<context-param>
<!-- The only significant configuration for Tapestry 5, this informsTapestry of where to look for pages, components and mixins. -->
<param-name>tapestry.app-package</param-name>
<param-value>net.project.view</param-value>
</context-param>
这个配置也比较重要,这个配置项告诉Tapestry去哪个package下面去找页面、组件、服务等东西。在源代码中需要在此配置的package下面建立4个package,分别为:com.demo.pages,com.demo.components, com.demo.services, com.demo.mixins
现在流行约定高于配置,所以Tapestry 5.1默认要求使用这样4个package名称。其中页面类放在pages目录下,组件放在components目录下,服务放在services目录下,mixins翻译起来比较困难(Tapestry的作者也说mixins是一个很tricky的概念,这是一种能让一个真的组件与一些其他特殊组件混合起来的东西)。
web.xml中的过滤器配置
<!-- Tapestry 5 filter -->
<filter>
<description>Custom filter for TapestryFramework</description>
<filter-name>tapestryFilter</filter-name>
<filter-class>net.project.hibernate.util.CustomTapestryFilter
</filter-class>
</filter>
<!-- Tapestry 5 filter mapping -->
<filter-mapping>
<filter-name>tapestryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这个filter-name是比较重要的一个名字,Tapestry没有一个象Spring那样的Xml配置文件,它的初始化配置工作在一个初始化类中完成,这个初始化类需要放在上面提到的services目录下,类名就是filter-name+Module.class。
在本项目中,类名称是:
net.project.view.services.TapestryFilterModule
页面
页面模板和页面Java类处在同一位置,扩展名为tml,代表Tapestry Markup Language
${开头,以}结尾的部分是expansion
常用expansion包括:
l asset
l block
l component 组件编号
l context 上下文路径
l literal 字符串
l nullfieldstrategy 空串策略
l message 本地消息
l prop 属性。缺省前缀,可以省略。
l translate
l validte
l var 组件变量
tapestry查找页面模板的顺序:
1、 在页面所在类的系统目录
2、 在web根目录
Page的onActivate实际上是对tapestry的事件Activate的一种响应,该事件发生在页面加载前,并且会根据上下文调用。
例如,假设有一个Page类名为Extend,那么使用如下链接:
/sessionHook/Extend/get_session_inactive_interval
会在生成html前,调用
Object onActivate(String action)
其中action参数的值为get_session_inactive_interval
如果使用如下链接:
/sessionHook/Extend/
那么会启用
Object onActivate()
sso (Session State Object)使用@SessionState存储在会话中的数据。注意,sso只与类型相关,同一类型的任意名称,存取都是同一个session变量。
组件
组件类必须在components包下面,可以带参数,也需要配套的模板文件.tml。
@Parameter注解用于定义组件参数
tapestry会对组件逻辑名进行优化,当包名是组件名的前缀/后缀时,前缀/后缀会自动去除。
组件解析过程如下图所示:
组件中每个橘黄色的阶段,对应组件的一个方法。tapestry使用annotation来标示组件的方法。例如SetupRender方法由@SetupRender注解标示。
注解
tapestry在很大程度上依赖于Java注释,而不是XML文件,几乎它的所有配置。 (另外,Tapestry的方法命名约定的意思是你在许多情况下不必使用注释)。
Tapestry的注解根据他们的目的被分为几个不同的模块。
Tapestry Core and IoC 注释
大多数的tapestry注释(Tapestry Core and IoC的定义)是非常具体的Tapestry组件或Tapestry的IoC服务:
TapestryComponent 注释
注释类型概要 | |
ActivationRequestParameter | 标志着一个领域一直保存在URL(不是组件)的页面激活的context。 |
AfterRender | 标记注解的方法与AfterRender阶段。 |
AfterRenderBody | 对应到BeforeRenderBody,允许额外的标记渲染一个组件体后,在此之前呈现的其余部分的组件的模板。 |
AfterRenderTemplate | 对应到BeforeRenderTemplate,允许额外的标记后使组件的模板。 |
BeforeRenderBody | 标记方法被调用组件时,渲染状态机在body元素出现在组件的模板。 |
BeforeRenderTemplate | 相关联的组件,有一个模板,该阶段被调用来允许组件装饰它的一些附加的标记的模板。 |
BeginRender | 此方法,应在开始呈现组件执行标记注释。 |
BindParameter | 指定一个mixin这个必须的值对应于包含的组件的参数中的一个字段。 |
Cached | 表示方法应该只进行一次计算和缓存的结果。 |
CleanupRender | 标记注释的组件渲染状态机与终端阶段的组件方法。 |
Component | 在另一个组件用于定义一个嵌入式组件。 |
ContentType | 注释页面上的组件,用于识别的内容,返回页面的类型。 |
DiscardAfter | 标记页面或组件的方法,放弃所有的持久化字段的变化。 |
Environmental | 组件类定义一个字段,在运行时从环境服务替换一个只读值。 |
Events | 注释应用到组件记录一个组件可能会触发什么事件。 |
HeartbeatDeferred | 标记组件的方法,推迟Heartbeat结束。 |
Id | 可选的注释,用于注射,它的存在是为了提供一个对象的id时,它不能确定通过其他方式(如从字段名)。 |
ImmutableSessionPersistedObject | 标记注释可以放置在一个会话持久化对象,对象是不可改变的,因此不需要恢复到会话的请求。 |
Import | 控制导入JavaScript栈和库以及样式表的注释。 |
InjectComponent | 允许在模板中定义的组件被注入为只读属性。 |
InjectContainer | 用于注入的组件包含该组件。 |
InjectPage | 允许一对一页(在页面的根组件)被注入到另一个组件是一个只读字段。 |
Log | 标记注释组件的方法,使调试级别的日志记录。 |
Meta | 允许的每个组件的元数据的规范。 |
Mixin | 定义一个实现mixin的一个组成部分。 |
MixinAfter | 标记注解应用到一个mixin, mixin的渲染状态的行为声明被推迟到的mixin是连接组件的行为。 |
MixinClasses | 用于连接一个或多个实例,混入一个嵌入式组件。 |
Mixins | 用于连接一个或多个实例混入到一个嵌入式组件。 |
OnEvent | 标记作为一个客户端事件处理程序的方法。 |
PageActivationContext | 页面激活context处理程序(onActivate和onPassivate)建立一个字段的注释。 |
PageAttached | 已过时。在Tapestry5.3开始不再使用。 |
PageDetached | 已过时。在Tapestry5.3开始不再使用。 |
PageLoaded | 使用方法注释的页面完全加载后,应调用的方法。 |
PageReset | 当一个页面被重置的方法被调用的标记注释。 |
Parameter | 注释放在一个字段,以表明它是一个组件参数。 |
Path | Inject注解,基于路径的asset注入结合使用。 |
Meta | 允许的每个组件的元数据的规范。 |
Persist | 持续性,这意味着其价值仍然存在,从一个请求到下一个标识字段。 |
Property | 字段的存取方法(getter和setter)的注释。 |
RequestParameter | 注释可能被放置在事件处理程序方法的参数。 |
Retain | 已过时。在Tapestry5.2开始不再使用。 |
Secure | 一个标记注释,指出有问题的页面可能只通过HTTPS访问。 |
Service | 适用Inject注解结合,以确定一个服务名称,而不是按类型。 |
SessionAttribute | 用于映射一个页面或组件的属性值存储在会话中。 |
SessionState | 标记注释的领域,这是一个会话状态对象(SSO)的ApplicationStateManager控制。 |
SetupRender | 标记注释的方法,应执行在SetupRender阶段。 |
SupportsInformalParameters | 用来识别一个组件,它可以支持非正式参数。 |
WhitelistAccessOnly | 标识的页面应该只从客户端访问的白名单。 |
TapestryIoC 注释
注释类型概要 | |
Advise | 一个注解,可以放置一个模块上的顾问方法。 |
Autobuild | 通过ObjectLocator.autobuild(class),指示要建的值应该是一个自动生成实例的类型进行注射。 |
Contribute | 一个注解,可以放置在一个模块的贡献者的方法。 |
Decorate | 一个注解,可以放置在一个模块的装饰方法。 |
EagerLoad | 实现标记注释放在服务应急切地加载一个服务构建器方法:如果一个服务方法被调用。 |
Inject | 这个注解服务是依赖注入到任意的Java Bean的方法相关的操作的东西。 |
InjectResource | 已过时。在Tapestry5.3开始不再使用。 |
InjectService | 注释使用的服务构建方法的参数被注入到服务构建器方法通过参数识别服务。 |
IntermediateType | 用于引导tapestry强迫从一个原始类型时,一个字段或者参数的类型迫使tapestry中间型。 |
Local | 限制搜索可能的服务只是同一个模块中包含的服务被注入一个特殊的标记注释。 |
Marker | 用于定义一个或多个标记注释的服务实现。 |
Match | 可选的但经常使用的注释,用来定义哪些服务适用于装饰服务的装饰方法。 |
NotLazy | 标记方法,特别不是懒加载,即使在同一个界面的其他方法被建议为懒加载。 |
Optional | 在一个模块作为可选的服务标记贡献法:如果不匹配的贡献与实际的服务,它是不是一个错误。 |
Order | 与服务的装饰方法来控制装饰品出现的顺序。 |
PostInjection | 注射后应调用的方法注释。 |
PreventServiceDecoration | 一个服务标记不符合装饰。 |
Primary | 注释标记用来表示一种服务,是一些常见的接口的主实例。 |
Scope | 一个可选的注释,可以被放置在一个模块服务的建设方法,或实现类(使用服务时绑定)。 |
ServiceId | 一个可选的注释,可以被放置在一个模块服务的建设方法,或实现类(当使用服务绑定通过的ServiceBinder)。 |
Startup | 一个注解,可以放置在一个模块的启动方法。 |
SubModule | 连接到模块类,此批注的其他模块类的,应该也可以添加到注册表。 |
Symbol | 用于注射的符号值,通过符号名。 |
UsesConfiguration | 一个文档接口服务的服务接口,一个无序的配置,以确定类型的贡献。 |
UsesMappedConfiguration | 放在一个文档接口上有一个映射配置的服务接口,以确定类型的键(通常是一个字符串)和ofcontribution的类型。 |
UsesOrderedConfiguration | 放在一个文档接口,服务接口的服务,有一个有序的配置,以确定该类型的贡献。 |
UseWith | 诠释记录tapestry提供注解可以使用的context。 |
Value | 注入一个文本值,而不是服务结合使用。 |
hibernate注释
注释类型概要 | |
CommitAfter | 标记为事务性的服务(或组件的方法)。 |
Tapestry持久化
针对于单个page而言
Tapestry有一个@Persist注解,它有三种类型,Session,Flash,Client(不推荐)。
Session,默认级别,经过多次请求,它会保存一个页面上的数据。
Flash,(PersistenceConstants.FLASH),信息仍然是储存在session里面,但是它不会被保存太长时间,一旦它在页面上显示过一次了就会被从session中删除。
Tapestry的请求时Post-Redirect-Get类型的,应该说它会在一个请求完成之后就删除。
凡是被@Persist标注的变量是不允许设定默认值的,无论直接赋值或者在构造器中设定值。