bug
* element.forceattribute uses the element's namespace to match the attribute.
* element.attribute(string name, string value) adds elements that already exist
* element#addclassname can create an additional new 'class' attribute
* properties defined in an interface are not exposed by propertyaccess for abstract classes that do not directly implement the methods
* some services require a notification that they have been reloaded, so they can clean up external dependencies
* whitespaces in symbolconstants.supported_locales cause that locales are not persised
* validation macros do not work when used in @validate annotation
* client-side validation of @pattern is broken
* linking a form to a zone will no longer work unless the form contains validated fields
* when using propertyshadowbuilder to build a service, if the property is null, an immediate exception is needed (rather than a nullpointerexception)
* when using a multizoneupdate, tapestry will clear the referenced zone
improvement
* add the facility to optionally disable on-focus-change triggered validation while retaining the on-form-submit validation
* form component should be able to render a secure url even on an insecure page
* new annotations @decorate and @advise to identify methods that decorate or annotate services
* extend link with new methods for producing absolute urls (that include scheme, hostname, etc.)
* simplify connecting a link or form to an (enclosing) zone
* beanblockcontribution should be split into two sub-classes: editblockcontribution and displayblockcontribution
* define a special css class to prevent a client-side form from submitting normally (for ajax use cases)
* additional method for link: addparametervalue(string,object) that uses contextpathencoder to encode object value to a string
* seleniumtestcase should expose the underlying commandprocessor, to allow execution of commands not defined by the selenium interface
* allow individual seleniumtestcases to run w/o configuring seleniumlauncher
name | column1 | column2 | column3 | column4 | column5 | column6 |
---|---|---|---|---|---|---|
test | 00150002331 | 238156 | 075 | 001 | 172.16.14.20 | 1-1-05 |
test-2 | 00150002332 | 238157 | 075 | 002 | 172.16.14.21 | 1-1-05 |
test | 00150002333 | 238158 | 075 | 003 | 172.16.14.23 | 1-1-05 |
test | 00150002341 | 238159 | 075 | 004 | 172.16.14.24 | 1-1-05 |
test | 00150002339 | 238186 | 075 | 006 | 172.16.14.26 | 1-1-06 |
自定义prefix一般来说是3个步骤,
1、定义一个bindingfactory,这个需要实现bindingfactory接口
2、定义一个binding继承abstractbinding
3、注册这个binding
看一下具体的prefix的类:
@property
private string datefrom;
@property
private string dateto;
object onformsubmit() {
output.setdatefrom(datefrom);
output.setdateto(dateto);
return output;
}
首先使用注解注入output页面,然后在表单的提交事件中,返回output,这样就在程序中定义了返回页面,而不是使用配置文件的方式。
但是这样的实现却不能正确运行,原因是因为tapestry5的使用了页面池技术,页面在每次渲染前都是从页面池中随机获取一个页面,而从页面池中取得的页面,所有的属性都是被清空了的。
也就是说在上例中,虽然我们注入了output页面,但是此页面马上就被放入了页面池,而且其中的属性值马上就被清空了。这就是引入onactivate和onpassivate这丙个方法的原因。tapestry5在清空属性前会首先查看是否包含onpassivate方法,如果有,就把其返回值保存起来,然后从页面池中取得页面后,再把刚才保存的值作为参数传递给onactivate方法。
这就是方法3的基本原理,但是无论是在官方的文档或是示例或者网上其他的应用中,可以发现大部分都是使用单个参数的,比如说id。这也很容易理解,因为onpassivate的方法的返回值只能有一个。
在tapestry5的官方文档中,只有一句非常简要的话介绍了如果传递多个文档的方法: the activation context may consist of a series of values, in which case the return value of the method should be an array or a list. (参见:http://tapestry.apache.org/tapestry5.1/guide/pagenav.html)。
但是这并不是说只要在onpassivate中把参数的值加入到list中,返回一个list,而在onactivate中接受一个list参数,然后就可以得到其中的参数了,因为tapestry5把参数传给onactivate的方法其实是通过将参数作为httprequest中的参数的。如果试图使用上述方法就是得到一个“无法将list转换成string的错误”
所以方法应该是这样的,在output中:
private list
public void setparamlist(list
this.paramlist = paramlist;
}
public list
return paramlist;
}
list
return paramlist;
}
void onactivate(string datefrom, string dateto) {
this.datefrom = datefrom;
this.dateto = dateto;
}
private string datefrom;
private string dateto;
在input页面中,需要把onformsubmit改一下:
object onformsubmit() {
list
output.setparamlist(list);
return output;
}
其中,需要注意的是output中的onactivate方法,基参数的顺序必须和list中放入的参数顺序一致。
这就是filter的代码,这个filter必须实现componentrequestfilter接口。值得注意的是其构造函数所需要用到的4个参数,这4个参数都是tapestry5本身自有的服务,所以我们什么也不用做,tapestry5自动会将服务的实例注入进来,这就是tapestry-ioc的威力。
componentrequestfilter接口一共有4个方法需要实现,具体代码如下:
在componentrequestfilter中,我们无法使用@sessionstate注解来直接注入session中的变量,但是我们可以通过applicationstatemanager来取得。
现在我们需要把刚定义的filter注册到系统中,很简单,只要在appmodule中添加以下函数就行了:
示例:
1. 在登录页面:
@sessionstate
private authentication auth;
......
// if user name and password is valid:
auth.setprivliegelist(.....);
2. 在需要权限控制的页面模板中:
administrator can see this block
这就是一个最简单的tapestry应用所需要配置的内容了。
a.context-param中的tapestry.app-package配置,这在第一部分说过:这是tapestry要求配置的java package的名称,tapestry相关内容都需要在这个package下面的pages, services, componets子package下。这里的配置是t5demo
b.tapestryfileter的配置。这个非常容易理解,几乎所有现在流行的web框架都需要一个类似的定义。
2、start.tml以及相应的java class,例子中就是t5demo.pages.start.java
start.java非常简单,只定义了一个get方法:
public class start
{
public date getcurrenttime()
{
return new date();
}
}
相应的页面start.tml
this is the start page for this application, a good place to start your modifications.
just to prove this is live:
the current time is: ${currenttime}.
[
首先要注意在html的tag中加入了tapestry的命名空间。
第二、${currenttime}就是tapestry的tag了,这里就会调用对应class的getcurrenttime方法在页面上显示对应的值。
第三、
3、需要的library:
commons-codec.jar
javassist.jar
log4j.jar
slf4j-api.jar
slf4j-log4j.jar
tapestry5-annotations-5.1.0.5.jar
tapestry-core-5.1.0.5.jar
tapestry-ioc-5.1.0.5.jar
4、再加上一个log4j.properties,这就是一个最简单的tapestry应用所需要的全部东西了。
怎么样,感觉还是挺简单的吧。
上述是原文的翻译。下面是一些评论:
howard(应该是tapestry的作者):taptestry5和struts相比,我认为差别应该是在反射的使用上(包括在java.bean.introspector中大量的synchronization)。因此在struts将查询参数的名称映射成javabean属性的时候,会比较耗时。而tapestry5是不使用反射的,tapestry在查询参数和javabean的属性之间使用一种“预编程”向量组件,也许这就是两者(tapestry和struts)的差别。当然,这只是猜想,如果要证实的话,是需要花费很多时间的。我认为ognl的教训不是说反射很慢,而是在于一个关键代码上的序列存取对于性能的影响是相当大的。
最后一个小提示:我觉得在tapestry5应用中如果把beanmodel从beanmodelsource中只提取一次,然后给grid,beaneditform等等提供一个可以存取的方法,将会获得相当的性能提升。这样就不是需要每次都重建beanmodel,将减少操作的消耗。
jeverest:我也进行了tapestry的性能测试,并且同意tapestry5的性能比较以前版本的要快。
这次的版本算得上是比较迅速了,从官方凯发k8网页登录主页中可以看到,第一版5.1.0.1是2月24日发布了,短短3个月不到的时间,发了4个版本,动作不可谓不迅速。
5.1中具有以下几个新特性
1、tapestry现在开始采用blackbird作为javascript的调试工具
2、一个ajax的事件请求现在可以返回一个multizoneupdate实例来更新浏览器中的多个区
3、客户端数字的检验实现了国际化
4、相对于5.0.18有显著的性能提升,主要是页面的加载时间和页面的渲染时间大大缩短
5、tapestry的ioc服务现在既可以是advised也可以是decorated
6、tapestry的服务现在可以注入到spring的bean中
7、对于支持gzip的客户端,tapestry现在可以压缩返回包
8、有序的和mapped的配置信息现在可以被重新赋值
9、属性表达式得到加强,现在可以调用有参数的方法,或者创建一个列表
10、ioc的贡献既可以是类(自动生成实例)也可以是具体的实例
11、现在提供了一个简单的可以重写内建服务的方法
这里面最让我感兴趣的还是性能的提升,不知道在展示大数据量的时候性能的提升到底有多少,有机会一定要测试一下。