由于WebWork本身提供了一套自定义的标签库,而且该标签库支持OGNL,因而在做注册登陆功能的时候,也将其标签库体验了一把。
以前在使用WAF做Web应用程序的时候,会在HtmlAction中的doEnd方法将所要显示的内容使用SetAttribute方法存入request中,再dispatch(分发)到不同的页面,页面上或者通过getAttribute方法或者使用<c:out>标签显示之。而在WebWork中,由于使用了ValueStack,我们在定义Action的时候,不需要象HtmlAction那样了。而Action本身几乎就是一个普通的JavaBean,而其中的属性值都会存放在ValueStack中,那么setAttribute方法就不再需要了,在JSP页面上,我们使用<webwork:property>标签即可获得相应的属性值。
除了property标签之外,if标签也进入了我的使用范围。因为在实现登陆功能的时候,通常都会在登陆成功以后,将原来的输入框隐藏以来,那么就要使用<webwork:if>去实现这样的显示逻辑了。但是我在使用if标签的时候,面临的第一个问题就是如何获得存放在ValueStack的属性值呢?查阅了一下资料,资料中给出的例子是这样的:
< font color ="blue" >
< webwork:property value ="greeting" />
</ font >
</ webwork:if >
< webwork:else >
< font color ="pink" >
< webwork:property value ="greeting" />
</ font >
</ webwork:else >
而我依葫芦画瓢,写下了:
</ webwork >
运行的结果并不如我预计的那样,输入框还是显示出来了。当我百思不得其解的时候,我选择了去看源代码。
从IfTag类中doStart到WebWorkTagSupport类中的findValue,再到CompatUtil中的compat,终于找到了错误的根源。在compat方法有这样的代码:
原来是通过" ' "作为token将传入的字符串区划分开的,然后再根据得到的字符串到ValueStack中去找相应的值。很明显,test这样写是错误的,因为test的值会根据Token划分为loginId!=和两个单引号,那么loginId!= 在ValueStack根本就是不存在的。但是当我写成
</webwork>
仍然是不行的。
到了最后,我只能在Action类中定义了一个新的变量:hasLogined,并在登陆成功之后,将其设为true,然后在JSP页面上,[1]
</ webwork >
这样就能实现前面所说的功能了。
由以上可以发现,在使用WebWork自定义的if标签的时候,要比JSTL中的if标签麻烦,而且,我现在还不知道该如何在test表达式中表示一个空字符串,但是在JSTL中,我经常都会这样用:
</ c:if >
我想WebWork的标签库的实现很大一部分上都需要对ValueStack进行存取的操作,而存放在ValueStack中的一般都是Map,因此,在标签当中处处都有键值对(key-value pair),那么就只能通过Token去区分一个String里面包含的key值了。
PS:在经过了第二天的小小研究之后,我发现以上的说一些地方是错误的,[1]处的改进也是行不通的,我不知道为什么当时会得到正确的结果,而且这个正确的结果后来再也没有办法重现了,我想是因为自己更新了JSP,却忘了在浏览器上刷新了吧。具体的分析请看WebWork深度探索之标签库(续)。这篇Blog原本想删掉的,最后还是保留了下来,我想我不怕丢脸,就当作一面镜子来照照自己,并提醒自己保持严谨的态度吧。