<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>On The Road</title>
    <description></description>
    <link>http://zerozone.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>译稿通过复审</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/218556" style="color:red;">http://zerozone.javaeye.com/blog/218556</a>&nbsp;
          发表时间: 2008年07月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          刚得到消息，译稿顺利通过复审，编辑和质量优。2个月内出版。一年多的努力没有白费。<br /><br />感谢本书统稿人hax,编辑杨福川。辛苦了。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/218556#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 23 Jul 2008 14:01:43 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/218556</link>
        <guid>http://zerozone.javaeye.com/blog/218556</guid>
      </item>
      <item>
        <title>基于MVC的Flex framework比较</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/215060" style="color:red;">http://zerozone.javaeye.com/blog/215060</a>&nbsp;
          发表时间: 2008年07月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          原文出处：http://blogs.warwick.ac.uk/stevencarpenter/entry/flex_mvc_frameworks/<br /><br />当我打算选用一种MVC framework开发Flex应用时，我想我得看看目前有哪些框架可供选择。Rob已经使用Cairngorm做了一些实际项目，Cairngorm是Adobe推荐的解决方案，但还存在着一些别的框架，包括PureMVC，Model-Glue和Guasax，再加上一些我以前闻所未闻的或不成熟或成熟的框架。<br /><br />Pattern Park公司的一些研究人员最近对已存在框架做了一个比较。他们使用三大标准：Approachability（可实现性，创建一个工程并让它跑起来的过程是否简单，以及文档的丰富程度和支持力度），Scalability（扩展性，添加新特性是否困难，代码是否可测试） 和Flexibility （灵活性，代码是否开源，可修改以及是否环境独立等）对每个框架的质量进行评分。<br /><br />这个演讲值得一看，他们给出的结论是，PureMVC在全部三项指标中得到最高，Cairngorm紧随其后。不过正如某人在演讲上指出的那样，要使用这些框架，了解Cairngorm是一个先决条件，因为很多已存在的项目使用了较早出现的框架。Luke Bayes对演讲做了进入探讨，详细介绍了这些要点。<br /><br />下面是他们将PureMVC排在首位的原因：<br /><br />* 组合优于继承（Composition over inheritence）<br />* 无约束的接口（Liberal use of Interfaces）<br />* 有点拐弯抹角但还不至于迷失方向（Indirection is used but not overwhelming）<br />* 在应用代码中实例成员隐藏了单例引用（？不清楚确切含义）（Instance members hide singleton references from application code）<br />* MXML文件非常简洁（MXML views can be extremely thin）<br />* 吸取了Cairngorm的优点，但也包含一些缺点（Benefits of Cairngorm, with few of the disadvantages）<br /><br />这个演讲对任何考虑使用设计模式/框架进行Flex开发的人都非常有用，我打算本周开始研究PureMVC，看看它到底如何...
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/215060#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 15 Jul 2008 17:19:19 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/215060</link>
        <guid>http://zerozone.javaeye.com/blog/215060</guid>
      </item>
      <item>
        <title>在Flex中实现自定义的Caret</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/207211" style="color:red;">http://zerozone.javaeye.com/blog/207211</a>&nbsp;
          发表时间: 2008年06月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Flex中只有TextField组件实现了Caret，即插入位置的显示功能。最近研究Editor，自己实现了一个Caret类。<br /><br />难点：如何按固有频率切换状态（显示--擦除）<br /><br />大家知道Flex中，用Timer触发定期事件不准确，因此使用Timer处理Caret状态，自然也有类似问题。经试验确实存在此问题，需另寻途径。<br /><br />还要回到Timer定时器上，如果我们定义一个间隔非常短的定时器，对系统时间进行轮询，有了系统时间，而且在极短的时间内如毫秒级，几乎可以认为是连续的“Thread”了。只要能记住第一次显示Caret的时间，就可以在擦除时刻或下一个显示时刻进行相应的操作。<br /><br />最终效果不错。<br /><br />代码如下：<br /><br /><pre name="code" class="java">
package 
{
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import mx.core.UIComponent;
	
	public class Caret extends UIComponent
	{
		private static var DELAY:uint  = 700; //mileseconds  
		private static var PERIOD:uint  = 1000; //mileseconds
		private static var DELTA:uint = 20;
		private var startTime:Date;
		
		private var started:Boolean = false;		
		
		private var checkTimer:Timer = new Timer(1);
		override public function Caret()
		{
			super();
			createCaret();			
		}
		
		private function createCaret():void{
			draw();
			checkTimer.addEventListener(TimerEvent.TIMER,checkTimer_handler);		
			checkTimer.start();				
		}
			
		
		private function checkTimer_handler(event:TimerEvent):void{
			var date:Date = new Date();
			var elapsed:Number = (date.time-startTime.time)%PERIOD;
			trace(elapsed);
			if(elapsed>=(DELAY-DELTA) && elapsed&lt;=DELAY){
				this.graphics.clear();
				trace("clear");
			}
			else if(elapsed>(PERIOD-DELTA) && elapsed&lt;=PERIOD){
				draw();
			}
		}
		
		public function draw():void{		
			if(!started){
				this.startTime = new Date();
				started = true;
			}
			this.graphics.drawRect(10,30,2,20);			
			this.graphics.beginFill(0x000000);
			trace("draw");	
		}		
	}
}
</pre><br /><br />今天的研究结果表明，上述连续的Thread根本不可能保证，视代码而定。这部分内容属于高级内容。如有兴趣，请见http://www.bit-101.com/blog/?p=910。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/207211#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 23 Jun 2008 20:01:11 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/207211</link>
        <guid>http://zerozone.javaeye.com/blog/207211</guid>
      </item>
      <item>
        <title>20分钟创建基于Flex的Text Editor</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/204656" style="color:red;">http://zerozone.javaeye.com/blog/204656</a>&nbsp;
          发表时间: 2008年06月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          选择开源文本编辑器如TinyMCE、FCKeditor，当然是不错的选择，但定制自己的Text Editor也不困难。最近使用Flex开发Editor，研究了一下Flex自带的RichTextEditor，发现其工作原理非常简单。为了研究其工作原理及不足，我使用两个核心类自定义了一个Editor，效果图见附件。欢迎拍砖。<br /><br /><br />目标：用Flex定制自己的Text Editor<br />功能：字体，大小，粗体，斜体，下划线，列表（Bullet），对齐方式（Alignment），字体颜色。<br />开发环境：Flex Builder 3<br /><br /><strong>简介</strong>：<br /><br />    熟悉《设计模式》一书的开发人员都知道，此书从文档编辑器（document editor）展开讨论，引出数十种设计模式。本文对此不作讨论，我们所关注的是如何实现文档编辑器本身。更深入更复杂的例子，可以参考Jexi(参考价值更大，但没有实现Table)，TinyMCE。<br />     <br /><br /><strong>相关内容</strong>：<br /><br />    <strong>核心类--TextField和TextFormat</strong><br /><br />    TextField和TextFormat是实现文本编辑器的核心部件。TextField包含了文本的输入、显示和格式化功能，还有光标、选中(selection)处理。TextField是DisplayObject，可以作为子元素添加到Container上。TextFormat是Util类，负责表示用户设置的格式（Style）。<br /><br />    <strong>事件处理</strong><br /><br />    用户交互，少不了事件处理。TextEvent类专门用于处理和Text相关的事件，例如用户键盘输入或点击一个超链接(Link)。除了TextEvent，还需要处理一些自定义的事件，例如文本区域的内容、格式改变。<br />   <br /><strong>如何创建</strong>：<br /><br /> <strong>1.新建Flex Application，工程命名为test</strong>。<br /> <strong> 2.新建MXML Component，基类是Panel类</strong>。<br />      <br />      声明Event<br />      <pre name="code" class="java">
      &lt;mx:Metadata>
	       [Event(name="change", type="flash.events.Event")]
	       [DefaultTriggerEvent("change")]
      &lt;/mx:Metadata></pre><br />     <br />      声明变量。<br />      <pre name="code" class="java">
      private var previousTextFormat:TextFormat = null;</pre><br /><br />      重载createChildren()方法（初始化）<br />       <pre name="code" class="java">
       ////////////////////////////////
       //overridden 
       ////////////////////////////////
       override protected function createChildren():void{
	         super.createChildren();
	         createTextField(-1);					
       }			
       </pre><br />      <br />      创建TextField控件本身，添加事件处理器。<br />      <pre name="code" class="java">
      private function createTextField(childIndex:int):void{
          if(textField)return;
	      
	  textField = IUITextField(createInFontContext(UITextField));
	  //textField.
	  textField.autoSize = TextFieldAutoSize.NONE;
	  textField.enabled = enabled;
	  textField.ignorePadding = true;
	  textField.multiline = true;
	  textField.selectable = true;
	  textField.styleName = this;
	  textField.tabEnabled = true;
	  textField.type = TextFieldType.INPUT;
	  textField.useRichTextClipboard = true;
	  textField.wordWrap = true;
	
	  textField.addEventListener(Event.CHANGE, textField_changeHandler);
	  textField.addEventListener(Event.SCROLL, textField_scrollHandler);
	  textField.addEventListener(TextEvent.TEXT_INPUT,
	                                       textField_textInputHandler);
	                                     
	            
	  if (childIndex == -1){
	       addChild(DisplayObject(textField));
	       //updateDisplayList();
	  }                
            
	}</pre><br /><br />        应用文本格式<br />        <pre name="code" class="java">public function setTextStyles(type:String, value:Object = null):void{
				var tf:TextFormat;

				var beginIndex:int = textField.selectionBeginIndex;
				var endIndex:int = textField.selectionEndIndex;
		
				if (beginIndex == endIndex)
				{
					tf = previousTextFormat;
				}
				else	
					tf = new TextFormat();
				
				if (type == "bold" || type == "italic" || type == "underline")
				{
					tf[type] = value;
				}
				else if (type == "align" || type == "bullet")
				{
					if (beginIndex == endIndex)
					{
						tf = new TextFormat();
					}
		
					// Apply the paragraph styles to the whole paragraph instead of just 
					// the selected text
					beginIndex = textField.getFirstCharInParagraph(beginIndex) - 1;
					beginIndex = Math.max(0, beginIndex);
					endIndex = textField.getFirstCharInParagraph(endIndex) +
						textField.getParagraphLength(endIndex) - 1;
					tf[type] = value;
					if(!previousTextFormat) 
						previousTextFormat = new TextFormat();
					previousTextFormat[type] = value;
					if (!endIndex)
						textField.defaultTextFormat = tf;
				}
				else if (type == "font")
				{
					tf[type] = fontFamilyCombo.text;
				}
				else if (type == "size")
				{
					var fontSize:uint = uint(fontSizeCombo.text);
					if (fontSize > 0)
						tf[type] = fontSize;
				}
				else if (type == "color")
				{
					tf[type] = uint(colorPicker.selectedColor);
				}
						
				if (beginIndex == endIndex)
				{
					previousTextFormat = tf;
				}
				else
				{
					textField.setTextFormat(tf,beginIndex,endIndex);
				}
		
				dispatchEvent(new Event("change"));
				
				var caretIndex:int = textField.caretIndex;
				var lineIndex:int =	textField.getLineIndexOfChar(caretIndex);
		
				textField.invalidateDisplayList();			
		
				callLater(textField.setFocus);
			}</pre><br /><br />        添加ControlBar，编辑工具条<br />        <pre name="code" class="java">			&lt;mx:ControlBar width="100%" > 
				&lt;mx:ToolBar id="toolbar" width="100%" horizontalGap="7">			
					&lt;mx:ComboBox id="fontFamilyCombo" editable="true"
						creationComplete=""
						dataProvider = "{fontFamilyArray}"
						close="setTextStyles('font');"
						enter="setTextStyles('font');"/>		
					&lt;mx:ComboBox id="fontSizeCombo" editable="true"
						paddingLeft="2" paddingRight="2"
						dataProvider = "{fontSizeArray}"
						close="setTextStyles('size');"
						enter="setTextStyles('size');"/>							 
					&lt;mx:HBox id="toolBar2" horizontalGap="0">		
						&lt;mx:Button id="boldButton" width="20" toggle="true"							
								   icon="@Embed('icon_style_bold.png')"
								   click="setTextStyles('bold', event.currentTarget.selected);" /> 						
						&lt;mx:Button id="italicButton" width="20" toggle="true"
								   icon="@Embed('icon_style_italic.png')"
								   click="setTextStyles('italic', event.currentTarget.selected);" /> 						
						&lt;mx:Button id="underlineButton" width="20" toggle="true"
								   icon="@Embed('icon_style_underline.png')"
								   click="setTextStyles('underline', event.currentTarget.selected);" />		
					&lt;/mx:HBox>				
					&lt;mx:ColorPicker id="colorPicker" width="22" height="22"
								close="setTextStyles('color');"/>		
					&lt;mx:VRule height="{alignButtons.height}"/>		
					&lt;mx:ToggleButtonBar id="alignButtons" buttonWidth="20"
									itemClick="setTextStyles('align', ToggleButtonBar(event.currentTarget).dataProvider.getItemAt(ToggleButtonBar(event.currentTarget).selectedIndex).action); " >
						&lt;mx:dataProvider>
							&lt;mx:Array> 
								&lt;mx:Object icon="@Embed('icon_align_left.png')" action="left"/>
								&lt;mx:Object icon="@Embed('icon_align_center.png')" action="center"/>
								&lt;mx:Object icon="@Embed('icon_align_right.png')" action="right"/>
								&lt;mx:Object icon="@Embed('icon_align_justify.png')" action="justify"/>
							&lt;/mx:Array>
						&lt;/mx:dataProvider>
					&lt;/mx:ToggleButtonBar>
					&lt;mx:Button id="bulletButton" width="20" toggle="true"
						   icon="@Embed('icon_bullet.png')"
						   click="setTextStyles('bullet', event.currentTarget.selected);" />					 				
				&lt;/mx:ToolBar>
			&lt;/mx:ControlBar> </pre><br /><br />  3.在test.xml引用该组件<br /><br />      <pre name="code" class="java">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:NewEditor="*">
	&lt;mx:Style>
		Panel {
           borderAlpha: 1;
           borderThicknessLeft: 0;
           borderThicknessTop: 0;
           borderThicknessBottom: 0;
           borderThicknessRight: 0;
           roundedBottomCorners: true;
           headerHeight: 23;
           highlightAlphas: 0, 0.12;
           headerColors: #4e84df, #0f6cc3;
           footerColors: #efaa15, #e6780c;
           titleStyleName: "mypanelTitle";
        }
        .mypanelTitle {
           color: #ffffff;
           fontSize: 12;
           fontWeight:bold;
        }
        ControlBar {
            paddingTop:2px;
            paddingBottom:2px;
            height:15px;
        }
	&lt;/mx:Style>
	&lt;NewEditor:NewEditor title="Text Editor" height="50%" />		
