Tapestry

记录学习Tapestry专用布格格。很多文章都转载网络。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  20 随笔 :: 0 文章 :: 4 评论 :: 0 Trackbacks

2005年12月1日 #

     摘要: tapestry的URL形如/examples/app?service=page/Admin
能够保证有效运行的一个非常重要的原因是,用有状态的javabean代替无状态的servlet构建一个tapestry应用。page是有状态的,他只能在一个线程里为一个用户处理一个 request,而一个servelet,没有用户的状态,可以在并发线程中为任何数量同时发生的request提供服务。使用有状态的page遇到的问题和使用数据库的连接遇到的问题非常相似  阅读全文
posted @ 2007-08-03 17:39 Tapestry 阅读(1089) | 评论 (0)编辑 收藏

http://www.javaeye.com/t/4463.html

<img jwcid="@Any" src="images/btn2.gif" onClick="ognl:yourScriptFun"/>

posted @ 2007-04-16 08:41 Tapestry 阅读(435) | 评论 (0)编辑 收藏

from http://dengyin2000.javaeye.com/blog/47452


a) @Persist("client")
b) @Persist("client:page")
c) @Persist("client:app")

a) is the same as b). If you use b) for a property x for page Foo, then
you can get back the property only if the navigation is Foo => Foo. If the
navigation is Foo => Bar => Foo, then it will be lost when Bar is
invoked. In contrast, if you use c), then it will be maintained all
the way.

client 跟 session是一样的效果只是实现的方式不一样, 一个是存在cookie或url中另一个是存在http session中。

client:page session:page 仅在当前页面有用, 假如转到其他页面 这个属性值就失效了。
client:app session:app 对于整个application都有效, 转到其他页面再转回来的话这个值仍然存在。如果我们想让他失效怎么办呢?你可以调用这个方法cycle.forgetPage("YourPageName").
posted @ 2007-04-11 11:50 Tapestry 阅读(511) | 评论 (0)编辑 收藏

     摘要: All interactive programs provide two basic functions: obtaining user input and displaying the results. Web applications implement this behavior using two HTTP methods: POST and GET respectively. This simple protocol gets broken when application returns web page in response to POST request. Peculiarities of POST method combined with idiosyncrasies of different browsers often lead to unpleasant user experience and may produce incorrect state of server application. This article shows how to design   阅读全文
posted @ 2007-03-30 23:03 Tapestry 阅读(1616) | 评论 (0)编辑 收藏

     摘要: http://ralf-realman.javaeye.com/blog/post/144266  阅读全文
posted @ 2007-03-30 22:43 Tapestry 阅读(706) | 评论 (0)编辑 收藏

     摘要: Tapestry的rewind一直是学习和使用Tapestry的难点,rewind是用来处理表单提交的,表单默认使用的是 DirectService来提交。在详细介绍之前,先说明下此文中需要用到的一些概念,首先是表单组件,我这里指的是指继承自 AbstractFormComponent类的组件,例如:TextField、TextArea、Checkbox等,而不是具体的Form组件,表单组件使用时必须在Form组件中,这些组件在rewind时调用继承自AbstractFormComponent的 rewindFormComponent来读取数据,并将数据赋值给容器或者页面。
我们来看一下最简单的TextField组件,组件定义如下   阅读全文
posted @ 2007-03-30 22:32 Tapestry 阅读(446) | 评论 (0)编辑 收藏

     摘要: 1. iframe所引用的页面类实现IExternalPage接口和activateExternalPage方法

2. 持有iframe的页面类中实现一个getIframeRenderer方法:  阅读全文
posted @ 2007-03-22 19:05 Tapestry 阅读(589) | 评论 (0)编辑 收藏

I've added a new screencast, this one showing off the use of the tapestry-simple Maven archetype to create a new project. It runs about five minutes and shows off how simple it is to get up and running.

