posts - 5, comments - 16, trackbacks - 0, articles - 0

2006年9月5日

收藏一篇DLEE老大的文章,里面的话句句说到了我的心坎里。

为什么我说Struts/WebWork会受到Ajax的威胁呢?有的人可能觉得大家相安无事不是很好,你是不是有神经病故意挑起人民内部矛盾?问题是他们之间确实存在着一些深层的内在矛盾和冲突,这些矛盾才是目前Struts和 WebWork都只能在非常有限的程度上支持Ajax的原因。所以,问题是架构性的,并不是小型的修补或者更好的编程技巧可以彻底解决的。

传统的服务器端MVC架构设计(也就是Model2),存在着一个基本的假设就是Web应用的工作流是由一系列的页面切换构成的。这种架构中的一个View,从语义上来讲只能代表一个完整的HTML页面。整个Web应用的表现层,被划分成为非常多的页面的组合。

而Ajax开发者眼里,Web应用的工作流并不是这样构成的。Ajax开发者看待Web应用的角度与传统开发者相比差别非常大。在一个Ajax应用中,只有相对很少的页面。每个页面,包括页面引用CSS样式、JS脚本,都是一个更小型的Ajax应用。甚至一些功能简单的Ajax应用,本身仅仅由一个单一的页面构成。例如一个简单的RSS阅读器,还有IBM笔记本上那个获得天气预报的桌面。
按照Ajax in Action,Ajax应用可以分成3种类型:

  1. 以内容为中心的应用,服务器返回的是一段HTML内容。
  2. 以脚本为中心的应用,服务器返回的是一段JS脚本。
  3. 以数据为中心的应用,服务器返回的是一段数据,可以是XML格式、JSON格式或者其他文本格式。
服务器返回给Ajax应用的3种类型的网络流量(不称为数据是与上面第3种Ajax应用相区别),任何一种都不能被简单地视作传统MVC架构中的View,因为他们各自所代表的语义与传统MVC架构中的View的语义是完全不同的。所以可以看出,除了初次交付给浏览器一个完整的Ajax应用之外,传统的MVC架构对于Ajax应用的支持是非常有限的。其实为了给客户端提供上面3类网络流量,一个Servlet已经足够了。DWR、JSON-RPC、Buffalo在服务器端也就是由Servlet实现的,不要求服务器端一定要安装某种MVC框架。
上面3类应用,前面的两类,客户端JS代码比较简单,表现逻辑仅有一部分位于客户端,大部分仍然位于服务器端,因此传统的服务器端MVC架构仍然是非常有价值的。但是大家注意第3类Ajax应用,实际上它已经将绝大部分甚至可以将全部的表现逻辑都转移到客户端来执行,这个时候服务器端传统的Web表现层实际上被架空了(皮之不存,毛将焉附?)。而对于Ajax应用来说,虽然近期可能还是以第1类Ajax应用为主(例如,所谓的AHAH技术),但是最有生命力和发展前景的还是第3类Ajax应用。

自从1999年M$推出IE5.0支持XMLHTTP,可以不刷新页面以异步方式从服务器获取数据之后,Web开发的领域就埋下了一颗定时炸弹(6年以后,一个新词Ajax的出现引爆了这颗炸弹)。Model2最初的设计应该发生在这件大事(现在应该承认,M$做了一件天大的好事)发生之前,其设计师不可能想到异步请求的价值。按照Model2的设计思想直接产生了Struts。但是后来的WebWork在最初设计阶段仍然与这个技术失之交臂,这是相当可惜的一件事情。WebWork其实最初设计的时候就可以走的更远,但是他们只想超越Struts,做一个更好的Model2 MVC开发框架。现在他们再想赶上这班列车已经有点晚了。如果基础的服务器端MVC架构的价值是可疑的,那么其他围绕这个架构所开发的基础架构的价值也同样是可疑的。

所以在现在这个时刻,重新正本清源地思考Model2最初的设计,它带来的Web开发的巨大进步,以及它所存在的不足,是一个非常现实的问题。

posted @ 2006-09-08 22:16 BennyBao 阅读(261) | 评论 (0)编辑 收藏

     摘要: 在网上看到了有些同志提到了为Ajax的XMLHttpRequest提供一个对象池,也读了他们给出的实现代码。感觉不是特别理想,于是模仿apache的commons中的ObjectPool的思路写了一个简单的JavaScript版。望指教: function ...  阅读全文

posted @ 2006-09-08 17:47 BennyBao 阅读(2436) | 评论 (3)编辑 收藏

在JavaScript可以使用try...catch来进行异常处理。例如:
try   {
    foo.bar();
}
  catch  (e) 
{
    alert(e.name 
+   " "   +
 e.message);
}

目前我们可能得到的系统异常主要包含以下6种:
  • EvalError: raised when an error occurs executing code in eval()
  • RangeError: raised when a numeric variable or parameter is outside of its valid range
  • ReferenceError: raised when de-referencing an invalid reference
  • SyntaxError: raised when a syntax error occurs while parsing code in eval()
  • TypeError: raised when a variable or parameter is not a valid type
  • URIError: raised when encodeURI() or decodeURI() are passed invalid parameters

上面的六种异常对象都继承自Error对象。他们都支持以下两种构造方法:

new  Error();
new  Error( " 异常信息 " );

手工抛出异常的方法如下:

try   {
    
throw   new  Error( " Whoops! "
);
}
  catch  (e)  {
    alert(e.name 
+   " "   +
 e.message);
}

如要判断异常信息的类型,可在catch中进行判断:

try   {
    foo.bar();
}
  catch  (e) 
{
    
if  (e  instanceof  EvalError) 
{
        alert(e.name 
+   " "   +
 e.message);
    }
  else   if  (e  instanceof  RangeError)  {
        alert(e.name 
+   " "   +
 e.message);
    }

    
//   etc
}

Error具有下面一些主要属性:

  • description: 错误描述 (仅IE可用).
  • fileName: 出错的文件名 (仅Mozilla可用).
  • lineNumber: 出错的行数 (仅Mozilla可用).
  • message: 错误信息 (在IE下同description)
  • name: 错误类型.
  • number: 错误代码 (仅IE可用).
  • stack: 像Java中的Stack Trace一样的错误堆栈信息 (仅Mozilla可用).
因此为了更好的了解错误信息我们可以将catch部分改为如下形式:

try   {
    foo.bar();
}
  catch  (e) 
{
    
if  (browserType  !=  BROWSER_IE) 
{                            
        alert(
            
" name:  "   +  e.name  +

            
" \nmessage:  "   +  e.message  +
            
" \nlineNumber:  "   +  e.lineNumber  +
            
" \nfileName:  "   +  e.fileName  +
            
" \nstack:  "   +  e.stack);        
    }

    
else   {                    
        alert(
            
" name:  "   +  e.name  +
    
            
" \nerrorNumber:  "   +  (e.number  &   0xFFFF +

            
" \nmessage:  "   +  e.message " );        
    }

}

JavaScript中的throw命令事实上可以抛出任何对象,并且我们可以在catch接受到此对象。例如:

try   {
    
throw   new  Date();     //  抛出当前时间对象

}
  catch  (e)  {
    alert(e.toLocaleString());    
//  使用本地格式显示当前时间

}

posted @ 2006-09-05 17:56 BennyBao 阅读(1972) | 评论 (1)编辑 收藏