论坛首页 Java企业应用论坛

Tapestry 4.0 新特性(9月8日修订)

浏览 6175 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-06-09  
参考:http://jakarta.apache.org/tapestry/current/UsersGuide
基本上是理解性翻译,英文好的可以直接去看此guide,我只是做了笔记,然后放到这里希望能对大家有所帮助。
新特性我也只是了解,没有具体应用(很想用:D),有理解错误的地方,希望大家原谅。

Tapestry4新特性(一)-default binding types

default binding types(默认的绑定类型)
    每一个组件的参数都可以定义默认的绑定类型,如果一个绑定的参数没有前缀,将使用默认的绑定类型。
    下面的代码实现同样的功能:


<ul element="ul" jwcid="@Foreach" source="ognl:items" value="ognl:item"> <li><span jwcid="@Insert" value="ognl:item.name"/> </ul>

<ul element="ul" jwcid="@Foreach" source="items" value="item"> <li><span jwcid="@Insert" value="item.name"/> </ul>    

     加粗的部分显示前后的变化,之所以可以这样定义,是因为Insert组件定义value参数的默认绑定类型为ongl.
     注意:默认的绑定参数总是可以被显式的绑定声明覆盖掉。
    如果没有定义默认的绑定参数,那么在html模板中定义的默认绑定参数为literal,页面定义文件里的默认绑定参数为ognl
修订:

从beta4版本开始,此特性已经被删除,

Beta4的change log:

Remove default-binding attribute from element(HLS)

但是“如果没有定义默认的绑定参数,那么在html模板中定义的默认绑定参数为literal,页面定义文件里的默认绑定参数为ognl”这个效果经测试依然存在。

怀念:

此段文字在beta3中存在,beta4后就删掉了!

Binding Type Defaults
Tapestry 4.0 introduces a new idea: default binding types. Each component parameter may define a default binding type (using the default-binding attribute of the <parameter> element).

If a binding reference does not have a prefix, the default binding type is used.

Because of this, the following two snippets are identical:

<ul element="ul" jwcid="@Foreach" source="ognl:items" value="ognl:item">
  <li><span jwcid="@Insert" value="ognl:item.name"/>
</ul>
<ul element="ul" jwcid="@Foreach" source="items" value="item">
  <li><span jwcid="@Insert" value="item.name"/>
</ul>
This works because the Insert component defines the default-binding for the value parameter to be "ognl". Likewise, the source and value parameters of the Foreach component are defined to be "ognl". However, the element parameter of the Foreach component has a binding type of "literal".

This is a decision made by the component author. If a particular parameter is (nearly) always bound using a particular binding type, then a default-binding may be set. The default binding can always be overriden with an explicit binding type prefix.

What about parameters that don't define a default binding type? The answer to this question (which includes all informal parameters), is that it depends on whether the parameter is bound in an HTML template, or in a page or component specification. In an HTML template, the default binding type is "literal". In a specification, the default binding type is "ognl".

Tapestry4新特性(二)-listener method

     如果使用过tapestry的应该知道listener方法在4.0以前版本中的定义,如public void formSubmit(IRequestCycle cycle),方法必须有一个IRequestCycle参数。参数的取得方式如下:Object[] parameters = cycle.getServiceParameters();
     在4.0中参数的取得可以通过以下两种方式:

1、调用IRequestCycle.getListenerParameters()方法,需要传入IRequestCycle实例作为参数。
2、按照参数的声明顺序依次定义为listener方法的参数。
     第二种方法比较符合软件的设计思维,而且参数的类型在传入后保存,而不是想象中的统一String类型。
例如:
<a jwcid="@DirectLink" listener="doClick" parameters="{ objectId, index }"> . . . </a>
其中objectId为String类型,index为int,声明中使用了默认的参数绑定类型。
对应的方法声明如下
public void doClick(String objectId, int index)
{ . . . }
此为第二种方式,可见方法的定义符合自然习惯,当然你也可以通过传统的方法,如下所示: public void doClick(IRequestCycle cycle)
{ Object[] parameters = cycle.getListenerParameters();
String objectId = (String)parameters[0];
int index = ((Integer)parameters[1]).intValue(); . . . }
这种方式是为了向后兼容以前的版本,当然也适用那种参数数目不确定的情况。 Tapestry默认搜索以下的方法声明:

