Buffalo VS DWR

根据BJUG maillist讨论整理,原始帖子见这里

共性:

特性 Buffalo DWR
支持Spring集成 支持 支持
使用一个Servlet来接收所有的AJAX请求 ApplicationServlet DWRServlet
使用XMLHttpRequest + JavaScript 传输数据 buffalo.js dwr.js & util.js
在Java和Javascript之间转换数据 marshallingContext Converter
协议 1.2.x之前采用burlap, Buffalo解析大数据量可能会比较慢,然而可以适用于多种服务器端和客户端,并且burlap协议的完整性和支持的数据类型更加丰富。2.0开始采用自定义的基于xml的协议(来自burlap,做了更适合web的修改),并自行编写了解析器,性能更高 使用自定义的简单文本协议
生命周期对象访问 BuffaloContext.getContext() WebContextFactory.get()

Buffalo特性:

  1. 基于prototype,如果你的AJAX应用也是基于prototype,那么可以减少重复加载prototype的带宽,并且获得相当一致的编程概念
  2. Bind: 提供了对结果数据的处理,直接将数据绑定到页面对象并展示,这是一个动人的特性。(DWR在Util.js中也提供了一些方法来简化数据的展示,但不如Buffalo做的更多。) 在2.0中,Bind能力更加强大,能够将值直接绑定到表单元素、表格、DIV/Span、甚至整个表单上。关键是这种绑定是无侵入并且与buffalo整体结构完全整合,对外表现只有一个简单的{{buffalo.bindReply}}或者{{Buffalo.Bind.bind}}即可。http://buffalo.sourceforge.net/binding.html有一些描述。
  3. 序列化:Buffalo支持任意对象,任意深度,任意数据结构的java到javascript以及javascript到java的双向序列化。并且支持引用。这里有完整的协议说明。由于文档和演示不充分,很多人以为buffalo不支持任意对象了 ~
  4. 生命周期对象访问:1.2.4之前需要继承一个BuffaloService,[来源www.iocblog.net]
    从1.2.4开始就不需要继承了,引入了线程安全的BuffaloContext对象,只需要通过BuffaloContext.getContext()即可获得一个线程安全的引用,并且对Request的各种属性进行操作。更方便的是:
    Map BuffaloContext.getContext().getSession()
    Map BuffaloContext.getContext().getApplication()
    Map BuffaloContext.getContext().getCookie()

    即可获得session/application/cookie的Map,操作这些Map即可获得对这些生命周期的各种变量进行查询和更新。这个特性参考了webwork中ActionContext的设计

  5. 对Collection/Array的模糊处理:buffalo中提供了对Collection/Array对象的模糊识别能力。例如:服务器端有一个方法需要List参数,客户端传递过去一个javascript数组就可以了,不需要费心的组装对象。buffalo通过这些很细小的地方来提高程序员生产力。
  6. 客户端组装对象:buffalo支持在客户端组装对象,甚至可以直接将整个表单序列化为一个对象作为参数传给远程客户端。
  7. 对重载方法的处理能力:由于java与javascript之间类型的不匹配,DWR的代码生成无法对重载方法进行处理。例如,sum(double,double), sum(int, int) DWR很可能不知道你要调用哪一个。从2.0开始buffalo支持了对重载的处理。

DWR特性:

  1. 支持Batch,可以将多个Service函数调用放在一个XMLHttpRequest请求中完成。

    Michael Chen:我一直认为这不是一个好的实践。在客户端发起多个请求并获得响应除了获得编程的复杂外,还增加了服务器端设计service的自由度。这种方式感觉上更鼓励为远程调用设计细粒度的服务、将组装逻辑放在客户端。这种设计风格我不太喜欢,因此batch也一直没有考虑实现,虽然实现不太麻烦。

  2. Converter:可以转换任意类型的Java对象到JavaScript,并允许直接使用。例如:Customer类包含一个address变量, 当AjaxCall返回Customer对象的时候,可以直接在Javascript中使用customer.address来获得Address的信息。
  3. 允许Expose部分函数和属性。(Buffalo无限制,可以访问Service中的任意函数。)

    Michael Chen: 这个我也考虑过...DWR的代码生成机制使得它不得不通过这种方式减小些流量。Buffalo如果想实现这个特性也不是不行,只是我觉得,既然Service辛辛苦苦实现了,还需要通过这种方式来让别人不能用么?况且buffalo没有代码生成,无论你暴露多少方法流量都是一样的。考虑到实际情况,buffalo没有实现这个特性。

    jimguo: 想像这样的需求:对于一个AddressService,通过AJAX只能添加和更新,不允许删除。如果没有Expose限制的话,就只能写在两个Service中了,添加和更新的功能在一个Service里被Expose,而删除的功能在另一个Service里。或者再创建一个Facade类?

  4. DWR2.0中提出了Reverse Ajax,提供在Java代码中来处理页面上元素的功能。

    Michael Chen: 这个东东...也还是代码生成的trick...然而我的态度是javascript与java同样重要的,因此不会让代码生成类的东西破坏javascript的整体性。

Comments:
嗯,这个AddressService能说明一些问题。从方便使用的角度来说,这样做确实没错,但我觉得,一个真正的service应当具备完整的边界,这个边界是系统内部(领域模型)的一部分,这一部分不应当由外边的服务来限定如DWR或者其他之类。设计习惯的问题。

在计划中,我仍然不想在buffalo中实现这个。实际上,通过BuffaloConfigure bean, 你可以将proxy后的bean放进来;或者做一个regular expression的拦截器来拦截那些不想被使用的方法。[来源www.iocblog.net]

Posted by Michael Chen at Oct 24, 2006 18:29 | Permalink



文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。