If you haven't built Tapestry 5 locally, you need to remember to add -DremoteRepositories=http://people.apache.org/repo/m2-snapshot-repository/ to the command line.

I'm thinking about starting a vote to do a preview release of Tapestry 5, just to get the necessary JARs and archetypes into the general Maven repository.



posted @ 2007-01-30 09:47 Tapestry 阅读(240) | 评论 (0)编辑 收藏

     摘要: Tapestry中表单的提交有很多问题,刷新导致表单的重复提交、臭名昭著的dirty form warning、
显示不友好的URL等,这些都可以使用redirect-after-postpostredirectredirectredirectPagefriendlyUrlurl

要使用这个模式,不得不提到一个ILinkT4listener:
  阅读全文
posted @ 2007-01-29 18:56 Tapestry 阅读(874) | 评论 (1)编辑 收藏

     摘要: The toolkit known as GWT is all about creating dynamic client side javascript widgets and applications. The intriguing part of the toolkit is that these "scripty" bits are written as normal Java source code and are transcoded by the GWT compiler into relatively small and efficient javascript code. A "hosted" environment is provided by the toolkit which embeds a browser where developers can load their GWT enabled pages during development. When a page is loaded into this embedded browser, the GWT   阅读全文
posted @ 2007-01-29 18:53 Tapestry 阅读(681) | 评论 (0)编辑 收藏

     摘要: Tapestry4初试小结 http://www.blogjava.net/mstar/archive/2005/08/28/11393.html
  阅读全文
posted @ 2007-01-29 18:49 Tapestry 阅读(432) | 评论 (0)编辑 收藏

对之前的该文章进行了一些修正,主要是针对finishLoad()方法。

我觉得对初学者会有一些帮助。

下面这几个函数是我在使用的,它们的执行顺序依次从上到下。

1.protected void finishLoad() {} ***

2.public void pageValidate(PageEvent event) {}

3.public void activateExternalPage(Object[] parameters, IRequestCycle cycle) {}

4.public void pageBeginRender(PageEvent event) {}

// 如果有表单提交,则将form中的各字段的值赋给页面类
5. ...... 赋值

6.public void submit() // 表单提交等用listenter:调用的方法

7.protected void prepareForRender(IRequestCycle cycle) {}

----------------------------------------------------

1.protected void finishLoad() {}
这个函数最先执行,但是它实际上没有什么用处(我感觉)。因为:
  这个函数只在页面池中没有某一个页面类、需要生成一个新的页面对象时才调用。这里就有一个陷阱:如果你的tomcat启动时使用了- Dorg.apache.tapestry.disable-caching=true(为了调试方便而设),那么你每次刷新页面时,它都会执行(因为每个request都会新生成一个页面类对象),造成了它总是执行的假象。在实际的部署时,会使用caching,则这个函数执行的机会很少。所以要注意。
  初始化的代码放在4 pageBeginRender()中

2.public void pageValidate(PageEvent event) {}
如果实现了PageValidateListener接口,则可以在这里进行验证,比如访问权限等。执行完1后,它就开始执行。

3.public void activateExternalPage(Object[] parameters, IRequestCycle cycle) {}
如果实现了IExternalPage接口,则可以从这里取得由外面传过来的参数。执行2后,执行到这里。在这里可以把那些参数取出,赋给页面类。

4.public void pageBeginRender(PageEvent event) {}
执行完3后,将执行本函数。但是这时从客户端传过来的参数还没有被赋值(如果提交了表单的话)。这里可以进行一些初始化操作。

5.执行完4后,如果有表单提交,在这里将会取出那些值,赋给对应的字段。(注意:只是将表单中有的值赋过来)

6.public void submit()
如果有表单提交的话,在这里将进行对应的操作。因为此时各字段已经取好值了,所以可以拿来直接用。

