2008年3月15日星期六

从JSP到Velocity

1.JSP有优点。
Rails页面脚本的做法跟JSP其实差不多,也是在HTML中通过<%...%>将Server端语言嵌入其中,这应该是最容易实现的方法。如果说比JSP有强出的地方,那就是Ruby的语法比Java简洁很多。
Grails:

Struts:

对于这种用XML格式来表达逻辑,同JSTL大同小异,个人感觉总是别扭。一则不如Server端语言灵活,二则要掌握另外一种语法。
相比velocity就做的很直观了:

#foreach ( $item in [1..5] )
On this iteration, refers to the value $item.
#end

其做法更多是贴近一般语言的习惯,仿佛只不过是在语句前加上#(velocity里面称为Directives),变量前加上$。
Grails里面变量的表示为"${}"。一些流行的Javascript框架如prototype、JQuery也采用这种写法。不过这种变量的表示在JSP 2.0里面也被引入,我们就再也不必看到难看如<%=name%>的写法了。

对于XML格式的标签写法,可能对于机器来说容易处理,其实在这里没有一般的语法的校验,有的只是XML的scheme的校验,当然这也是一种语法,不过就容易处理多了。
对于Velocity,其采用了Antlr来产生语法分析器,在其源代码包org\apache\velocity\runtime\parser 下可以看到详细的代码。

还有另外一种模板框架freemarker,跟velocity很类似。

如果我们采用更为简洁的做法:将逻辑和页面彻底的分离,如JSF或者Tapestry的做法,让页面更为单一和纯净。这可能是最理想的做法,也有更好的对页面组件的重用性。但是当前台页面异常复杂,需要浏览器端较多javascript操作,特别是AJAX的引入,势必有越来越多的页面逻辑转移到客户端,从而破坏了整个架构的一致性,让扩展更难处理。

这说明B/S架构中的逻辑存在于浏览器端和server段是导致系统复杂的根本原因。
C/S就没有这样的烦恼。
为什么呢?

对旧技术的补丁,最好的技术是GWT,其将逻辑集中于java代码中(虽然客户端的代码和server端的代码还是分开的)。
而新的技术,则是RIA。

2008年3月9日星期日

jQuery的做法

最近学习jQuery.
jQuery正如其名字一样,是一个用来方便的查找到HTML文档中的元素的javascript框架,其查找条件的语法借鉴了CSS和XPath中对DOM元素定位的方式,由于CSS的广泛流行,jQuery可以很快的上手。

jQuery对查询的结果统一返回为集合,而且可以对该集合再次查询,如:

$('div.disText').attr('title','点击来编辑数据').mousemove(handleMouseMove).mouseout(handleMouseOut).click(handleClick);

这是很直观的方式,让人奇怪:为什么很少在其他地方见到这样的简洁的模式呢?
(其实在JAVA中也有,比如:
StringBuffer buff = new StringBuffer(128);
buff.append(getModuleName("dojo"))
.append(".require('")
.append(getModuleName(name))
.append("');");

)

jQuery这种视一切为“集合”的方式对“批量”的处理DOM可谓得心应手,而在Web应用中,页面可以显示大量的信息,这些信息可以以常以相同的样式表现,比如“超链接”,在这里用jQuery就可以统一的这些元素处理。和传统的Fat Client不一样,这些页面以XML的格式来定义,还有比如XUL,也以XML来定义界面。XML是一种结构化的数据格式,所以就需要jQuery这样的框架。

后记:LINQ,.net下的一个框架,也有跟上面类似的语法:

var myList = [
{FirstName:"Chris",LastName:"Pearson"},
{FirstName:"Kate",LastName:"Johnson"},
{FirstName:"Josh",LastName:"Sutherland"},
{FirstName:"John",LastName:"Ronald"},
{FirstName:"Steve",LastName:"Pinkerton"}
];

var exampleArray = From(myList).
Where("item.FirstName == 'Chris'").
OrderBy("item.FirstName").
Select("item.FirstName");

2007年12月25日星期二

异步I/O实践:Linux & Java

