他们说:“Web改变世界,我们改变Web”,你知道是谁改变了谁吗?
他们说:“From the earth to the moon, and ready for Mars!”,你ready for what呢?
他们勇敢,他们开放,他们懂得分享,所以他们选择开源,并且可以自豪地宣布,他们活在“勇敢者的新世界”里。而同样作为程序员的你,你的世界又是什么样的呢?
这里的“他们”,我想我不提大家已经知道是谁,就是来自中国的开源项目operamasks。他们虽然没有创造世界神话(不知道第四个通过JavaEE5认证的服务器算不算),但他们确实创造了中国神话,如果你不服,那么你能举出一个在他们领域里面比他们成功的同类产品吗?
成功者都常说,“细节决定成败”,只有为用户考虑到各种细节,用户才会支持你。Operamasks的成功,我觉得除了他们的“勇敢”以外,还有一个重要因素是“细节”,他们考虑到了很多细节,很多都是在JSF这样一个“标准”层面的东西无法强制规定死,但往往对用户来说又是非常实用的细节,还有解决了很多常遇到的繁琐细节。
道理及感叹在这里就不想多发了,我想大家都关注的是具体的技术,所以本文就简单例举一下operamasks中的一些比较具有人性及亲和力的细节,看了后我想使用JSF开发的你一定很觉得非常体贴。
1、 Kill掉JSF中令人讨厌的配置
一个简单类似的注册示例,成功就导航到/accepted.jsp去,而拒绝就导航到/accepted.jsp。
ManagedBean中
public String signup() {
if (Math.random() < 0.2) {
return "accepted";
} else {
return "rejected";
}
}
让标准JSF来干吧,只是为了一个简单的跳转,你就需要配置下面这样一堆html,你估算一个项目下来的配置文件代码是多少。
<faces-config>
<navigation-rule>
<from-view-id>/signup.jsp</from-view-id>
<navigation-case>
<from-outcome>accepted</from-outcome>
<to-view-id>/WEB-INF/results/accepted.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>rejected</from-outcome>
<to-view-id>/WEB-INF/results/rejected.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
而用operamasks,你的代码只需要写成下面这样即可:
public String signup() {
if (Math.random() < 0.2) {
return "/WEB-INF/results/rejected.jsp ";
} else {
return "/WEB-INF/results/accepted.jsp ";
}
}
也就是说operamasks帮你吞掉了这些无味又没有太多营养的配置文件,并帮你消化,你说他是不是很人性。
另外,比如我们想要用到一个ManagedBean,标准JSF需要在配置文件中写一堆的配置文件,如下:
<faces-config>
<managed-bean>
<managed-bean-name>myBean</managed-bean-name>
<managed-bean-class>
package.MyBean
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
而operamasks设计了一套注解annotation标签,你只需要在类的声明前加上一个@ManagedBean标签即可,如下:
@ManagedBean(name="myBean", scope=ManagedBeanScope.REQUEST)
public class MyBean {
}
类似这样的细节还有很多,让我们慢慢去发掘吧。
2、用Ajax是那样方便
不管你信不信,事实摆在那里他真的很方便,Ajax的无刷新的效果对于Web应用来说确实很酷也很铉。对于传统的JSF实现,要想用Ajax你就要借助其它的一些Ajax框架,名字大一点算是ajax4jsf吧。下面看一个动态刷新页面中id为msg处的内容的示例:
首先要定义一个JSF标签
<h:outputText id="msg" value="#{bean.text}" />
然后定义一个ajax2jsf的按钮标签:
<a4j:commandButton reRender="msg" value="Submit"/>
而operamasks中的按钮标签仍然是:
<h:commandButton value="Server Submit" />
不懂JSF的同仁一定都觉得怪,得懂行的就知道。这个<h:commandButton value="Server Submit" />可是在JSF的JCP中规定的标签标准啊,这个是任何支持JSF的开发工具都能认识的,当然程序员就不用说了。而那个什么<a4j:commandButton>是什么,那个reRender属性,更是怪怪的,鬼二哥Studio才会认他。
3、Rich Components的集成
看过Operamasks有名的jsfdemo示例吧,我们来看看反应。一些菜鸟感叹说:“发漂亮啊,太伟大了!”;一些小牛们会眼红红地生闷气,怎么我才想到的你就做出来了;一些大牛们会说:“这不是偷人家ext的吗?”,幽默一点会说:“我认为是是进到了extjs.com”;还有一些很有尊严并非常爱国的人会说:“真丢无耻,真丢中国人的脸,把别人的东西改改就说成自己的了,真贱……*&^&^%%^&8…”。
上面的种种反应应该归纳为中国开源的特色悲喜剧。这里我想说的是,如果你真正花一点时间去了解一下Operamasks、了解一下Ext、了解一下Rich Components,那么所有你就不会成为上面悲喜剧中主角。
我们知道Java跟Web式的Rich Components也无法,跟Ajax也无关。Ext专用于Web式的Rich Components,但对于企业级的应用来说,他是解决了很小的一部分问题,而且单独使用Ext要写很多很多的跟很酷的Ajax效果一样很酷又很让人头晕的Javascript。那么该如何解决这问题呢?很明显,只有大家合作。Operamasks也就通过集成同样是开源的Ext项目来实现了丰富的Rich Components,你可以像开发Delphi或VB那样,直接往界面上拖出一棵非常实用的树出来。Rich Components的集成中有很多细节及技巧,本文就不例出。
其实细节还存在很多地方,比如多国语言中的小标签,注入Spring中的Bean,由于研究Operamask的时间比较短,而且资料也比较少(哪位朋友如果有好的资料或示例方便的话请发一些给我学习),所以暂时就写这些,以后会逐渐以大家分享。
后记:
虽然才开始投身开源的世界,但发现这个纯技术的世界并不是想象中的那么单纯。我上一篇写过
《中国java开源界最可爱的人们》一文,从一些同仁们的回复看出大家对中国的开源(包括项目、环境、产品、人品)仍然很悲观,甚至还存在一些心理阴暗的人,篇造出什么“软件界的洪志 lee”之类的大词,也许就恐天下不乱吧。