7.protected void prepareForRender(IRequestCycle cycle) {}
最后才执行这个方法。我们可以在其中进行为了在页面上显示数据而进行的操作,比如取得什么对象什么的,因为这里页面类的属性赋值已经结束,可以直接拿来使用了。
注意:如果执行了6,则还要执行4,再执行7。如果没有6,4完了就直接是7。

以上是我所总结的执行顺序,不当之处请指出。

-----------------------------------------------------

最开始学tapestry的时候,觉得“怎么有这么多地方需要持久啊”。原来以前只知道pageBeginRender这个函数,什么初始化操作都放在它里面。可是它是在赋值之前执行,所以拿到的字段多都是空的,却都以为是没有持久化的缘故。所以在客户端里放了一大堆的@Hidden,或者 session中持久,非常麻烦,,,对tapestry也产生的怀疑。现在才知道那些需要取得客户端传来的参数的代码,最好放在 prepareForRender里,很多不必要的持久都可以省掉了。

posted @ 2007-01-29 18:47 Tapestry 阅读(273) | 评论 (0)编辑 收藏

第一,页面是页面,页面跳转的时候,需要清空properties数据,否则,这些数据保存在session里面,很容易造成bug。打个比方说吧,initialize()这个方法,的确,在页面表现的时候,执行两次。页面表现之前,初始化你的页面,然后页面表现你的业务逻辑,比如你要显示什么新闻呀等等。。。最后,页面在结束表现之前,再次执行这个方法,将你的properties还原为初始值,这样,在你的下次再访问该页面的时候,不会因为 properties的值已经改变而造成意想不到的错误。

第二,提交一般是指表单,也就是formSubmit。如果你希望这个表单在提交之前就有初始值,也很容易,将ognl对应的get方法对应的成员变量初始化一个值就可以。比如说用initialize()来初始化。在你submit之后,ognl会自动调用properties相应的set方法赋值,你在form对应的监听方法进行数据处理就可以了。

第三,其它的Tapestry自带方法就不说了。什么validate()等等,都不提,只讲这5个方法:
initialize()
detach()
attach()
pageBeginRender()
pageAfterRender()
它们的执行是有先后顺序的,其中只有initialize()方法会执行两次,其它的都执行一次。这些特点,足够你利用来做很多事。
页面在表现(render)的时候,我只以direct service举例:
1)执行initialize(),初始化该页面的properties,这些properties都应该是客户端的瞬时状态。
2)执行attach(IEngine value),获取你的engine。所以,你可以利用这个方法往你的web容器里面加载服务。
3)执行pageBeginRender(),同样是用来在页面表现之前,给你希望的变量赋值。。比如说,我基本上是用这个方法来获取Visit对象中储存的session值。
4)页面表现业务逻辑。你的什么Foreach啊,等等,现在才开始执行。
5)执行pageEndRender()。在你的页面业务逻辑表现完之后,如果你希望有什么后续工作,可以在这里执行。
6)执行detach()的super(),也就是执行AbstractPage里面Tapestry自己的detach(),目的是为了清空该页面所调用的engine,visit,requestCycle。因为如果不清空的话,比如什么用户信息的话,就可能会泄露。这个方法的存在是 Tapestry基于安全性的考虑。
7)执行initialize(),再次将你的properties恢复为初始值。
8)执行detach()里面,你自己写的内容。。
以上仅仅最简单的情况下,这5种方法的执行顺序。。。

posted @ 2007-01-29 18:46 Tapestry 阅读(557) | 评论 (0)编辑 收藏

     摘要: http://gocom.primeton.com/blog/index.php?op=ViewArticle&articleId=206&blogId=23
注意啦,Delegate堂而皇之地作为“一等公民”在C#中“直接支持”,而Tapestry这样的Java社区的著名项目又“转而采用”,给个理由先?  阅读全文
posted @ 2007-01-29 18:44 Tapestry 阅读(335) | 评论 (0)编辑 收藏

