对2007年《tapestry 3.0 绘制页面》的补充和修改。
回头看了一下2007年的那文章,感觉文字没有组织好,虽然大意还是讲明白了。
也有几处没有说仔细,还有几出写错,不想在原文上修改和补充了,所以写了这个新
文章。
==============================================
模拟一个Tapestry 的ApplicationServlet ,并且假定它在web 服务器上是可以直接运行的。
class myApplicationServlet extends HttpServlet {
RequestContext context = null;
ApplicationServlet servlet = null;
IRequestCycle requestCycle = null;
String serviceName;
IEngineService service = null;
IPage requestPage = null;
public void setUpMyEngine() {
context = getContext();
servlet = context.getServlet();
//从client取得每次service名
serviceName = extractServiceName(context);
service = getService(serviceName);
//生成requestCycle
requestCycle = createRequestCycle(context, service, monitor);
}
/* 某个client要求某张页面
* servlet就获取这个要
*/求的页面
① public void getRequestPage (){
requestPage = requestCycle.renderPage();
}
//把这页面绘制出来
public void renderPage( requestPage ){
.....
//事件处理段,处理pageBeginRender
if (_listenerList == null)
return;
PageEvent event = null;
Object[] listeners = _listenerList.getListenerList();
for (int i = 0; i < listeners.length; i += 2)
{
if (listeners[i] == PageRenderListener.class)
{
PageRenderListener l = (PageRenderListener) listeners[i + 1];
if (event == null)
event = new PageEvent(this, _requestCycle);
l.pageBeginRender(event);
}
}
//判断是否rewinding
if (!requestCycle.isRewinding()){
requestCycle.commitPageChanges();
}
② render(writer, cycle);
//事件处理段,处理pageBeginRender
if (_listenerList == null)
return;
PageEvent event = null;
Object[] listeners = _listenerList.getListenerList();
for (int i = 0; i < listeners.length; i += 2)
{
if (listeners[i] == PageRenderListener.class)
{
PageRenderListener l = (PageRenderListener) listeners[i + 1];
if (event == null)
event = new PageEvent(this, _requestCycle);
l.pageEndRender(event);
}
}
}
}
==========================================
一张页面类,代码:
public abstract class MyPage extends BasePage implements PageRenderListener {
/* 省略getter/setter */
.....
public void submitAction(IRequestCycle cycle) {
//todo
}
public void pageBeginRender(PageEvent event) {
//todo
}
}
============================================
说明:
我是参考Tapestry的源代码写的,经过了自己的改造,省略掉了很多东西,代码不是很完整的。
但是觉的,应该不影响阅读了(特别是针对一次具体的表单提交的request),所以我就不完善整理了。
①生成了MyPage实例,然后可以在myApplicationServlet是调用这个实例的代码(如 myPage.pageBeginRender());
至于submitAction()代码的运行,是在②处进行的,我这里没有展开写,只要明白就可
以了。所以,怎么写好②处的代码也是很讲究的。
②处还可以看成是,我在2007年写的《tapestry 3.0 绘制页面》中代码的入口,在这里开始render页面。
②处,还得处理假如是rewind的时候,重新绘制表单的html,即rewindFormComponent( ),然后才可以
render下整张页面。
②处没有写仔细,看来我偷了很大的懒啊,呵呵。
总结:
可以看出来
|----render ----------------> |
一次具体Request ---> | | ----->Response Client
|----rewind ---- render --->|
==================================
什么是rewind / render ?
Page rewinds, which are related to the Form and ActionLink components, also perform a render
operation in order to restore dynamic state on the page. The PageRenderListener events are
still fired. The event listeners can invoke isRewinding() on IRequestCycle to determine whether
this is a normal render, or for rewind purposes.
The properties of a page and components on the page can change during the rendering process.
These are changes to the page's dynamic state.
rewind 就是用来处理表单,用来实现DirectService服务。(带有Action的组件是放在表单里面的)