Linux上面的称为AIO,可以参考这篇文章:

使用异步 I/O 大大提高应用程序的性能

编译时使用“gcc a.c -lrt"。这表示链接时包含库/usr/lib/librt.XX,这个库里面可能包含了aio的库,否则会出现"Undefined reference to aio_read"的错误。

2007年12月13日星期四

My linux enviroment setting

1. close noisy bell

setterm   -bfreq   0   -blength   0

2007年11月27日星期二

Rethink the big element in web page: Data Table

image

  Data Table is heavily used in information system. In most case, these tables just display a query result set. They are read only. The operations on them are: paging, sorting, single selection and multi-selection. The all elements of a table include: field, field title, sort and page number state, and value format(or convert). In some extend, a data table is not too much associated with other page elements. So it will be a better way to define a table in one place other than several places in application.

Commet, Grizzly and Tomcat 6

  一个比较早的对这方面讨论的帖子在这里: Comet,下一代Ajax? DW上面好几篇文章做了介绍:Comet:基于 HTTP 长连接的“服务器推”技术面向 Java 开发人员的 Ajax: 使用 Jetty 和 Direct Web Remoting 编写可扩展的 Comet 应用程序。在《Ajax Design Patterns》这本书上也有介绍,不过称为HTTP Streaming。Java EE 迎合 Web 2.0 采用事件驱动的异步架构应对现代 Web 应用程序带来的挑战这篇文章从理论的高度说明了异步模式对提高系统吞吐量的作用。
如果要实现Comet,Server端就需要NIO来解决HTTP长连接的问题,否则Server端支持的并发数就会大大减少。

  Servlet和NIO的使用可以参考Servlet API 和 NIO: 最终组合在一起 使用非阻塞 I/O 构建基于 Servlet 的 Web 服务器。虽然是一篇较早的文章,仍然提供了很多关于NIO的有用信息。

  Tomcat 6里面相关NIO的配置可以参考其文档,只用修改Connector的protocol即可。接下来可以写一个简单的Servlet A,其implements CometProcessor接口。为测试方便,将Sender存放在Application变量中,在另外一个Servlet B中就可以调用Sender的send(...)方法,当浏览器访问A时,可以动态看到Server端push过来的信息(这时浏览器会一直处于页面正在装载的状态,实际应用中可以用AJAX来接受信息)。

  由于是长连接,数据在传送过程中就存在缓冲的问题。一般的一个Server端的发送到客户端的消息(注意这里不是一个响应)不会很大,而默认的Tomcat缓冲配置偏大,导致客户端响应滞后,出现这种奇怪的现象:1)当send(...)方法触发多次后,server才会一次把消息全部push到客户端(即是每次使用了flush方法);2)1 发生后,每次的send(...)的调用会导致server段立即把这条消息发送到客户端(这是buffer又好像不存在一样)。

  对于Tomcat 6自带例子里面的bug,也有位哥们在他的blog中提到:Asynchronous IO is hard!



 

2007年11月25日星期日

Use JPA with Hibernate in Netbeans(Tomcat)

0. prerequisite
  Tomcat 6.0.14
  Netbeans 6 rc1
  Hibernate core 3.2.5GA
  Hibernate EntityManager 3.3.1GA


1. Add a new JPA library implement
  The default used TopLink. Change to Hibernate.
Untitled


2. Adjust in JSF design
The default data provider ObjectArrayDataProvider works not well with JSF design UI.

image

  My target is when let a jsf table "Bind to Data", the all fields of a Hibernate JOPO can be chosen as the  above dialog. These displayed fields come from provider's getFieldKeys method which is part of interface DataProvider signature. So the simplest way is to extends ObjectArrayDataProvider and overide that method. Or just use setObjectType(Student.class). Be sure to compile that class manually so the JSF Design can take this change into account.

Why not use :

private ObjectArrayDataProvider objectArrayDataProvider1 = new ObjectArrayDataProvider(someType);

It does not work. Even I put them in _init() method of backend bean, as the CachedRowSet provider does.

3. Done.