在4.0的官网上的说法是:
<implementation service-id="tapestry.multipart.MultipartDecoder">
<create-instance class="org.apache.tapestry.multipart.MultipartDecoderImpl,maxSize=-1" model="threaded" />
</implementation>
自己在更改后发现系统运行不了,在网上查了一下都说是4.0版本的问题,查看源代码发现其中的配置文件是写成 tapestry.multipart.ServletMultipartDecoder,因此应该将MultipartDecoder改成 ServletMultipartDecoder,更改后系统一切运行正常。开源的项目文档经常会有些小笔误,最好的解决办法就是看看源代码
在hivemind里配置:
<implementation service-id="tapestry.multipart.ServletMultipartDecoder">
<create-instance class="org.apache.tapestry.multipart.MultipartDecoderImpl,maxSize=-1" model="threaded" />
</implementation>
posted @ 2007-01-29 18:33 Tapestry 阅读(398) | 评论 (0)编辑 收藏

     摘要: 介绍:Tapestry框架底层使用了Hivemind这个小巧的IOC容器,很多功能都有相应的配置文件。
这些配置文件主要包括:service-point(服务点), implementation(服务实现),configuration-point(配置点)和contribution(配置实现)三个关键概念。
其中,服务点定义了服务的接口与默认实现,implementation可以覆盖服务点的默认实现,服务点ID和配置点ID在一个模块中必须唯一。  阅读全文
posted @ 2007-01-29 18:26 Tapestry 阅读(600) | 评论 (0)编辑 收藏

实在不太愿意去研究什么Java框架了,以前什么都学,结果弄得身心俱疲,不怎么愿意再下功夫了,还不如学好操作系统,学好数据库,那些东西几十年了基本上没有变化,而Java框架几乎每天都不一样,每天都有新的框架出现,每一个都是那么吸引人,可是再深入使用后总要发现又有更多的问题要去解决,所以框架就想办法去解决这些问题,结果原本简单的东西也复杂了。

现在的框架太多了,结合使用可不是每个人都搞得来了,很少有人有那么多时间,把所有的框架测试一边,然后结合在一起使用,Matt Raible的AppFuse给大家一个结合使用的Demo,还提供了一些开发模式,使用他提供的开发模式作一些例子非常快,可是如果让我们做一些东西,却不是那么简单,我们有太多事情不知道。

以前认真研究过AppFuse的各个部分,其中吸引人但也最乱的部分就是许多自动过程。Matt Raible确实把Ant使用的出神入化,后来我遇到不会的Ant用法,我也尝试在AppFuse里查找可能的用法。另一个就是自动代码生成机制,大多是用XDoclet完成,但是撰写自己XDoclet生成模版确实不是件容易的事,当页面有许多特殊情况的时候,这种自动生成机制实在只能作为一个辅助手段,只可以作为起始的模版,以后我们如果修改了模型,我们很难再通过这种生成机制生成页面和类,所有的工作我们要学着自己去作,这时候生成的代码就是一场噩梦,维护更加复杂。

当然有一些框架可以弥补这种生成的代码不好维护的问题,如Tapestry,另一个类似于AppFuse,号称MDA框架的Trails也使用这个作为前台现实的框架,可见Tapestry已经在这方面有一定的改善。不过Trails还是刚刚起步,未来还很难说。

我想,在对Ant和XDoclet还并不熟练时,在没有这种开发意识的情况下,还很难使用AppFuse来开发,但是AppFuse对我们来说有很多参考价值,它可以教会我们如何使用Spring,它可以教会我们如何写TestCase测试,也给我们很多启发,怎样才能尽可能的自动化代码工作,怎样优化我们的工作流程。

我现在一直关注着
Trails,在许多人看来TrailsAppFuse很类似,不知道它会发展到什么程度,它至少在表面看来比AppFuse简单,好像要简单一些,这是我们最需要的。
posted @ 2005-12-01 08:54 Tapestry 阅读(367) | 评论 (0)编辑 收藏