&lt;/mx:Application>
</pre><br />      <br />       注意，我们为Panel和ControlBar添加了样式（Style）。<br /><br /><strong>问题和不足</strong>：<br /><br />    上述自定义Editor基于RichTextEditor（基于TextArea），有兴趣的读者可以研究它们。本文探讨如何实现简易的文本Editor。真正的Editor，包含很多类型的图元编辑，例如文本、图像、表格。由于TextField和TextFormat仅限于文本功能，因此要实现图像和表格编辑，还有很多的工作要做，甚至要抛弃TextField和TextFormat，设计一套基于Glygh的图元渲染系统。限于篇幅，不再进一步讨论。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/204656#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 17 Jun 2008 13:03:33 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/204656</link>
        <guid>http://zerozone.javaeye.com/blog/204656</guid>
      </item>
      <item>
        <title>Ext改变license争论之我见</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/196236" style="color:red;">http://zerozone.javaeye.com/blog/196236</a>&nbsp;
          发表时间: 2008年05月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          首先，本人对开源软件相关协议如LGPL和GPL概念模糊。因此本文观点仅供参考，欢迎讨论。<br /><br />切入正题，Ext作者改变协议引发的讨论很多，JavaEye上的帖子也不少。尤其是Charton和hax的争论引人关注。对Jack改变协议是否是背信的争论停留在道德层面，但驱使人们做出决定的理由不外乎金钱、名声。因此，我打算从已公开的资料如Blog来搜集“Jack受到人身攻击”的八卦。<br /><br />先介绍出场人物及背景：<br />1）Jack Slocum，ExtJs作者，事件的“受害者”<br />2）Sanjiv Jivan，GWT-Ext作者，Jack的主要攻击者。<br /><br />事件导火索是Sanjiv在博客发表一篇文章，声明GWT-Ext不打算改变到LGPL，并称Jack对金钱贪婪不顾道德和破坏开源社区诚信。我对Sanjiv为何如此大动肝火感到不解，他的观点虽然有道理但不足以证明GWT-Ext不能采用GPL。Jack原本想拉他入伙，但他拒绝，本来是可以双赢的合作他找理由推脱了。后来Jack和MyGWT合作推出Ext GWT，使得GWT-Ext的地位受到影响。Jack做事方式可能有问题，他曾发信“劝说”Sanjiv转向LGPL。<br /><br />尽管他们开始也互相吹捧和支持，但随着Jack的一些发展策略，两人之间的不信任和猜疑也越来越多，Ext GWT的出现直接导致Sanjiv的GWT-Ext受到排挤，最终爆发了二人之间的舌战。<br /><br />回到争论的焦点，转向GPL是对OSS的破坏吗，Jack对金钱很贪婪吗？我想Jack有权利从ExtJs项目获得收入，关键是方式。中途改变协议，客观上有迫使已有商业用户放弃或购买商业版的效果，而且这种协议的不持续性破坏了OSS社区的诚信。仅以道德层面指责Jack是站不住脚的，所以Sanjiv选择了这种方式抗议。<br /><br />不过事件背后的真正原因，还是利益分歧以及个人志趣、发展规划相左。即使没有Sanjiv，也有其他人站出来反对。<br /><br />一句话，Sanjiv不愿意生活在Jack的光环下，而更希望在开源社区建立自己的名声、尊重。Jack这个人比较强势、善于把握商业机会并获取最大利益。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/196236#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 23 May 2008 18:59:41 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/196236</link>
        <guid>http://zerozone.javaeye.com/blog/196236</guid>
      </item>
      <item>
        <title>在HostMonster上部署rails应用</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/196161" style="color:red;">http://zerozone.javaeye.com/blog/196161</a>&nbsp;
          发表时间: 2008年05月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          因为个人需要做一个网站，买了HostMonster的空间。如何部署Rails，花了不少时间，主要是没有经验导致。HostMonster服务不错，只是Online Chat服务人员多数不是Rails专家，只能解决基本问题。<br /><br />如何把应用部署到域名下，例如http://mydomain.com，很多帮助和资料都在解释如何创建子域名的应用。HostMonster关于该问题的答复是使用symbolic link，但语焉不详。<br /><br />由于我对Unit和Linux了解不多，一直无法理解到底如何使用该命令。直到昨晚，花时间研究、尝试，并找到一个牛贴。恍然大悟。<br /><br />使用SSH连接空间，过程如下。<br /><br />首先，把原有的public_html备份，mv public_html public_html-bak。<br />其次，在$HOME下用rails命令创建自己的Rails应用，rails test。<br />然后，使用ln -s $HOME/test/public public_html。<br /><br />完成，输入http://mydomain.com，看到Rails示例应用正常运行。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/196161#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 23 May 2008 15:53:30 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/196161</link>
        <guid>http://zerozone.javaeye.com/blog/196161</guid>
      </item>
      <item>
        <title>netbeans中文字体引发的新问题</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/194421" style="color:red;">http://zerozone.javaeye.com/blog/194421</a>&nbsp;
          发表时间: 2008年05月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          打算使用netbeans作为rails的开发工具。发现中文字体太小，难看。Google之后，更改etc/netbeans.conf文件<br /><br />注意粗体部分是新加内容：<br />netbeans_default_options="-J-Dcom.sun.aas.installRoot=\"C:\Program Files\glassfish-v2ur1\" -J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Xverify:none -J-Dapple.laf.useScreenMenuBar=true" <strong>--fontsize 12</strong><br /><br />重新启动，遇到一个错误，提示如下：<br /><br />D:\Program Files\NetBeans 6.0.1\Files\glassfish-v2ur1 -J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Xverify:none -J-Dapple.laf.useScreenMenuBar=true<br />不存在，或者不是普通文件。<br /><br />点击确定，打开netbeans，每次都弹出这个对话框，烦！<br />再检查错误信息，发现Files\目录很搞笑，哪有这个目录啊。应该是修改中文字体所致。想起很多Java程序无法正确读取文件名中空格问题，大概有了解决方法。那就是把Program Files更改为Program%20Files，尝试一下，OK。<br /><br />再想想，要解析netbeans_default_options参数，必须以空格作为pattern，因此Program Files中间的空格被误认为是两个参数之间的分隔符。解析过程出错。<br /><br />总结：<br />1）安装netbeans时，不放到Program Files下能避免该问题。<br />2）出现该问题，将空格改为%20，问题解决。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/194421#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 19 May 2008 13:44:40 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/194421</link>
        <guid>http://zerozone.javaeye.com/blog/194421</guid>
      </item>
      <item>
        <title>PSP开发环境</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/170011" style="color:red;">http://zerozone.javaeye.com/blog/170011</a>&nbsp;
          发表时间: 2008年03月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          熟悉PSP的人大概都知道PSPSDK（http://www.pspdev.org），一个基于BSD协议的软件包。可是安装PSPSDK的开发环境不那么省心。因为该包推荐的安装运行方式有严重问题。也就是说你要花大量时间准备开发环境。我上周亲自经历整个过程，那叫一个痛苦。<br />    <br />    Cygwin+PSPSDK，看似一个不错的选择，都是Windows程序，安装方便。可通常方便的事情不一定最有效率。首先，Cygwin模拟Linux环境，比真实环境慢上数倍，而psptoolchain又是一个极其耗费资源的任务，你会遇到各种各样的错误，除非你的机器配置极高（2G以上内存），即便安装过程顺利，也要耗费很多时间：<br /><br />    1.下载安装Cygwin，20分钟。<br />    2.下载安装psptoolchain，编译需要大概60~120分钟甚至更多。<br /><br />    漫长的等待！还要担心错误出现，事实上这种可能性很高。<br /><br />    VirtualPC+Ubuntu+psptoolchain。至少不会出现耗尽资源的问题，但VirtualPC里面你要管理一个真实的Linux系统，如果不熟悉，先花时间熟练它吧。例如apt-get工具。并且psptoolchain的编译过程同样不可省略。<br /><br />    最佳选择是devkitPro for PSP。需要20分钟，一次下载安装全部搞定。<br /><br />    最后，说说Cygwin的耗尽资源问题，我在单位和家里两台计算机都出现该问题。看来这个问题很严重，于是查查了pspdev论坛，发现psptoolchain的作者oopo说，该任务确实耗费资源，他不建议在很差的机器上安装。<br /><br />Seriously, building the toolchain can put stress on your hardware that you won't normally see. Think of it like a burn-in test. Cheap hardware and barely capable ram can cause weird intermittent errors.<br /><br />There's nothing you can do other than replace the faulty hardware. Installing a pre-built toolchain may seem to work for now but there's always the chance you'll still get weird unexplained errors and and corrupt data.<br /><br />    其实，完全没有道理要求开发者下载这样一个浪费时间和资源的工具，显然该工具不够人性化，如此恐怖烦人的安装过程，我还遇到的不多。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/170011#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 10 Mar 2008 23:57:30 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/170011</link>
        <guid>http://zerozone.javaeye.com/blog/170011</guid>
      </item>
      <item>
        <title>&lt;&lt;Ajax In Practice&gt;&gt;翻译定稿</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/170004" style="color:red;">http://zerozone.javaeye.com/blog/170004</a>&nbsp;
          发表时间: 2008年03月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          为了翻译，我已经很久没有写博客了。好在此书已进入最后定稿阶段，可以抽些时间认真做个总结了。<br /><br />    尽管做了最坏的打算，在本书翻译过程中，我们还是遇到了非常多的困难，限于篇幅这里不仔细说明了。交稿自然延期了，幸亏翻译团队的核心人物hax，他技术理解准确，语言驾驭力强。本书的翻译质量还是不错的。<br /><br />    本书注重实践，给出了Ajax应用开发过程涵盖的各个方面的大量实例。尤其是第2篇，也是本书的核心内容，深入探讨了事件处理、表单验证和提交、处理后退/刷新/撤消按钮、内容导航、拖放，还有用户友好性的UI设计、状态和缓存管理、第三方Web接口等领域。相信本书能为读者的Ajax开发带来一些帮助。可惜的是，书中的一些语句包括示例选取，甚至在某些技术细节上原作者的理解可能都是瑕疵的。总的来说，还是一本值得看的好书。<br /><br />    翻译下来的最大体会是，翻译需要投入巨大的时间、精力，最重要的是保持严谨的态度，无论技术还是译文，力求准确无误，这也是翻译的基本要求。当然，正确理解技术是做好翻译的基础，不过我更感觉到<strong>现代汉语基础</strong>的重要！技术书籍中文版的失败，主要还是人的因素。譬如译者的汉语能力高低、工作态度，合作能力等等都会影响翻译质量。把简单的事情做好，也许是复杂的事情就不那么难了。<br /><br /><br /><br />第6章	表单验证与提交<br />Form validation and submission<br /><br /><br />本章内容<br />	客户端字段验证<br />	客户端跨字段验证<br />	用POST方法发送HTTP请求<br />	使用XMLHttpRequest（XHR）进行表单提交<br /><br /><br />对输入进行有效性验证大概是Web开发人员最不喜欢的活动之一。我们经常听到这样的抱怨：“为什么用户就不能一次性键入正确的数据呢？”还有“我们反正要在服务器上进行验证，干嘛要自寻烦恼做什么客户端验证？”。特别是后者，貌似还挺有道理。那么我们为什么要进行输入验证呢？<br />这是因为，它创造了更好的用户体验：<br />■ 将表单上的错误数据立即反馈给用户<br />■ 减少服务器资源占用（网络流量和服务器运行周期），令用户界面（UI）运行更流畅<br /><br />	输入验证要和HTML表单提交配合使用：首先验证数据是否有效，然后将它提交到服务器。本章第二部分，我们将讨论使用Ajax请求实现HTML表单处理和提交。自行实现POST请求其实要进行低层次的数据处理，你要直接与服务器通讯，而不是由浏览器代劳。这个过程非常容易出错，不过如果正确实现了它，就能消除那些讨厌的浏览器页面刷新，令你的用户界面更为迅速。<br /><br />6.1 客户端表单验证<br />Client-side validation<br /><br />什么是表单验证？简单说，就是确认用户在表单中输入的数据是否有效。目前有效这个概念有点模糊，但主要是指表单中的数据要符合某些规则。<br />表单验证早已有之，最初多在服务端实现，后来转移到客户端，这使得用户能更快得到反馈。许多服务端框架比如Struts都提供了表单验证功能，但遗憾的是，对客户端验证的支持始终不够。<br />本节我们将看一看怎样亲手创建一个可扩展的客户端验证框架。我们会循序渐进，先是一些简单的验证功能，然后是“即输即验”式验证以及跨字段验证。<br /><br />6.1.1 在客户端进行验证<br />Validating on the client side<br /><br />	在客户端进行验证可能非常……唔，可能不太有趣 。显然，如果能创建一个程序库，然后每个页面都重用这个程序库，而不是每次去重新编写一遍验证代码，那就好了。没错，这正是我们下面所要看到的。<br />	注意，我们将使用面向对象的JavaScript，以便提高程序的可维护性和可扩展性。如果你需要复习一下这部分内容，请参考本书第3章。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/170004#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 10 Mar 2008 23:15:38 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/170004</link>
        <guid>http://zerozone.javaeye.com/blog/170004</guid>
      </item>
      <item>
        <title>SmartClient Ajax 框架目前推出了基于LGPL的开源版本</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/142038" style="color:red;">http://zerozone.javaeye.com/blog/142038</a>&nbsp;
          发表时间: 2007年11月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          SmartClient Ajax 框架目前推出了基于LGPL的开源版本<br />