1、public void method(parameters)(页面的跳转 cycle.activate()如何实现?)
2、public void method(IRequestCycle cycle, parameters) (倾向于使用此方式)
3、public void method()(无需参数传递和页面跳转的情况,估计可能性不大)
4、public void method(IRequestCycle cycle)(传统方式)
   不要试图通过参数的类型来映射listener方法,tapestry是根据参数的数目来确定方法的。

Tapestry4新特性(三)-Global Property Source(全局的消息属性配置)

消息属性配置听起来不是很舒服,暂时这样称呼好了,消息属性配置也就是通称的国际化配
置,通过配置一个properties文件使不同语言的浏览者看到对应语言的版本,一般
的使用如下,一个page页面,例如example.page,同目录下放一个
example.properties,在 example.html中使用<span key="key"/>来指定显示值,
中文可以使用example_zh_CN.properties来配置。看起来挺方便的,可
tapestry4.0以前的版本的国际化不支持全局的属性配置文件,必须每个页面定义
自己的,无法几个页面共享,但实际开发中,多页面共享属性配置是很常见的,
tapestry4.0中可以通过以下方式获得全局的属性配置文件:
创建一个跟你的项目全局配置文件,如yourApp.application,此文件在4.0以前的
版本中是必须的,4.0中如果没有必要配置,可以不需要此文件(扯远了),yourApp
是根据你在web.xml定义的,例如
<servlet>
<servlet-name>tapesty4</servlet-name>
<servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
那属性定义文件就应该是tapestry4.properties,这样在此文件中定义一个:test=
测试,在Home.html中使用< span key="test">test</span>,看到“测试”正确显示。

Tapestry4新特性(四)-源代码标注的异常处理

Tapestry本来提供的debug功能就十分强大,4.0版本中提供了更加详细的报错机制,可以显示错误的代码,并在报错的地方加亮标注,具体截图请看附件(谁能告诉我怎么将多余的照片删除呀)


Tapestry4新特性(五)-Friendly URLs

Tapestry4.0以前版本中的URL一直被人所诟病,当然现在已经有很多的解决方
案,4.0版本中已经对此做了改进,
因为现在的版本需要通过hivemind来配置,所以需要设置hivemind.xml中的一些属
性,具体配置如下:
<?xml version="1.0"?> 
<module id="tapestry4" version="1.1.0">
<contribution configuration-id="tapestry.url.ServiceEncoders">
<page-service-encoder id="page" extension="html" service="page"/>
<direct-service-encoder id="direct" stateless-extension="direct"
stateful-extension="sdirect"/>
<asset-encoder id="asset" path="/assets/"/>
<extension-encoder id="extension" extension="svc" after="*"/>
</contribution>
</module>

同时web.xml中加入映射:
<servlet>
<servlet-name>tapestry4</servlet-name>
<servlet-class> org.apache.tapestry.ApplicationServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>tapestry4</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>tapestry4</servlet-name>
<url-pattern>*.direct</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>tapestry4</servlet-name>
<url-pattern>*.sdirect</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>tapestry4</servlet-name>
<url-pattern>/assets/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>tapestry4</servlet-name>
<url-pattern>*.svc</url-pattern>
</servlet-mapping>
如果希望首页的调用不是通过/app来映射,可以在web.xml中更改redirect:
<filter-name>redirect</filter-name>
<filter-class>org.apache.tapestry.RedirectFilter</filter-class>
<init-param>
<param-name>redirect-path</param-name>
<param-value>/Home.html</param-value>
</init-param>
</filter>
这样键入http://localhost:8080/tapestry4,系统导航到http://localhost:
8080/tapestry4/Home.html,
添加一个Page页面例如Test.page,在Home.html中加入<a href="#"
jwcid="@PageLink" page="Test">test</a>,
在生成的Home.html中生成的test的链接地址为:http://localhost:
8080/tapestry4/Test.html

Tapestry4新特性(六)-自动定位页面类文件

关于此特性的介绍请参考:http://jakarta.apache.org/tapestry/current/UsersGuide/page-class.html
说明:

通俗点说就是您可以不定义.page文件或者定义的.page文件中不指定class 属性,而让服务器自动根据.html文件的路径来寻找对应的类文件。
配置:
在.application的定义文件中添加: <meta key="org.apache.tapestry.page-class-packages" value="org.edynasty.pages"/> 这样如果在文档根目录下有个Home.html文件,你就可以将Home.java放到 org.edynasty.pages(实际开发中配置为您自己的包名)包中,tapestry自动根据 Home.hmtl构造org.edynasty.pages.Home来定位页面的类文件,当然您也可以在WEB -INF目录下放一个Home.page,不需要定义class属性,tapestry自动按照上边的原 理定位。
效果:
这样您可以不需要维护.page中的class属性,直接根据.html文件来写对应 的类文件。而且可以根据业务逻辑来定义目录结构,例如将 org.edynasty.pages.user定义为user相关的类,.html也就可以放到user目录下 边,目录结构如下:
user/ListUsers.html
user/EditUser.html
course/ListCourses.html
course/EditCourses.html
Home.html

Tapestry4新特性(七)-Application和Session范围对象的使用

关于此特性的介绍请参考:http://jakarta.apache.org/tapestry/UsersGuide/state.html
说明:
Application和Session范围的概念就不说了,T4以前的版本只可以分别指定一个对象,
以前版本的定义如下:
<property name="org.apache.tapestry.visit-class" value="your.package.Visit"/>
<property name="org.apache.tapestry.global-class" value="your.package.Global"/>,
T4中可以指定任意多的对象,而且默认的visit和global仍然可以使用。

配置:
在hivemodule.xml的定义文件中添加:
<contribution configuration-id="tapestry.state.ApplicationObjects">
<state-object name="applicationUser" scope="application">
<create-instance class="org.edynasty.model.User"/>
</state-object>
<state-object name="sessionUser" scope="session">
<create-instance class="org.edynasty.model.User"/>
</state-object>
</contribution>
两个user分别对应Application和Session范围,在需要使用user的page中注入:
<inject property="applicationUser" type="state" object="applicationUser"/>
<inject property="sessionUser" type="state" object="sessionUser"/>,通过
getter和setter方法调用。

效果:怎么说呢,可以不需要在一个visit中定义N多属性,因为Session的创建需要资源,
只要操作一个visit的属性,就需要创建整个visit,分别定义之后,可以在需要存取时分别创建。
   发表时间:2005-06-09  
恩,改了一些东东,看起来有点意思了。
不过强迫用hivemind,hls真是@#$%^&
0 请登录后投票
   发表时间:2005-06-09  
T4与Havmand集合在了一起,要是能谈谈配置心得就好了。
Tapestry非常好,可惜了解的人太少。
0 请登录后投票
   发表时间:2005-06-13  
等待继续更新
0 请登录后投票
   发表时间:2005-06-13  
对tapestry持续关注中,我觉得它有前途。
0 请登录后投票
   发表时间:2005-06-13  
对于Tapestry4.0,我想说的第一句话就是:偶很不爽。

没有想到Howard说变就变,原本的3.1一下子就改为和Hivemind结合在一起的4.0。当然,开源项目都是这样,变与不变,又或者改变多少,仅在其作者一念之间。所以上周听Ewaves大哥无奈地说,由于他公司的经理担心Tapestry的稳定性,只好回归struts。对此,偶除了望天长叹,无可奈何也。

自从Howard扬言将Tapestry3.1直接提升为Tapestry4.0之后,我就再也没有关注过Tapestry,很简单的理由,如果要为Tapestry4.0而放弃我们已经相当熟练的spring,改为使用陌生的Hivemind的话,且不要说去说服我们经理,就连我自己都说服不了自己。

不过,最终是否使用Tapestry4.0,我还需要进行非常慎重地考虑和研究,Howard说他已经在做最后地注释添加工作,相信已经离正式发布不远。正式发布之后,我会去看看里面的结构,是否能够将Tapestry4.0从Hivemind中脱离出来。