<br />
<a href="http://www.smartclient.com/company/pr_60_release.jsp">http://www.smartclient.com/company/pr_60_release.jsp</a><br />
<br />
2007年11月7号，Isomorphic软件在加利福尼亚旧金山市正式宣布，业界领先的Ajax框架目前已开源并推出了基于LGPL的开源版本，包括服务端、工具库和其他组件。<br />
<br />
基于LGPL的新版本拥有完整的Ajax可视化组件集以及数据绑定设施，主流软件提供商多年来一直使用它们来交付基于SmartClient的产品。<br />
<br />
<strong>企业级的开源组件</strong><br />
作为非开源的商业框架爱提供商，目前推出基于LGPL的开源版本的SmartClient框架，已经为当今世界众多专业而成功的Ajax应用提供了基础，包括Informatica、Intuit和Wily/CA公司的产品。<br />
<br />
目前所有基于SmartClient的应用都不需要了解框架的源代码。因为SmartClient框架的设计思想就是使开发人员不必关心Ajax底层实现细节。使用SmartClietn进行开发，不用熟悉SmartClient框架的源代码、接受Ajax基础知识培训或者解决跨浏览器不兼容问题。基于LPGL的SmartClient包含完整的应用示例集、文档、必要的诊断工具来创建前沿的Ajax应用。<br />
<br />
&ldquo;有人认为Ajax是一门新技术，实际上，SmartClient是一个有着7年历史的老产品，它有大量成功的实际应用&rdquo;，Isomorphic软件公司的CTO Charles Kendrick这样说。&ldquo;在这一点上，我们见过开发新手成功利用SmartClient实现小型商业应用，与此同时一些软件供应商使用SmartClient开发出了突破Ajax能力极限的应用&rdquo;。<br />
<br />
<strong>更多功能</strong><br />
SmartClient LGPL版包含多数Ajax框架都有的经典UI组件库，但除了这些标准组件外还支持大型数据库、元数据（metadata）管理、高级界面皮肤管理、WSDL/SOA绑定，还有许多其他特性，详情请访问smartclient.com。<br />
<br />
SmartClient LGPL版的扩展部分包括SmartClient Java Server，SmartClient Visual Builder工具，还可以购买一些企业级的可选组件。<br />
<br />
&ldquo;人们有多好疑惑譬如说：我要采用一项前沿技术吗或者我需要使用开源软件吗，我们打算消除人们的这种疑虑&rdquo;，Isomorphic软件的创建者之一Alex Shvedoff说，&ldquo;使用SmartClient LGPL版相当简单，问题变成了是否要利用我们提供的服务端产品、工具和服务或者更多支持&rdquo;。<br />
<br />
<strong>关于Isomorphic<br />
</strong>Isomorphic软件是一家从事Ajax技术的软件公司，致力于为企业和软件供应商提供真正可用的Ajax框架。SmartClient不是简单的组件，它提供了更广阔的、可定制的、可扩展的Ajax技术平台。该平台支持完整的软件开发周期，包括设计工具、强大的诊断工具以及介乎两者之间的所有工具。<br />
<br />
更多信息请访问<a href="http://www.smartclient.com">www.SmartClient.com</a>. <br />
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/142038#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 20 Nov 2007 14:37:18 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/142038</link>
        <guid>http://zerozone.javaeye.com/blog/142038</guid>
      </item>
      <item>
        <title>使用GWT开发Ext应用-- GWT-Ext 0.9已发布</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/99851" style="color:red;">http://zerozone.javaeye.com/blog/99851</a>&nbsp;
          发表时间: 2007年07月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <br />
感谢作者的辛勤劳动！<br />
<br />
我曾经写过<a href="http://www.javaeye.com/topic/94847">一篇文章</a>介绍GWT-Ext及其示例，现在它已经发布<a href="http://code.google.com/p/gwt-ext/">http://code.google.com/p/gwt-ext/</a>。我会投入一些时间研究它（这是我的工作之一<img src="/javascripts/fckeditor/editor/images/smiley/msn/teeth_smile.gif" alt="" />），如有时间会把<span style="font-size: 120%; font-weight: bold;">GettingStarted</span>翻译并介绍给大家或者提供一些有意义的基于实践总结性的文章。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/99851#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 10 Jul 2007 18:19:46 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/99851</link>
        <guid>http://zerozone.javaeye.com/blog/99851</guid>
      </item>
      <item>
        <title>[翻译]Ext  vs. Dojo</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/99755" style="color:red;">http://zerozone.javaeye.com/blog/99755</a>&nbsp;
          发表时间: 2007年07月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          你是否觉得人们似乎习惯了人云亦云而忽视了这样一个事实即只有用户才有最终的发言权。如论如何请把文本看完，我相信作者的独到观点很值得大家思考。原文：<a href="http://jroller.com/page/sjivan">http://jroller.com/page/sjivan</a><br />
<br />
<strong>Ext&nbsp; vs.&nbsp; Dojo</strong><br />
<br />
尊重是挣来的而非买来的。本文不对Ext和Dojo进行技术上的对比，而是对两者发展和建立用户群的区别做个比较。<br />
<br />
读完Alex Russell（Dojo创建者）的文章Why Dojo?之后，激发了我写本篇Blog。Alex在他的文章写到为什么Dojo应该被选用：相对其它Ajax库，Dojo拥有特有超越对手的深度&amp;广度，质量，性能和社区。他还指出：Dojo用于创建高级的，日流量高的网站。Dojo的创建工具是其关键。Dojo的Package系统使管理大型的UI开发项目变得轻松，它顶级的系统组件层使得你的应用让人尖叫不已；而这不需要更改代码。<br />
<br />
我曾经大量使用Dojo以前的版本0.3和0.4，当时还没有很多的选择，而Dojo领先于其它库。不过现在我的Dojo经验和Alex说的完全相反。Dojo的确有其广度和深度，但多数使用过的人说他们发现Dojo变的臃肿，这就是一个（不使用Dojo）的合理原因。当你开始创建任何一个比其示例大型的应用，Dojo应用就迅速变得相当迟钝。由于Dojo模板加载的同步特性导致正常浏览器&ldquo;僵住&rdquo;，这已经被某些Dojo提交者公开承认。Dojo组件框架中存在漏洞特别是Tab和Dialog，他们确实不知道其原因何在。<br />
<br />
Dojo社区变得越来越大，也许是因为Dojo曾领先于其它库或者因为用户已经在Dojo上投入很多，不管怎样都不值得乐观。多数用户对Dojo的差劲性能和文档匮乏感到不满和挫败。2007年7月3日，Dojo 0.9提前一年发布。它很大一部分被重写别且现在声称&ldquo;极快&rdquo;（译者注，巧合的是jQuery新版本同样声称速度提高800%，我的天&hellip;）。我很欣赏他们为新版本发布所做的辛勤工作以及Dojo新的改进，但让人厌倦的是在Dojo 0.9 beta 发布不到一周，作者就开始大谈Dojo有多快；如何在一些高级的网站上应用以及为何用户应该选用Dojo而不是其它。我相信Alex有他正确的理由，但我们能否让社区用户率先使用并验证其之前声称的成就吗？我们与其总是听作者讲Dojo有多好，倒不如多从用户那里倾听一些。<br />
<br />
现在让我们谈谈Ext &ndash; Ext源于一个YUI扩展，Jack Slocum出色的工作迅速引起广大用户们的注意。作者原网站上wordpress风格的注释马上取得成功并引发用户铺天盖地的评论。Jack继续做他的工作并在难以想象的极短时间内并制作出了最优质的成果如Grid组件和Tree组件；在质量和功能性上，它远超于任何我所知道的其它组件库。Jack是一个非常聪明的家伙，他从社区获取主要组件设计方案例如Grid，并基于用户反馈使其合为一体。YUI-Ext从一个YUI扩展开始成长为一个全面的库，它有简洁、强大的API。此时它的快速发展使得YUI保持跟进。<br />
<br />
Ext和Dojo的明显区别在于，当你浏览Ext论坛时，这里的用户对使用Ext极其兴奋并对他们制作的产品满意。我已经无法统计有多少次看到用户请求一个功能而Jack回复说这个功能早已经有了并指出其在文档的所在章节。我没有看到我用过的其它库有过类似情况。令人难以置信的是Jack好像总是能先于用户添加他们想要的功能。<br />
<br />
你也看不到Jack发布任何重大的引入侧目的讲述Ext如何好的新闻。相反是用户在说Ext如何好。有不计其数的使用Ext创建的网站，而不是虚幻的高级的、高流量的网站列表。<br />
<br />
Jack从社区赢得了尊重，他不是靠谈论他的工作，而是努力制造用户喜欢的最优质的库。
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/99755#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 10 Jul 2007 13:29:56 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/99755</link>
        <guid>http://zerozone.javaeye.com/blog/99755</guid>
      </item>
      <item>
        <title>GWT+Ext </title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/94847" style="color:red;">http://zerozone.javaeye.com/blog/94847</a>&nbsp;
          发表时间: 2007年06月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          GWT支持对第三方library的模块化及重用。<a href="http://www.ibm.com/developerworks/cn/java/j-ajax4/#listing1">http://www.ibm.com/developerworks/cn/java/j-ajax4/#listing1</a> 介绍了如何GWT-RPC以及Scriptaculous创建Weather Reporter示例。<br />
<br />
很多人喜欢Ext，我也不例外。GWT虽然独具匠心，但缺乏给人眼前一亮的Widget组件。如果能结合GWT和Ext开发，岂不是很好。事实上，Sanjiv Jivan已经完成这个工作了，来看一个示例：<br />
<br />
<img src="http://jroller.com/resources/s/sjivan/gwt-ext-fv.jpg" alt="" /><br />
<br />
<br />
目前，作者在整理JavaDoc并表示即将把这个封装Ext的Wrapper代码在LGPL协议下发布。更多信息:<a href="http://jroller.com/page/sjivan?entry=gwt_ext_integration">http://jroller.com/page/sjivan?entry=gwt_ext_integration</a>
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/94847#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 27 Jun 2007 21:15:02 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/94847</link>
        <guid>http://zerozone.javaeye.com/blog/94847</guid>
      </item>
      <item>
        <title>GWT开发利器之Cypal Studio for GWT</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/94587" style="color:red;">http://zerozone.javaeye.com/blog/94587</a>&nbsp;
          发表时间: 2007年06月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">一）什么是</span><span style="font-size: 10pt; font-family: 宋体;">Cypal Studio for GWT?<o:p></o:p></span>
<p class="MsoNormal" style="margin-left: 15.75pt;"><span style="font-size: 10pt; font-family: 宋体;">Cypal Studio for GWT <span lang="ZH-CN">其实就是</span>Googlipse<span lang="ZH-CN">（</span>http://www.googlipse.com<span lang="ZH-CN">），但</span>Googlipse<span lang="ZH-CN">已经不再更新。该项目作者创建了一个新产品来替代</span>Googlipse<span lang="ZH-CN">，这就是</span>Cypal Studio for GWT<span lang="ZH-CN">。从下面的配置过程大家也可以看到二者基本一致。</span><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 15.75pt;"><span style="font-size: 10pt; font-family: 宋体;"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">二）环境配置及示例</span><span style="font-size: 10pt; font-family: 宋体;"><o:p></o:p></span>     <span style="font-size: 10pt; font-family: 宋体;"><br />
</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 宋体;">&nbsp; 1.Eclipse 3.2 + WTP1.5</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 宋体;">&nbsp; 2.</span><span style="font-size: 10pt; font-family: 宋体;">GWT<span lang="ZH-CN">，从</span><a href="http://code.google.com/webtoolkit/download.html">http://code.google.com/webtoolkit/download.html</a><span lang="ZH-CN">下载并解压缩至</span>D:/gwt-windows-1.4.10<span lang="ZH-CN">目录</span></span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 宋体;"><span lang="ZH-CN">&nbsp; 3.</span></span>Cypal Studio for GWT<span lang="ZH-CN">，从</span><a href="http://www.cypal.in/studio">http://www.cypal.in/studio</a> <span lang="ZH-CN">下载并解压缩至</span>Eclipse<span lang="ZH-CN">目录</span></p>
<p class="MsoNormal"><span lang="ZH-CN">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; font-family: 宋体;"><span lang="ZH-CN">4.</span></span><span lang="ZH-CN"></span><span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">运行</span><span style="font-size: 10pt; font-family: 宋体;">Eclipse<span lang="ZH-CN">，打开</span>Window-&gt;</span> <span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">Preferences-&gt;Cypal Studio<span lang="ZH-CN">，设置</span>GWT Home<span lang="ZH-CN">（步骤</span>2)</span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">&nbsp; 5.</span><span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">创建</span>Dynamic Web Project<span lang="ZH-CN">，在</span>configurations<span lang="ZH-CN">选项选中</span>Default Cypal Studio Project<br />
</p>
<span style="font-size: 10pt; font-family: 宋体;"> &nbsp; 6.</span><span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">创建</span><span style="font-size: 10pt; font-family: 宋体;">module<o:p></o:p></span>，<span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">从</span>File-&gt;New-&gt;Other-&gt;Cypal Studio-&gt; Module<span lang="ZH-CN">，输入</span>Module<span lang="ZH-CN">名称，注意</span>package<span lang="ZH-CN">不能为空，否则无法创建</span>com.yourcompany.server<span lang="ZH-CN">和</span>com.yourcompany.clinet目录。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 打开com.yourcompany.gwt.test.public下的test.html,添加一个表格。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<div class="code_title">html 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-xml" start="1">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">table</span><span>&nbsp;</span><span class="attribute">align</span><span>=</span><span class="attribute-value">center</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">tr</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">td</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">&quot;slot1&quot;</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">td</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">td</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">&quot;slot2&quot;</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">td</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">tr</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">table</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<br />
<span style="font-size: 10pt; font-family: 宋体;"><strong><span courier="" style="font-size: 10pt;"></span></strong><strong><span lang="ZH-CN" style="font-size: 10pt; color: rgb(127, 0, 85); font-family: 宋体;"></span></strong><strong><span courier="" style="font-size: 10pt;"></span></strong><strong><span lang="ZH-CN" style="font-size: 10pt; color: rgb(127, 0, 85); font-family: 宋体;"></span></strong><span courier="" style="font-size: 10pt;"><o:p></o:p></span><span courier="" style="font-size: 10pt;"><span style="font-size: 10pt; font-family: 宋体;"><span>
<p class="MsoNormal">&nbsp;&nbsp; <span style="font-size: 10pt; font-family: 宋体;">Test<span lang="ZH-CN">类实现</span>EntryPoint<span lang="ZH-CN">接口，需要手工实现</span>onModuleLoad<span lang="ZH-CN">方法。</span></span><span style="font-size: 10pt; font-family: 宋体;"><span lang="ZH-CN"><span lang="ZH-CN"></span></span>&nbsp;&nbsp;&nbsp; &nbsp; </span></p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;onModuleLoad()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">final</span><span>&nbsp;Button&nbsp;button&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Button(</span><span class="string">&quot;Click&nbsp;me&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">final</span><span>&nbsp;Label&nbsp;label&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Label();&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;button.addClickListener(<span class="keyword">new</span><span>&nbsp;ClickListener()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;onClick(Widget&nbsp;sender)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(label.getText().equals(</span><span class="string">&quot;&quot;</span><span>))&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label.setText(<span class="string">&quot;Hello&nbsp;World!&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">else</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label.setText(<span class="string">&quot;&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;Assume&nbsp;that&nbsp;the&nbsp;host&nbsp;HTML&nbsp;has&nbsp;elements&nbsp;defined&nbsp;whose</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;IDs&nbsp;are&nbsp;&quot;slot1&quot;,&nbsp;&quot;slot2&quot;.&nbsp;&nbsp;In&nbsp;a&nbsp;real&nbsp;app,&nbsp;you&nbsp;probably&nbsp;would&nbsp;not&nbsp;want</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;to&nbsp;hard-code&nbsp;IDs.&nbsp;&nbsp;Instead,&nbsp;you&nbsp;could,&nbsp;for&nbsp;example,&nbsp;search&nbsp;for&nbsp;all&nbsp;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;elements&nbsp;with&nbsp;a&nbsp;particular&nbsp;CSS&nbsp;class&nbsp;and&nbsp;replace&nbsp;them&nbsp;with&nbsp;widgets.</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RootPanel.get(<span class="string">&quot;slot1&quot;</span><span>).add(button);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RootPanel.get(<span class="string">&quot;slot2&quot;</span><span>).add(label);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<span style="font-size: 10pt; font-family: 宋体;"><span lang="ZH-CN"></span><o:p></o:p></span>
<p>&nbsp;</p>
<ol start="7" type="1" style="margin-top: 0in;">
    <li class="MsoNormal"><span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">运行</span><span style="font-size: 10pt; font-family: 宋体;"><o:p></o:p></span> </li>
</ol>
<p class="MsoNormal" style="margin-left: 0.25in;"><span lang="ZH-CN" style="font-size: 10pt; font-family: 宋体;">点击</span><span style="font-size: 10pt; font-family: 宋体;">Run-&gt;Run/Debug<span lang="ZH-CN">，打开运行配置对话框，双击</span>GWT Hosted Mode Application<span>，在右侧选择项目和模块，然后可以运行或调试。<br />
</span></span></p>
</span></span></span></span>
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/94587#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 27 Jun 2007 11:57:20 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/94587</link>
        <guid>http://zerozone.javaeye.com/blog/94587</guid>
      </item>
      <item>
        <title>金庸访谈感想</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/91558" style="color:red;">http://zerozone.javaeye.com/blog/91558</a>&nbsp;
          发表时间: 2007年06月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          昨晚《大家》对金庸进行访谈。有一点很有启发，就是金庸一生大部分时间从事于新闻事业。他坦然做新闻很痛苦。而写小说则很快乐。<br />
<br />
早年他立志做一名外交官，由于正直有余，对领袖不够忠诚，大学被开除。他又是一个很洒脱的人，不愿意被规矩束缚。尽管得到乔冠华的赏识，他最终还是没有进入新中国的外交圈，对于一个地主家庭出身的人又不是党员，当外交官没前途。<br />
<br />
谈到确立目标，他说他愿意立大的目标，小的目标容易达成，但没有什么意义。在八十多岁的年龄要读剑桥大学的博士学位，这岂是一般人所能做的事情！
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/91558#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Jun 2007 10:42:05 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/91558</link>
        <guid>http://zerozone.javaeye.com/blog/91558</guid>
      </item>
      <item>
        <title>基于Prototype实现对象级别Observer模式</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/87431" style="color:red;">http://zerozone.javaeye.com/blog/87431</a>&nbsp;
          发表时间: 2007年06月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p class="MsoNormal"><span style="FONT-SIZE: 10pt">Prototype</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">框架提供了基于</span><span style="FONT-SIZE: 10pt">JavaScript</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">语言的面向对象风格的</span><span style="FONT-SIZE: 10pt">AJAX</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">库，使编写动态</span><span style="FONT-SIZE: 10pt">WEB</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">程序成为可能。基于</span><span style="FONT-SIZE: 10pt">Prototype</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">的</span><span style="FONT-SIZE: 10pt">Scriptaculous</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">的流行就是一个很好的证明。</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="FONT-SIZE: 10pt"><o:p></o:p>Prototype</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">封装了</span><span style="FONT-SIZE: 10pt">Form</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">、</span><span style="FONT-SIZE: 10pt">Element</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">和</span><span style="FONT-SIZE: 10pt">Event</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">，并为</span><span style="FONT-SIZE: 10pt">Form</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">提供了</span><span style="FONT-SIZE: 10pt">Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">模式以便于进行事件管理和减少依赖。</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><strong><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">问题：</span></strong><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="FONT-SIZE: 10pt"><o:p></o:p>Prototype</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">设计了两种</span><span style="FONT-SIZE: 10pt">Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">，一种基于</span><span style="FONT-SIZE: 10pt">Timeout</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">，一种基于事件。但无法支持普通对象级别的</span><span style="FONT-SIZE: 10pt">Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">。例如在调用</span><span style="FONT-SIZE: 10pt">A</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象的</span><span style="FONT-SIZE: 10pt">X </span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法之后触发</span><span style="FONT-SIZE: 10pt">B</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象的</span><span style="FONT-SIZE: 10pt">Y</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法。本文将尝试一种在对象级别实现</span><span style="FONT-SIZE: 10pt">Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">的方式。</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<strong><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">分析：</span></strong><span style="FONT-SIZE: 10pt"><o:p></o:p></span>
<p class="MsoNormal"><span style="FONT-SIZE: 10pt"><o:p></o:p>Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">模式实现在&ldquo;被观察者&rdquo;的行为发生变化时，向多个对象（观察者）发生消息（并由该对象完成</span><span style="FONT-SIZE: 10pt">Update</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">操作）。面向对象语言借助</span><span style="FONT-SIZE: 10pt">Interface</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">实现</span><span style="FONT-SIZE: 10pt">Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">模式。如</span><span style="FONT-SIZE: 10pt">Java</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">中的</span><span style="FONT-SIZE: 10pt">java.util.Observable</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">相当于</span><span style="FONT-SIZE: 10pt">Subject</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">（被观察者），而</span><span style="FONT-SIZE: 10pt">java.util.Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">接口的实现者（观察者）完成</span><span style="FONT-SIZE: 10pt">Update</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">操作。</span></p>
<span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体"></span>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体"><img src="file:///C:/Documents and Settings/cxu/Desktop/clip_image002.jpg" alt="" /></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">上述方式对于降低类之间依赖不错。但是我们必须从特定的类继承或实现特定的接口。</span><span style="FONT-SIZE: 10pt">Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">消息触发方式导致问题也需要考虑。详见：</span><span style="FONT-SIZE: 10pt"><a href="http://www.microsoft.com/china/MSDN/library/architecture/patterns/esp/DesObserver.mspx?mfr=true">http://www.microsoft.com/china/MSDN/library/architecture/patterns/esp/DesObserver.mspx?mfr=true</a><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">当然，我们可以在</span><span style="FONT-SIZE: 10pt">JavaScript</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">中按照上述结构实现</span><span style="FONT-SIZE: 10pt">Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">会导致更多问题，例如如何实现接口编程？即使这个问题很容易解决，无论从理解和使用上这种模式都不太方便、不够直接。</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><strong><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">设计：</span></strong><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">再次聚焦</span><span style="FONT-SIZE: 10pt">Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">模式并观察它的核心，会发现如何实现消息触发是关键。一旦</span><span style="FONT-SIZE: 10pt">ConcreteSubject</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象拥有</span><span style="FONT-SIZE: 10pt">ConcreteObserver</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">的引用，在消息触发时就可以直接调用后者的</span><span style="FONT-SIZE: 10pt">Update</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法。</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体"><o:p></o:p><br />
代码执行顺序：</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">在</span><span style="FONT-SIZE: 10pt">concreteSubject</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">的对象内部：</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="FONT-SIZE: 10pt">if(this.stateChanged())<o:p></o:p></span></p>
<p class="MsoNormal"><span style="FONT-SIZE: 10pt"><span>&nbsp; </span><span>&nbsp;&nbsp;&nbsp;</span>concreteObservers.update(this,args);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">再看我的问题：在调用</span><span style="FONT-SIZE: 10pt">A</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象</span><span style="FONT-SIZE: 10pt">X</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法之后调用</span><span style="FONT-SIZE: 10pt">B</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象的</span><span style="FONT-SIZE: 10pt">Y</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法。</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">在</span><span style="FONT-SIZE: 10pt">A</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象内部：</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN-LEFT: 0.25in"><span style="FONT-SIZE: 10pt">this.X();<o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN-LEFT: 0.25in"><span style="FONT-SIZE: 10pt">B.Y();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体"><o:p></o:p><strong><font size="3">动态语言特性支持在</font></strong></span><span style="FONT-SIZE: 10pt"><strong><font size="3">Runtime</font></strong></span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体"><font size="3"><strong>时刻改变对象（数据和行为）</strong>。</font>考虑引入对象</span><span style="FONT-SIZE: 10pt">Observer</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">及方法</span><span style="FONT-SIZE: 10pt">register</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">。用户期望</span><span style="FONT-SIZE: 10pt">A</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象的</span><span style="FONT-SIZE: 10pt">X</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法调用后触发</span><span style="FONT-SIZE: 10pt">B</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象</span><span style="FONT-SIZE: 10pt">Y</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法时，将</span><span style="FONT-SIZE: 10pt">A</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象、</span><span style="FONT-SIZE: 10pt">X</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法名称和期望的动作（</span><span style="FONT-SIZE: 10pt">B.Y</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">）传入</span><span style="FONT-SIZE: 10pt">register</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法，然后在该方法中改写</span><span style="FONT-SIZE: 10pt">X</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">的行为。</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="FONT-SIZE: 10pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>A. _$_X = A.X;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="FONT-SIZE: 10pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>A.X = {this._$_X(); B.Y();}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体"><o:p></o:p><br />
同时增加</span><span style="FONT-SIZE: 10pt">unregister</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法设法恢复</span><span style="FONT-SIZE: 10pt">A</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">对象的行为（</span><span style="FONT-SIZE: 10pt">X</span><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">方法）。</span><span style="FONT-SIZE: 10pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体"><o:p>&nbsp;</o:p><br />
代码：</span><span style="FONT-SIZE: 10pt"><o:p>&nbsp;&nbsp;</o:p></span>&nbsp;</p>
<p>&nbsp;</p>
<div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-c">
    <li class="alt"><span><span class="keyword">var</span><span>&nbsp;StringBuffer&nbsp;=&nbsp;Class.create();&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>StringBuffer.prototype&nbsp;=&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;emptyString:<span class="string">&quot;&quot;</span><span>,&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;initialize:<span class="keyword">function</span><span>(){&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.data=[];&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;clear:<span class="keyword">function</span><span>(){&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.data.length=0;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;append:<span class="keyword">function</span><span>(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>(</span><span class="keyword">var</span><span>&nbsp;i=0,len=arguments.length;i</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.data[</span><span class="keyword">this</span><span>.data.length]=arguments[i];&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;toString:<span class="keyword">function</span><span>(){&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.data.join(</span><span class="keyword">this</span><span>.emptyString);&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>};&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span><span class="keyword">var</span><span>&nbsp;Observer&nbsp;=&nbsp;Class.create();&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>Observer.prototype&nbsp;=&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;initialize:<span class="keyword">function</span><span>(){&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;register&nbsp;the&nbsp;action&nbsp;to&nbsp;the&nbsp;object's&nbsp;method</span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;{Object}&nbsp;object</span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;{String}&nbsp;method</span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;{String}&nbsp;action</span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;register:<span class="keyword">function</span><span>(object,method,action){&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(!object&nbsp;||&nbsp;!method&nbsp;||&nbsp;!action&nbsp;||&nbsp;method&nbsp;==&nbsp;</span><span class="keyword">typeof</span><span>&nbsp;String&nbsp;||&nbsp;action&nbsp;==&nbsp;</span><span class="keyword">typeof</span><span>&nbsp;String)</span><span class="keyword">return</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//checks&nbsp;whether&nbsp;the&nbsp;method&nbsp;is&nbsp;existed.&nbsp;</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;f&nbsp;=&nbsp;object[method];&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(!f)</span><span class="keyword">return</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//copy,&nbsp;rename&nbsp;the&nbsp;method&nbsp;and&nbsp;replace&nbsp;it&nbsp;as&nbsp;a&nbsp;new&nbsp;method.</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;_$_f&nbsp;=&nbsp;</span><span class="string">&quot;_$_&quot;</span><span>+method;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(!object[_$_f]){&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object[_$_f]&nbsp;=&nbsp;f;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object[method]=&nbsp;<span class="keyword">this</span><span>.createFunction(method,action);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;unregister&nbsp;the&nbsp;action&nbsp;from&nbsp;the&nbsp;object's&nbsp;method</span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;{Object}&nbsp;object</span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;{Object}&nbsp;method</span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;unregister:<span class="keyword">function</span><span>(object,method){&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(!object||!method)</span><span class="keyword">return</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;_$_f&nbsp;=&nbsp;</span><span class="string">&quot;_$_&quot;</span><span>+method;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(object[_$_f]){&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object[method]&nbsp;=&nbsp;<span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object[method]&nbsp;=&nbsp;object[_$_f];&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object[_$_f]&nbsp;=&nbsp;<span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;create&nbsp;a&nbsp;new&nbsp;function&nbsp;that&nbsp;invokes&nbsp;both&nbsp;the&nbsp;method&nbsp;and&nbsp;the&nbsp;action&nbsp;</span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;{String}&nbsp;method</span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;{String}&nbsp;action</span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;createFunction:<span class="keyword">function</span><span>(method,action){&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;sb&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;StringBuffer();&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sb.append(<span class="string">&quot;this[\&quot;_$_&quot;</span><span>,method,</span><span class="string">&quot;\&quot;]();\r&quot;</span><span>,action);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;Function(sb.toString());&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/87431#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 06 Jun 2007 18:48:27 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/87431</link>
        <guid>http://zerozone.javaeye.com/blog/87431</guid>
      </item>
      <item>
        <title>第一个ActionScript MySQL Driver：asSQL原理与实践</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/83402" style="color:red;">http://zerozone.javaeye.com/blog/83402</a>&nbsp;
          发表时间: 2007年05月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;<span style="font-size: 9pt; font-family: 宋体;">熟悉<span lang="EN-US">Flex </span>的开发者都知道，在<span lang="EN-US">Flex</span>中不能直接访问数据库，而是采用<span lang="EN-US">HTTPService/WebService/RemoteObject</span>等方式实现。<span lang="EN-US">asSQL</span>的出现多少让大家感到意外（抛开这两种方式的优劣不提），也可见它的威力。<span lang="EN-US"><br />
<br />
<strong>1. </strong></span><strong>简介</strong><span lang="EN-US"><br />
<br />
</span>大型软件系统都采取了分层设计的原则，将其分为大致表现（<span lang="EN-US">UI</span>）、业务逻辑以及<span lang="EN-US">EIS</span>三部分。在<span lang="EN-US">Java</span>语言，直接与数据库打交道曾是家常便饭。<span lang="EN-US">Hibernate</span>等<span lang="EN-US">O/R Mapping</span>工具流行，直接使用<span lang="EN-US">JDBC</span>编程变得少见了，但有时这种方式更加简便、速度更快。<span lang="EN-US"><br />
<br />
ActionScript</span>用于在<span lang="EN-US">Flash</span>实现动画设计，访问数据库自然不是它的强项，甚至大家都觉得没有必要。<span lang="EN-US">asSQL</span>的出现使许多<span lang="EN-US">Flash</span>的开发 者感到惊喜（也许在<span lang="EN-US">Java</span>开发人员看来这实在算不了什么）。<span lang="EN-US">asSQL</span>现在是<span lang="EN-US">alpha</span>版本，还很稚嫩有一些问题。但基本工作正常。<span lang="EN-US"><br />
<br />
<strong>2. asSQL</strong></span><strong>驱动</strong><span lang="EN-US"><br />
<br />
a</span>）<span lang="EN-US">Connection<br />
<br />
asSQL</span>也提供了类似<span lang="EN-US">Java</span>语言的<span lang="EN-US">Connection</span>，确切的说<span lang="EN-US">asSQL</span>中的<span lang="EN-US">Connection</span>是类，而<span lang="EN-US">Java</span>的<span lang="EN-US">Connectio</span>是接口。<span lang="EN-US"> Connection</span>负责与<span lang="EN-US">mySQL Server</span>通讯（通过<span lang="EN-US">socket</span>建立连接，握手，接收<span lang="EN-US">/</span>发送数据包），并按照<span lang="EN-US">mySQL</span>协议解析、加密数据包（此处略去协议处理细节，感兴趣的请访问<span lang="EN-US"> http://www.redferni.uklinux.net/mysql/MySQL-Protocol.html</span>）。<span lang="EN-US"><br />
<br />
b</span>）<span lang="EN-US">MysqlService<br />
<br />
</span>虽然<span lang="EN-US">Connection</span>是<span lang="EN-US">asSQL</span>的核心对象，但与客户打交道仅有一个<span lang="EN-US">UI</span>组件<span lang="EN-US">MysqlService</span>。该组件需要用户输入<span lang="EN-US">host</span>，<span lang="EN-US">port</span>，<span lang="EN-US"> database</span>等信息，在内部创建<span lang="EN-US">Connection，</span>这避免了用户直接操作<span lang="EN-US">Connection</span>可能引发的错误。<span lang="EN-US"><o:p></o:p></span></span>&nbsp;</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">controls:MysqlService</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">&quot;sqlService&quot;</span><span>&nbsp;</span><span class="attribute">host</span><span>=</span><span class="attribute-value">&quot;localhost&quot;</span><span>&nbsp;</span><span class="attribute">port</span><span>=</span><span class="attribute-value">&quot;3306&quot;</span><span>&nbsp;</span><span class="attribute">user</span><span>=</span><span class="attribute-value">&quot;root&quot;</span><span>&nbsp;</span><span class="attribute">scrambler</span><span>=</span><span class="attribute-value">&quot;{new&nbsp;PlainTextScrambler('sa')}&quot;</span><span>&nbsp;&nbsp;</span></span><span class="attribute">database</span><span>=</span><span class="attribute-value">&quot;jpetstore&quot;</span><span>&nbsp;</span><span class="attribute">response</span><span>=</span><span class="attribute-value">&quot;onResponse(event)&quot;</span><span>&nbsp;</span><span class="attribute">error</span><span>=</span><span class="attribute-value">&quot;onError(event)&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>&nbsp;<span style="font-size: 9pt; font-family: 宋体;">将操作结果保存到<span lang="EN-US">lastResult</span>中，因此它可作为数据源（<span lang="EN-US">data provider</span>）供其它组件（如<span lang="EN-US">DataGrid</span>）使用，如下所示：<span lang="EN-US"><o:p></o:p></span></span>&nbsp;&nbsp;</p>
<span lang="EN-US" style="font-size: 9pt; font-family: 宋体;">
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">mx:DataGrid</span><span>&nbsp;</span><span class="attribute">x</span><span>=</span><span class="attribute-value">&quot;55&quot;</span><span>&nbsp;</span><span class="attribute">y</span><span>=</span><span class="attribute-value">&quot;137&quot;</span><span>&nbsp;</span><span class="attribute">dataProvider</span><span>=</span><span class="attribute-value">&quot;{sqlService.lastResult}&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">mx:columns</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">mx:DataGridColumn</span><span>&nbsp;</span><span class="attribute">headerText</span><span>=</span><span class="attribute-value">&quot;UserId&quot;</span><span>&nbsp;</span><span class="attribute">dataField</span><span>=</span><span class="attribute-value">&quot;userid&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">mx:DataGridColumn</span><span>&nbsp;</span><span class="attribute">headerText</span><span>=</span><span class="attribute-value">&quot;Email&quot;</span><span>&nbsp;</span><span class="attribute">dataField</span><span>=</span><span class="attribute-value">&quot;email&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">mx:DataGridColumn</span><span>&nbsp;</span><span class="attribute">headerText</span><span>=</span><span class="attribute-value">&quot;First&nbsp;Name&quot;</span><span>&nbsp;</span><span class="attribute">dataField</span><span>=</span><span class="attribute-value">&quot;firstname&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">mx:columns</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span></span><span class="tag"><span class="tag-name">mx:DataGrid</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p class="MsoNormal" align="left" style="margin-bottom: 12pt; text-align: left;">在一个按钮click事件中，调用myService.send(<font face="宋体">'SELECT userid,email,firstname FROM account;'</font>)即可触发上述DataGrid加载数据。</p>
<p class="MsoNormal" align="left" style="margin-bottom: 12pt; text-align: left;">MysqlService<span style="font-size: 9pt; font-family: 宋体;">支持<span lang="EN-US">3</span>个事件，分别是<strong><em><span lang="EN-US">results</span></em></strong>、<strong><em><span lang="EN-US">response</span></em></strong>和<strong><em><span lang="EN-US">errors</span></em></strong>，供调用者定制操作结果。<span lang="EN-US"><br />
<strong><br />
<em><span style="color: fuchsia;">errors </span></em></strong></span><strong><em><span style="color: fuchsia;">：显然是发生错误</span></em><span lang="EN-US"><br />
<em><span style="color: fuchsia;">results</span></em></span><span style="color: fuchsia;">、<em><span lang="EN-US">response</span>的区别是前者针对<span lang="EN-US">SELECT</span>操作，后者针对<span lang="EN-US">UPDATE</span>，<span lang="EN-US">DELETE......</span></em></span></strong><em><span lang="EN-US" style="color: fuchsia;"><br />
<br />
</span></em>遗憾的是，<span lang="EN-US">MysqlService</span>设计的不够完美，<span lang="EN-US">Connection</span>的创建和释放<strong>可能</strong>被分离到类内部和外部实现。如果用户提供上述事件的响应函数，就必须在该函数中显示关闭<span lang="EN-US">connection</span>。如下所示：</span>&nbsp;</p>
<p class="MsoNormal" align="left" style="margin-left: 36pt; text-indent: -18pt; text-align: left;"><span lang="EN-US" style="font-size: 9pt; font-family: 宋体;"><o:p></o:p></span></p>
<span lang="EN-US" style="font-size: 9pt; font-family: 宋体;">
<div class="code_title">ActionScript&nbsp;代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">private</span><span>&nbsp;function&nbsp;onResults(e:ResultsEvent):</span><span class="keyword">void</span><span>{ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;st:Statement&nbsp;=&nbsp;Statement(e.target); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;con:Connection&nbsp;=&nbsp;st.getConnection(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;rs:ResultSet&nbsp;=&nbsp;e.resultSet; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>&nbsp;(&nbsp;rs.next()&nbsp;)&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;userid&nbsp;=&nbsp;rs.getString(</span><span class="string">&quot;userid&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//var&nbsp;email&nbsp;=&nbsp;rs.getString(2); </span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trace(userid); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.disconnect(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">private</span><span>&nbsp;function&nbsp;onResponse(e:ResponseEvent):</span><span class="keyword">void</span><span>{&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;st:Statement&nbsp;=&nbsp;Statement(e.target); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;con:Connection&nbsp;=&nbsp;st.getConnection(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;affectedRows:</span><span class="keyword">int</span><span>&nbsp;=&nbsp;e.affectedRows; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;insertID:</span><span class="keyword">int</span><span>&nbsp;=&nbsp;e.insertID; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.disconnect(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">private</span><span>&nbsp;function&nbsp;onError(e:SQLErrorEvent):</span><span class="keyword">void</span><span>{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;st:Statement&nbsp;=&nbsp;Statement(e.target); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;con:Connection&nbsp;=&nbsp;st.getConnection(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;message:String&nbsp;=&nbsp;e.msg; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;errorNo:</span><span class="keyword">int</span><span>&nbsp;=&nbsp;e.id; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;text:String&nbsp;=&nbsp;e.text;&nbsp;</span><span class="comment">//&nbsp;Equals&nbsp;SQLError&nbsp;#{id}:&nbsp;{msg} </span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.disconnect(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
<br />
3. <span style="font-size: 9pt; font-family: 宋体;">示例<span lang="EN-US"><br />
<br />
&nbsp;&nbsp;&nbsp; asSQL</span>目前仅支持<span lang="EN-US">mySQL</span>，它以<span lang="EN-US">UI</span>组件的形式供用户调用，并以数据源的形式把数据和<span lang="EN-US">UI</span>组件绑定。<span lang="EN-US"><br />
<br />
&nbsp;&nbsp;&nbsp; </span>开发环境：<span lang="EN-US">Flex Builder 2</span>，以及<span lang="EN-US">MySql 5</span>，还有<span lang="EN-US">Spring <st1:chsdate isrocdate="False" month="12" w:st="on" day="30" islunardate="False" year="1899">1.2.8</st1:chsdate></span>中实例<span lang="EN-US">JPetStore</span>的<span lang="EN-US">Schema</span>。<span lang="EN-US"><br />
<br />
</span>步骤<span lang="EN-US">1</span>：<span lang="EN-US">MySQL</span>中建立一个叫做<span lang="EN-US">JPetStore</span>的<span lang="EN-US">Database</span>。并把<span lang="EN-US">JPetStore</span>的<span lang="EN-US">Schema</span>导入其中。<span lang="EN-US"><br />
</span>步骤<span lang="EN-US">2</span>：从<span lang="EN-US">http://maclema.com/assql/downloads/asSQL-0.1alpha.swc</span>下载<span lang="EN-US">asSQL SWC<br />
</span>步骤<span lang="EN-US">3</span>：新建<span lang="EN-US">Flex Project</span>项目，然后选中项目根目录，右键<span lang="EN-US">Properties-&gt;Flex Build Path-&gt;Library Path</span>；点击右侧按钮<span lang="EN-US">Add SWC</span>，在浏览窗口找到刚下载的<span lang="EN-US">SWC</span>文件。<span lang="EN-US"><br />
</span>步骤<span lang="EN-US">4</span>：编辑<span lang="EN-US">Flex</span>的界面元素，增加<span lang="EN-US">1</span>个<span lang="EN-US">ComboBox</span>和<span lang="EN-US">1</span>个<span lang="EN-US">DataGrid</span>，以及<span lang="EN-US">2</span>个按钮。然后编辑<span lang="EN-US">MXML</span>文件。<span lang="EN-US"><br />
<br />
</span>附件是运行界面和源代码。</span></span></span>
          <br/>
          <span style="color:red;">
            <a href="http://zerozone.javaeye.com/blog/83402#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 26 May 2007 23:50:00 +0800</pubDate>
        <link>http://zerozone.javaeye.com/blog/83402</link>
        <guid>http://zerozone.javaeye.com/blog/83402</guid>
      </item>
      <item>
        <title>FlexPetStore--集成Flex和Spring (2)</title>
        <author>zerozone</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zerozone.javaeye.com">zerozone</a>&nbsp;
          链接：<a href="http://zerozone.javaeye.com/blog/81908" style="color:red;">http://zerozone.javaeye.com/blog/81908</a>&nbsp;
          发表时间: 2007年05月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Flex部署在Flex Builder帮助中有详细说明（如部署目录结构）。遗憾的是没有例子介绍Flex如何集成Spring。本文尝试解释这部分内容。由于机器重装，导致FlexPetStore的项目丢失，幸好是覆盖安装留下了可运行的WAR。<br />
<p> FlexPetStore通过RemoteObject技术访问JPetStoreFacade业务对象（引入一个FacadeAccessor对象），因此使用了Flex Data Service 2.0。</p>
<p>大致流程:<br />
</p>
<p>Flex (ActionScript )&lt;--&gt; AMF协议(AMF协议编码)&lt;--&gt;(解码)&lt;--&gt;FacadeAccessor (Java) &lt;--&gt; PetStoreFacade (Java)&lt;--&gt; ...</p>
<p> 看了一下 FDS 2.0 提供的几个应用WAR，发现只要按照Flex的部署思路，在现有WAR基础上适当修改就可以集成Flex和Spring。首先需要把flex.war该名为flexpetstore.war，现在按照一下介绍逐步修改。<br />
<br />
<strong>Spring集成</strong><br />
<br />
1. 加入Lib库。把spring.jar和jpetsotre.jar放到 flexpetstore\WEB-INF\lib下，这是运行Spring和JPetstore的必备包。<br />
2. 修改flexpetstore.war的web.xml，经过一番对比和试验找到两个段落需要修改。<br />
&nbsp;&nbsp; a. 添加web应用根目录和Spring应用上下文以及数据访问资源配置。<br />
&nbsp;&nbsp; b. 添加Remoting、web service。struts部分极有可能多余，因为没有action来Request。有待测试。<br />
&nbsp;&nbsp; c. <span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span>修改welcome-file-list，<span><span>FlexPetStore.html是FlexPetStore项目名称</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
&nbsp;&nbsp; <br />
</p>
<span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span></span>到此为止，集成Spring配置基本完成。还有一部分服务端的Java代码作为RemoteObject供Flex访问，下一部分再讲解。<br />
<br />
附件是两份web.xml。<br />
<br />
FacadeAccessor首先获取</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span>应用context</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span>，然后从context得到</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span>PetStoreFacade</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span><span>业务对象。<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;Decompiled&nbsp;by&nbsp;DJ&nbsp;v2.9.9.60&nbsp;Copyright&nbsp;2000&nbsp;Atanas&nbsp;Neshkov&nbsp;&nbsp;Date:&nbsp;2007-05-22&nbsp;22:12:45</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="comment">//&nbsp;Home&nbsp;Page&nbsp;:&nbsp;http://members.fortunecity.com/neshkov/dj.html&nbsp;&nbsp;-&nbsp;Check&nbsp;often&nbsp;for&nbsp;new&nbsp;version!</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span><span class="comment">//&nbsp;Decompiler&nbsp;options:&nbsp;packimports(3)&nbsp;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="comment">//&nbsp;Source&nbsp;File&nbsp;Name:&nbsp;&nbsp;&nbsp;FacadeAccessor.java</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span><span class="keyword">package</span><span>&nbsp;org.springframework.samples.jpetstore.domain.logic.flex;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span><span class="keyword">import</span><span>&nbsp;java.io.*;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.util.List;&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">import</span><span>&nbsp;org.springframework.context.support.ClassPathXmlApplicationContext;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span><span class="keyword">import</span><span>&nbsp;org.springframework.samples.jpetstore.domain.*;&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">import</span><span>&nbsp;org.springframework.samples.jpetstore.domain.logic.PetStoreFacade;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span><span class="keyword">import</span><span>&nbsp;org.springframework.samples.jpetstore.domain.logic.flex.exception.NotFoundBeanDifinitionException;&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">import</span><span>&nbsp;org.springframework.samples.jpetstore.domain.logic.flex.exception.OutputBeanDifinitionException;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;FacadeAccessor&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;FacadeAccessor()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;petStoreFacade&nbsp;=&nbsp;<span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init();&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;init()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">try</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getPetStoreFacade();&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;exception)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;PetStoreFacade&nbsp;getPetStoreFacade()&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">throws</span><span>&nbsp;NotFoundBeanDifinitionException,&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputBeanDifinitionException&nbsp;{&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(petStoreFacade&nbsp;==&nbsp;</span><span class="keyword">null</span><span>)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassPathXmlApplicationContext&nbsp;ctx&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;ClassPathXmlApplicationContext(&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;/applicationContext*.xml&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;beanDefinitionNames[]&nbsp;=&nbsp;ctx.getBeanDefinitionNames();&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(beanDefinitionNames&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;||&nbsp;beanDefinitionNames.length&nbsp;&lt;&nbsp;</span><span class="number">1</span><span>)&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">throw</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;NotFoundBeanDifinitionException(&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;Not&nbsp;found&nbsp;bean&nbsp;difinitions.&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;petStoreFacade&nbsp;=&nbsp;(PetStoreFacade)&nbsp;ctx.getBean(<span class="string">&quot;petStore&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;petStoreFacade;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;outputBeanDefinitionNames(String&nbsp;beanDefinitionNames[])&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">throws</span><span>&nbsp;OutputBeanDifinitionException&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(beanDefinitionNames&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>&nbsp;&amp;&amp;&nbsp;beanDefinitionNames.length&nbsp;&gt;&nbsp;</span><span class="number">0</span><span>)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataOutputStream&nbsp;out&nbsp;=&nbsp;<span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">try</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;DataOutputStream(</span><span class="keyword">new</span><span>&nbsp;BufferedOutputStream(&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">new</span><span>&nbsp;FileOutputStream(</span><span class="string">&quot;c:\\beandifinitions.txt&quot;</span><span>)));&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>&nbsp;(</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i&nbsp;&lt;&nbsp;beanDefinitionNames.length;&nbsp;i++)&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.writeBytes((<span class="keyword">new</span><span>&nbsp;StringBuilder(String&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.valueOf(beanDefinitionNames[i]))).append(<span class="string">&quot;\r\n&quot;</span><span>)&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.toString());&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.close();&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span class="keyword">catch</span><span>&nbsp;(IOException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">throw</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;OutputBeanDifinitionException((</span><span class="keyword">new</span><span>&nbsp;StringBuilder(&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;error&nbsp;occurs&nbsp;when&nbsp;output&nbsp;bean&nbsp;difinitions&nbsp;to&nbsp;file,&quot;</span><span>))&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.append(e.getMessage()).toString());&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Account&nbsp;getAccount(String&nbsp;username)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;petStoreFacade.getAccount(username);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Account&nbsp;getAccount(String&nbsp;username,&nbsp;String&nbsp;password)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;petStoreFacade.getAccount(username,&nbsp;password);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;insertAccount(Account&nbsp;account)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;petStoreFacade.insertAccount(account);&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;updateAccount(Account&nbsp;account)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;petStoreFacade.updateAccount(account);&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;List&nbsp;getUsernameList()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;petStoreFacade.getUsernameList();&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;List&nbsp;getCategoryList()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;petStoreFacade.getCategoryList();&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Category&nbsp;getCategory(String&nbsp;categoryId)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;petStoreFacade.getCategory(categoryId);&nbsp;&nbsp;</span></span><