其实,虽然我对Tapestry4.0不爽,但是我却非常认同Tapestry基于组件的表现层的编程理念。实际上Tapestry不论4.0也好,3.0.3也罢,我看来影响不大。哪怕即便Tapestry出到10.0,其核心程序的思维逻辑仍然不会有本质变化,就好象现在JSP出到2.0,而J2SDK出到1.5,但是大部分程序员仍然使用J2SDK1.4。从Tapestry4.0的新功能来看,这些都已经在3.0.3中另谋途径而得以实现。如果需要AOP进行特殊操作,添一个AspectJ就完了,上周我还尝试在Tapestry中添加OSCache。

我使用Tapestry已经快8个月,现在在做第四个项目的开发,积累的组件也有十几个,这个星期还可能对JS地图进行动态script封装(就是google上那种很冈的JS地图)。从技术与公司角度来讲,即便在未来两三年都只使用Tapestry3.0.3,对项目的开发效率以及项目积累,已经存在的优势并不会因使用Tapestry4.0而有所增减。而两三年后,所谓的“胖客户”技术已经趋于成熟,技术的时代又变了。

呵,不好意思,忍不住在此抱怨几句。shanghai和我也接触过,都相当认可Tapestry这门技术,算是同好之人。表现层这个领域的技术,从JSP发展到Tapestry,从基于元素发展到基于组件,这是一种技术的改革与进步。但是Tapestry3.0到Tapestry4.0的改变,只能够说明其功能在应用领域的完善,并不意味着技术的进步。所以虽然Tapestry4.0与Tapestry3.0变化的确有些大,但是其核心技术是已经足够成熟的(请不要和争论Tapestry是否足够成熟,我厌倦了这种争论,可以去参观我用Tapestry做的已经发布的项目。)。因此在我眼中,4.0与3.0仅仅代表这两种不同功能地相同工具,就好比“平口起子”和“十字起子”。不过的确有朋友因为Tapestry从3.0到4.0如此之大的变化而担心其稳定性,对此我仅仅只能够说,这些朋友不了解Tapestry这门技术罢了。
0 请登录后投票
   发表时间:2005-06-13  
Tapetry从3.1提升到并不是Howard决定的,而是整个Tapestry的社群的共同讨论的结果,整个过程陈列在邮件列表中,投票结果大多数投票着都是持赞成的态度。
事实Tapestry3.1一开始就是以Hivemind为底层机制的,这个在3.1没有开始开发的时候就已经定下来了,并不是因为4.0的原因。另外Tapestry 4.0并不强迫使用Hivemind,你依然可以使用非常熟悉的spring。
0 请登录后投票
   发表时间:2005-06-14  
hivemind是个依赖注射的微内核,如果我是tapestry的作者我也会采用自己的框架来开发,而且他并没有强迫用户使用hivemind来完成依赖注射,其实这好像就是一个错觉,就因为hivemind是一个依赖注射的容器,就觉得它跟sping不能共存,好像有点牵强,你可以使用hivemind来配置tapestry,注射可以使用spring,这点我相信完全可以做到,就是作者不做,开源社区也会有人做,tapestry4给我的感觉就是更加的自然,页面定义的简化和组件开发的简化都是令人激动的,现在正研究如何从T3移植到T4,新特性文章只有在研究中去发现了,下面是tapestry4中使用spring的方法,但是其不能用于t4 alpha3的版本,在即将发布的版本中其已经作为bug被修正了,希望新版中不会出现这个问题:

通过hivemind在tapestry中使用spring

tapestry4.0中使用hivemind作为微内核,Hivemind也是一个依赖注射的容器,其
功能有一部分与spring重合,但spring 有良好的用户基础,所以使用hivemind访
问spring中定义的bean是在tapestry中集成spring的关键,这个功能可以通过一个
软件包实现,项目地址:http://sourceforge.net/projects/diaphragma/,下载
tapestry- spring.jar包,放入系统类路径,就可以在页面和组件的定义中使用
hivemind提供的注射功能访问spring中的bean定义。 hivemind.xml不需要做任何
修改,但spring容器必须通过web容器启动,web.xml中启动spring容器:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
这样spring中定义一个bean,例如
<bean id="user" class="tapestry4.pages.User">
<property name="name">
<value>jimlaren</value>
</property>
</bean>

Home.page中定义注入: <inject property="user" object="spring:user"/>
Home.html中访问:<span jwcid="@Insert" value="ognl:user.name" />

输出:jimlaren
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics