??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲成人福利在线观看,亚洲av日韩av无码,亚洲一级视频在线观看http://m.tkk7.com/ericwang/category/5054.htmlzh-cnTue, 27 Feb 2007 13:11:24 GMTTue, 27 Feb 2007 13:11:24 GMT60【{载】用AJAX来控制书{֒回退按钮http://m.tkk7.com/ericwang/archive/2005/11/25/21397.htmlDionDionFri, 25 Nov 2005 02:33:00 GMThttp://m.tkk7.com/ericwang/archive/2005/11/25/21397.htmlhttp://m.tkk7.com/ericwang/comments/21397.htmlhttp://m.tkk7.com/ericwang/archive/2005/11/25/21397.html#Feedback0http://m.tkk7.com/ericwang/comments/commentRss/21397.htmlhttp://m.tkk7.com/ericwang/services/trackbacks/21397.html作者:Brad Neuberg
译?boool


版权声明QQ何获得Matrix授权的网站,转蝲时请务必以超链接形式标明文章原始出处和作者信息及本声?/span>
作?Brad Neuberg;boool
原文地址:http://www.onjava.com/pub/a/onjava/2005/10/26/ajax-handling-bookmarks-and-back-button.html
中文地址:http://www.matrix.org.cn/resource/article/43/43972_AJAX.html
关键词: ajax;bookmarks;back button


q篇文章描述了一个支持AJAX应用书签和回退按钮的开源的javascript库。在q个指南的最后,开发者将会得Z个甚至不?span style="color: Green;">Google Maps
或?Gmail那样处理的AJAX的解x案:健壮的,可用的书{֒向前向后的动作能够象其他的web面一h的工作?br>
AJAXQ怎样L制书{֒回退按钮 q篇文章说明了一个重要的成果QAJAX应用目前面对着书签和回退按钮的应用,描述了非常简单的历史库(Really Simple HistoryQ,一个开源的解决q类问题的框Ӟq提供了一些能够运行的例子?br>
q? 文章描q的主要问题是双重的Q一是一个隐藏的html 表单被用作一个大而短生命周期的客L信息的session~存Q这个缓存对在这个页面上前进回退是强壮的。二是一个锚q接和隐藏的iframes的组? 用来截取和记录浏览器的历史事Ӟ来实现前q和回退的按钮。这两个技术都被用一个简单的javascript库来装Q以利于开发者的使用?br>
存在的问?/span>
书签和回退按钮在传l的多页面的web应用上能利的运行。当用户在网站上冲浪Ӟ他们的浏览器地址栏能更新URL,q些URL可以被粘贴到的email或者添加到书签以备以后的用。回退和前q按钮也可以正常q行Q这可以使用户在他们讉K的页面间Ud?br>
AJAX应用是与众不同的Q然而,他也是在单一web面上成熟的E序。浏览器不是为AJAX而做的—AJAX他捕莯ȝ事gQ当web应用在每个鼠标点Lh面?br>
在象Gmail那样的AJAX软g里,览器的地址栏正的停留p用户在选择和改变应用的状态时Q这使得作书{ֈ特定的应用视N变得不可能。此外,如果用户按下了他们的回退按钮去返回上一个操作,他们会惊奇的发现览器将完全d原来他所在的应用的web面?br>
解决Ҏ
开 源的Really Simply History(RSH)框架解决了这些问题,他带来了AJAX应用的作书签和控制前q后退按钮的功能。RSH目前q是beta版,? Firefox1.0上,Netscape7及以?和IE6及以上运行。Safari现在q不支持Q要得到更详l的说明Q请看我的weblog中的文章Coding in Paradise: Safari: No DHTML History Possible).

目前存在的几个AJAX框架可以帮助我们做书{֒发布历史Q然而所有的框架都因Z们的实现而被几个重要的bug困扰Q请?a target="_new">Coding in Paradise: AJAX History Libraries 得知详情Q。此外,许多AJAX历史框架集成l定到较大的库上Q比如Backbase ?DojoQ这些框架提供了与传lAJAX应用不同的编E模型,开发者去采用一整套全新的方式去获得览器的历史相关的功能?br>
相应的,RSH是一个简单的模型Q能被包含在已经存在的AJAXpȝ中。而且QReally Simple History库用了一些技巧去避免影响到其他历史框架的bug.

Really Simple History框架?个javascriptcdl成Q分别叫DhtmlHistory ?HistoryStorage.

DhtmlHistory cL供了一个对AJAX应用提取历史的功能?AJAX面add() 历史事g到浏览器里,指定新的地址和关联历史数据。DhtmlHistory cȝ一个锚的hash表更新浏览器现在的URLQ比?new-location Q然后用q个新的URL兌历史数据。AJAX应用注册他们自己到历史监听器里,然后当用L前进和后退按钮D的时候,历史事g被激发,提供l浏览器? 的地址和调用add()持箋保留数据?br>
W二个类HistoryStorageQ允许开发者存储Q意大的历史数据。一般的面Q当一个用 户导航到一个新的网站,览器会卸蝲和清除所有这个页面的应用和javascript状态信息。如果用L回退按钮q回q来了,所有的数据已经丢失了? HistoryStorage c解决了q个问题Q他有一个api 包含单的hashtableҎ比如put(),get(),hasKey()。这些方法允许开发者在dweb面时存储Q意大的数据Q当用户点了 回退按钮q回Ӟ数据可以通过HistoryStorage c被讉K。我们通过一个隐藏的表单域(a hidden form fieldQ,利用览器即使在用户dweb面也会自动保存表单域值的q个Ҏ,完成q个功能?br>
让我们立卌入一个简单的例子吧?br>
CZ1
首先QQ何一个想使用Really Simple History框架的页面必d含(includeQdhtmlHistory.js 脚本?br>
<!-- Load the Really Simple 
     History framework -->
<script type="text/javascript"
        src="../../framework/dhtmlHistory.js">
</script>


DHTML History 应用也必d和AJAX web面相同的目录下包含一个叫blank.html 的指定文Ӟq个文g被Really Simple History框架l定而且对IE来说是必需的。另一斚wQRSH使用一个hidden iframe 来追t和加入IE历史的改变,Z正确的执行功能,q个iframe需要指向一个真正的地址Q不需要blank.html?br>
RSH框架创徏了一个叫dhtmlHistory 的全局对象Q作为操作浏览器历史的入口。用dhtmlHistory 的第一步需要在面加蝲后初始化q个对象?br>
window.onload = initialize;
    
function initialize() {
  // initialize the DHTML History
  // framework
  dhtmlHistory.initialize();


然后Q开发者用dhtmlHistory.addListener()Ҏ去订阅历史改变事件。这个方法获取一个javascript回调ҎQ当一个DHTML历史改变事g发生时他收?个自变量Q新的页面地址Q和M可选的而且可以被关联到q个事g的历史数据?br>
indow.onload = initialize;
    
function initialize() {
  // initialize the DHTML History
  // framework
  dhtmlHistory.initialize();
  
  // subscribe to DHTML history change
  // events
  dhtmlHistory.addListener(historyChange);


historyChange()Ҏ是简单易懂得Q它是由一个用户导航到一个新地址后收到的新地址QnewLocationQ和一个关联到事g的可选的历史数据historyData 构成的?br>
/** Our callback to receive history change
     events. */
function historyChange(newLocation,
                       historyData) {
  debug("A history change has occurred: "
        + "newLocation="+newLocation
        + ", historyData="+historyData,
        true);
}


上面用到的debug()Ҏ是例子代码中定义的一个工具函敎ͼ在完整的下蝲例子里有。debug()Ҏ单的在web面上打一条消息,W?个Boolean变量Q在代码里是true,控制一个新的debug消息打印前是否要清除以前存在的所有消息?br>
一个开发者用add()Ҏ加入历史事g。加入一个历史事件包括根据历史的改变指定一个新的地址Q就?edit:SomePage"标记, q提供一个事件发生时可选的会被存储到历史数据historyData?

window.onload = initialize;
    
function initialize() {
  // initialize the DHTML History
  // framework
  dhtmlHistory.initialize();
  
  // subscribe to DHTML history change
  // events
  dhtmlHistory.addListener(historyChange);
      
  // if this is the first time we have
  // loaded the page...
  if (dhtmlHistory.isFirstLoad()) {
    debug("Adding values to browser "
          + "history", false);
    // start adding history
    dhtmlHistory.add("helloworld",
                     "Hello World Data");
    dhtmlHistory.add("foobar", 33);
    dhtmlHistory.add("boobah", true);
      
    var complexObject = new Object();
    complexObject.value1 =
                  "This is the first value";
    complexObject.value2 =
                  "This is the second data";
    complexObject.value3 = new Array();
    complexObject.value3[0] = "array 1";
    complexObject.value3[1] = "array 2";
      
    dhtmlHistory.add("complexObject",
                     complexObject);


在add ()Ҏ被调用后Q新地址立刻被作Z个锚值显C在用户的浏览器的URL栏里。例如,一个AJAX web面停留在http://codinginparadise.org/my_ajax_appQ调用了dhtmlHistory.add ("helloworld", "Hello World Data" 后,用户在览器的URL栏里看到下面的地址
http://codinginparadise.org/my_ajax_app#helloworld

? 后他们可以把q个面做成书签Q如果他们用这个书{,你的AJAX应用可以d#helloworld值然后用她d始化web面。Hash里的? 址DReally Simple History  框架昑ּ的编码和解码QURL encoded and decodedQ? Q这是ؓ了解军_W的~码问题Q?br>
对当AJAX地址改变时保存更多的复杂的状态来_historyData  比一个更Ҏ的匹配一? URL的东西更有用。他是一个可选的|可以是Q何javascriptcdQ比如Number, String, 或?Object cd。有一个例子是用这个在一个多文本~辑器(rich text editorQ保存所有的文本Q例如,如果用户从这个页面漂U(或者说从这个页面导航到其他面Q离开了这个页面)走。当一个用户再回到q个地址Q浏览器 会把q个对象q回l历史改变侦听器Qhistory change listenerQ?br>
开发者可以提供一个完全的 historyData 的javascript对象Q用嵌套的对象objects和排列arrays来描l复杂的状态。只要是JSON (JavaScript Object Notation)  允许的那么在历史数据里就是允许的Q包括简单数据类型和null型。DOM的对象和可编E的览器对象比? XMLHttpRequest Q不会被保存。注意historyData 不会被书{持久化Q如果浏览器xQ或者浏览器的缓存被清空Q或者用h除历史的时候,会消失掉?br>
使用dhtmlHistory 最后一步,是isFirstLoad() Ҏ。如果你DC个web面Q再跛_一个不同的面Q然后按下回退按钮q回起始的网站,W一将完全重新装蝲QƈȀ发onload事g。这栯产生 破坏性,当代码在W一ơ装载时惌用某U方式初始化面的时候,不会再刷新页面。isFirstLoad() Ҏ让区别是最开始第一ơ装载页面,q是相对的,在用户导航回C自己的浏览器历史中记录的|页时激发load事gQ成为可能?br>
在例子代码中Q我们只惛_W一ơ页面装载的时候加入历史事Ӟ如果用户在第一ơ装载后Q按回退按钮q回面Q我们就不想重新加入M历史事g?br>
window.onload = initialize;
    
function initialize() {
  // initialize the DHTML History
  // framework
  dhtmlHistory.initialize();
  
  // subscribe to DHTML history change
  // events
  dhtmlHistory.addListener(historyChange);
      
  // if this is the first time we have
  // loaded the page...
  if (dhtmlHistory.isFirstLoad()) {
    debug("Adding values to browser "
          + "history", false);
    // start adding history
    dhtmlHistory.add("helloworld",
                     "Hello World Data");
    dhtmlHistory.add("foobar", 33);
    dhtmlHistory.add("boobah", true);
      
    var complexObject = new Object();
    complexObject.value1 =
                  "This is the first value";
    complexObject.value2 =
                  "This is the second data";
    complexObject.value3 = new Array();
    complexObject.value3[0] = "array 1";
    complexObject.value3[1] = "array 2";
      
    dhtmlHistory.add("complexObject",
                     complexObject);


? 我们l箋使用historyStorage cR类似dhtmlHistory QhistoryStorage通过一个叫historyStorage的单一全局对象来显CZ的功能,q个对象有几个方法来伪装成一个hash table, 象put(keyName, keyValue), get(keyName), and hasKey(keyName).键名必须是字W,同时键值可以是复杂的javascript对象或者甚xxml格式的字W。在我们源码source code的例子中Q我们put() 单的XML  到historyStorage 在页面第一ơ装载时?br>
window.onload = initialize;
    
function initialize() {
  // initialize the DHTML History
  // framework
  dhtmlHistory.initialize();
  
  // subscribe to DHTML history change
  // events
  dhtmlHistory.addListener(historyChange);
      
  // if this is the first time we have
  // loaded the page...
  if (dhtmlHistory.isFirstLoad()) {
    debug("Adding values to browser "
          + "history", false);
    // start adding history
    dhtmlHistory.add("helloworld",
                     "Hello World Data");
    dhtmlHistory.add("foobar", 33);
    dhtmlHistory.add("boobah", true);
      
    var complexObject = new Object();
    complexObject.value1 =
                  "This is the first value";
    complexObject.value2 =
                  "This is the second data";
    complexObject.value3 = new Array();
    complexObject.value3[0] = "array 1";
    complexObject.value3[1] = "array 2";
      
    dhtmlHistory.add("complexObject",
                     complexObject);
                    
    // cache some values in the history
    // storage
    debug("Storing key 'fakeXML' into "
          + "history storage", false);
    var fakeXML =
      '<?xml version="1.0" '
      +      'encoding="ISO-8859-1"?>'
      +      '<foobar>'
      +         '<foo-entry/>'
      +      '</foobar>';
    historyStorage.put("fakeXML", fakeXML);
  }


然后Q如果用户从q个面漂移赎ͼD赎ͼ又通过q回按钮q回了,我们可以用getQ)提出我们存储的值或者用haskeyQ)查他是否存在?br>
window.onload = initialize;
    
function initialize() {
  // initialize the DHTML History
  // framework
  dhtmlHistory.initialize();
  
  // subscribe to DHTML history change
  // events
  dhtmlHistory.addListener(historyChange);
      
  // if this is the first time we have
  // loaded the page...
  if (dhtmlHistory.isFirstLoad()) {
    debug("Adding values to browser "
          + "history", false);
    // start adding history
    dhtmlHistory.add("helloworld",
                     "Hello World Data");
    dhtmlHistory.add("foobar", 33);
    dhtmlHistory.add("boobah", true);
      
    var complexObject = new Object();
    complexObject.value1 =
                  "This is the first value";
    complexObject.value2 =
                  "This is the second data";
    complexObject.value3 = new Array();
    complexObject.value3[0] = "array 1";
    complexObject.value3[1] = "array 2";
      
    dhtmlHistory.add("complexObject",
                     complexObject);
                    
    // cache some values in the history
    // storage
    debug("Storing key 'fakeXML' into "
          + "history storage", false);
    var fakeXML =
      '<?xml version="1.0" '
      +      'encoding="ISO-8859-1"?>'
      +      '<foobar>'
      +         '<foo-entry/>'
      +      '</foobar>';
    historyStorage.put("fakeXML", fakeXML);
  }
  
  // retrieve our values from the history
  // storage
  var savedXML =
              historyStorage.get("fakeXML");
  savedXML = prettyPrintXml(savedXML);
  var hasKey =
           historyStorage.hasKey("fakeXML");
  var message =
    "historyStorage.hasKey('fakeXML')="
    + hasKey + "<br>"
    + "historyStorage.get('fakeXML')=<br>"
    + savedXML;
  debug(message, false);
}


prettyPrintXml() 是一个第一在例子源码full example source code中的工具Ҏ。这个方法准备简单的xml昄在web page Q方便调试?br>
? 意数据只是在使用面的历史时被持久化Q如果浏览器关闭了,或者用h开一个新的窗口又再次键入了ajax应用的地址Q历史数据对q些新的web面是不 可用的。历史数据只有在用前q或回退按钮时才被持久化Q而且在用户关闭浏览器或清I缓存的时候会消失掉。想真正的长旉的持久化Q请看Ajax MAssive Storage System (AMASS).
我们的简单示例已l完成。演CZQDemo itQ或者下载全部的源代码(download the full source code.Q?br>
CZ2
? 们的W?个例子是一个简单的模拟ajax email  应用的示例,叫O'Reilly Mail,cMGmail. O'Reilly Mail描述了怎样使用dhtmlHistorycd控制览器的历史Q和怎样使用historyStorage对象ȝ存历史数据?br>
O'Reilly Mail 用户接口Quser interfaceQ有两部分。在面的左Ҏ一个有不同email文g夹和选项的菜单,例如 收g,草稿Q等{。当一个用户选择了一个菜单项Q比如收件箱Q我们用q个菜单的内容更新双的页面。在一个实际应用中Q我们会q程取得和显C选择的信 内容,不过在O'Reilly Mail里,我们单的昄选择的选项?br>
O'Reilly Mail使用Really Simple History 框架向浏览器历史里加入菜单变化和更新地址栏,允许用户利用览器的回退和前q按钮对应用做书{֒跛_上一个变化的菜单?br>
? 们加入一个特别的菜单,地址,来描lhistoryStorage 能够怎样被用。地址是一个由联系的名字电子邮件和地址l成的javascript数组Q在一个真实的应用里我们会取得他从一个远E的服务器。不q,? O'Reilly Mail里,我们在本地创个数l,加入几个名字电子邮g和地址Q然后把他们存储在historyStorage 对象里。如果用L开了这个web面以后又返回的话,O'Reilly Mail应用重新从缓存里得到地址,胜过Q不得不Q再ơ访问远E服务器?br>
地址是在我们的初始化initialize()Ҏ里存储和重新取得?br>
/** Our function that initializes when the page
    is finished loading. */
function initialize() {
   // initialize the DHTML History framework
   dhtmlHistory.initialize();
  
   // add ourselves as a DHTML History listener
   dhtmlHistory.addListener(handleHistoryChange);

   // if we haven't retrieved the address book
   // yet, grab it and then cache it into our
   // history storage
   if (window.addressBook == undefined) {
      // Store the address book as a global
      // object.
      // In a real application we would remotely
      // fetch this from a server in the
      // background.
      window.addressBook =
         ["Brad Neuberg 'bkn3@columbia.edu'",
          "John Doe 'johndoe@example.com'",
          "Deanna Neuberg 'mom@mom.com'"];
          
      // cache the address book so it exists
      // even if the user leaves the page and
      // then returns with the back button
      historyStorage.put("addressBook",
                         addressBook);
   }
   else {
      // fetch the cached address book from
      // the history storage
      window.addressBook =
               historyStorage.get("addressBook");
   }


? 理历史变化的代码是简单的。在下面的代码中Q当用户不论按下回退q是前进按钮handleHistoryChange 都被调用。我们得到新的地址QnewLocationQ? 使用他更新我们的用户接口来改变状态,通过使用一个叫displayLocation的O'Reilly Mail的工h法?br>
/** Handles history change events. */
function handleHistoryChange(newLocation,
                             historyData) {
   // if there is no location then display
   // the default, which is the inbox
   if (newLocation == "") {
      newLocation = "section:inbox";
   }
  
   // extract the section to display from
   // the location change; newLocation will
   // begin with the word "section:"
   newLocation =
         newLocation.replace(/section\:/, "");
  
   // update the browser to respond to this
   // DHTML history change
   displayLocation(newLocation, historyData);
}

/** Displays the given location in the
    right-hand side content area. */
function displayLocation(newLocation,
                         sectionData) {
   // get the menu element that was selected
   var selectedElement =
            document.getElementById(newLocation);
            
   // clear out the old selected menu item
   var menu = document.getElementById("menu");
   for (var i = 0; i < menu.childNodes.length;
                                          i++) {
      var currentElement = menu.childNodes[i];
      // see if this is a DOM Element node
      if (currentElement.nodeType == 1) {
         // clear any class name
         currentElement.className = "";
      }                                      
   }
  
   // cause the new selected menu item to
   // appear differently in the UI
   selectedElement.className = "selected";
  
   // display the new section in the right-hand
   // side of the screen; determine what
   // our sectionData is
  
   // display the address book differently by
   // using our local address data we cached
   // earlier
   if (newLocation == "addressbook") {
      // format and display the address book
      sectionData = "<p>Your addressbook:</p>";
      sectionData += "<ul>";
      
      // fetch the address book from the cache
      // if we don't have it yet
      if (window.addressBook == undefined) {
         window.addressBook =
               historyStorage.get("addressBook");
      }
      
      // format the address book for display
      for (var i = 0;
               i < window.addressBook.length;
                     i++) {
         sectionData += "<li>"
                        + window.addressBook[i]
                        + "</li>";                  
      }
      
      sectionData += "</ul>";
   }
  
   // If there is no sectionData, then
   // remotely retrieve it; in this example
   // we use fake data for everything but the
   // address book
   if (sectionData == null) {
      // in a real application we would remotely
      // fetch this section's content
      sectionData = "<p>This is section: "
         + selectedElement.innerHTML + "</p>";  
   }
  
   // update the content's title and main text
   var contentTitle =
         document.getElementById("content-title");
   var contentValue =
         document.getElementById("content-value");
   contentTitle.innerHTML =
                        selectedElement.innerHTML;
   contentValue.innerHTML = sectionData;
}


演示QDemoQO'Reilly Mail或者下载(downloadQO'Reilly Mail的源代码?br>
l束?/span>
你现在已l学习了使用Really Simple History API 让你的AJAX应用响应书签和前q回退按钮Q而且有代码可以作为创Z自己的应用的素材。我热切地期待你利用书签和历史的支持完成你的AJAX创造?br>
资源
·onjava.com:onjava.com
·Matrix-Java开发者社?http://www.matrix.org.cn/
·Download all sample code for this article.
·Download the Really Simple History framework.
·Demo O'Reilly Mail or download the O'Reilly Mail source code. The full example download also includes more examples for you to play with.
·Coding in Paradise: The author's weblog, covering AJAX, DHTML, and Java techniques and new developments in collaborative technologies, such as WikiWikis.


感谢
特别的要感谢每个阅这文章的the Really Simple History框架的hQ?br> Michael Eakes, Jeremy Sevareid, David Barrett, Brendon Wilson, Dylan Parker, Erik Arvidsson, Alex Russell, Adam Fisk, Alex Lynch, Joseph Hoang Do, Richard MacManus, Garret Wilson, Ray Baxter, Chris Messina, and David Weekly.


Dion 2005-11-25 10:33 发表评论
]]>
一个用于J2EE应用E序的Backbase Ajax前端http://m.tkk7.com/ericwang/archive/2005/11/23/21178.htmlDionDionWed, 23 Nov 2005 12:31:00 GMThttp://m.tkk7.com/ericwang/archive/2005/11/23/21178.htmlhttp://m.tkk7.com/ericwang/comments/21178.htmlhttp://m.tkk7.com/ericwang/archive/2005/11/23/21178.html#Feedback0http://m.tkk7.com/ericwang/comments/commentRss/21178.htmlhttp://m.tkk7.com/ericwang/services/trackbacks/21178.html一个用于J2EE应用E序的Backbase Ajax前端

旉Q?005-11-03
作者:Mark Schiefelbein
览ơ数Q? 628
本文关键字:AjaxRIARich Internet ApplicationbackbaseDev Toolbox Eclipse WebLogic
文章工具
推荐l朋? align= 推荐l朋?/a>
打印文章 
打印文章

  动态HTML技术已l出C多年。最q,Google的最新Web应用E序GMail、Google Suggests和Google MapsQ在前端面中重新引入了Z标准的DHTML开发模型。Google证明了,DHTML开发模型能够让开发h员创建具有可视化吸引力和高度交互 式的Rich Internet ApplicationQ丰富网l应用程序,RIAQ?/p>

  Adaptive Path公司的Jesse James Garrett个基于标准的RIA开发模型创造了术语Ajax (Asynchronous JavaScript + XML)。与传统的基于页面的Web应用E序模型相比QAjax?点不同之处:

  • 有一个客L引擎担Q用户界面QUIQ和服务器之间的中介?/li>
  • 用户行ؓ由客L引擎处理Q而不是生成发往服务器的面h?/li>
  • XML数据在客L引擎和服务器之间传输?/li>

  换言之,Ajax解决Ҏ包括一个客L引擎Q它用于呈现用户界面Qƈ使用XML格式与服务器通信。这个引擎由很多JavaScript函数l成Q位于Web览器中Q它不需要插Ӟ也不需要用户安装?/p>

  ZAjax的RIA正在q速成为Web应用E序前端的基准,因ؓ它可以同时提供二者的优点Q丰富性和可达性。Ajax应用E序和桌面应用程? 一样丰富,响应高度灉|Qƈ且可以在一个页面上提供所有数据,无需h面。它们还拥有Z标准的浏览器应用E序的可达性特点,q类应用E序可以在不具备 览器插件或客户端applet的情况下q行部v?/p>

  Backbase所提供的Ajax软gh以下特点Q基于标准、功能全面且易于使用。Backbase Presentation Client (BPC)ZAjax技术,它用称为Backbase XML (BXML)的附加标{扩展了DHTML。Backbase XML Server Edition for J2EE (BXS)包含了一些服务器端的lgQ利用这些组ӞJ2EE开发h员可以快速开发J2EE应用E序的Ajax前端?/p>

  在本文中Q我使用Backbase为Java Pet Store开发了一个基于Ajax的前端。该案例分析说明了如何用Backbase技术作为J2EE应用E序的Ajax表示层。您可以查看文中所描述的应用程序的在线演示Q网址?a target="_blank">http://www.backbase.com/xmlserver?/p>

Backbase Ajax表示?/strong>

  Web开发h员应该能够轻村ֈ建具有以下特点的Rich Internet Application (RIA)Q完全基于HTML标准QW3CQ,不需要最l用户安装插Ӟ速度快Q能够在所有浏览器上进行操作,q与J2EEq行时和开发环境完全集成? RIA利用客户端(Web览器)资源创徏和管理用L面,从而ؓ最l用h供一个响应灵敏而且h应用E序风格的用L面?/p>

  q种Ҏ最q被UCؓAjax。Ajaxq个术语的灵感来源于Gmail、Google Maps和Google Suggestsq类应用E序Q它把现有的览器技术提高到了一个新的水q上。RIA从根本上改进了在U应用程序的可用性和有效性。Ajax RIA只用标准的览器技术(如JavaScript、XHTML和XMLHttpRequest对象Q就做到了这一炏V通过使用 XMLHttpRequestQ在数据异步加载到界面中时无需h面?/p>

  Backbase在J2EE架构中提供一个Ajax表示层,它结合了目前的J2EE服务器和先进的富客户端技术的优点。Backbase表示? 控制了富用户界面的每个方面:与最l用L交互模型Q与后端pȝ的集成,以及整个客户?服务器通信。Backbase直接提供了用于聚合来自Q意位|的 XML的下一个范型,数据绑定到先进的富用户界面控gQƈ在一个统一的富用户界面中交付组合应用程序?/p>

  Backbase表示层由一个客h和一个服务器l成。Backbase Presentation Client (BPC)是一个基于Ajax的GUI引擎Q它允许开发h员以声明性的方式快速构建RIA。Backbase XML(BXML)是对XHTML的扩展。它为开发h员提供了交付富前端功能的附加标签(B tag)。Backbase XML Server (BXS)提供一UXML水U架构,利用它可以从Web服务、数据库或Java对象获取数据Q可以聚合和转换q些数据Qƈ其l定到BPC中的UI? 素。BPC和BXS相结合,可以在Web览器和应用服务器之间搭Z座功能强大的桥梁Qƈ提供一个分布在客户端和服务器上的完整的富Internet? C层?/p>

  ?说明了在逻辑和物理应用程序架构中QBackbase所处的位置。应用程序由一个J2EE后端和一个基于Ajax的RIA前端l成。从逻辑 上说QBackbase提供了表C层Q而J2EE提供了业务逻辑和数据层。从物理上说Q表C层分布在客L和服务器上。在客户端上QBackbase使用 BPC扩展了浏览器。在服务器上QBackbase使用BXS扩展了应用服务器?/p>

?. Backbase富Internet表示?/p>

Pet Store案例分析

  我们用Java Pet Store作ؓ案例来分析如何ؓJ2EE应用E序dBackbase RIA前端。Java Pet Store Demo是Sun Microsystems提供的一个示例应用程序,其目的是Z演示如何使用Java 2 Platform, Enterprise Edition(J2EE)构徏Web应用E序Q详情请参见http://java.sun.com/developer/releases/petstoreQ?/p>

  Java Pet Store是业内一个著名的参考应用程序(pet storeq有.NET和Flash版本Q。由于以下两个原因,它成ZؓJ2EE应用E序dZAjax的RIA前端的完案例:

  • Java Pet Store是一个完整的Web应用E序?/li>

    Sun设计Pet Store的目的是演示所有常见的Web应用E序功能。通过使用Pet Store作ؓ案例Q我可以说明为J2EE应用E序dRIA层的所有方面?/p>

    作ؓ一个典型的在线商店Q它包含以下功能Q?/p>

    • 览产品cd?/li>
    • 在购物R中添加和删除物品?/li>
    • 填写订单表单?/li>
    • 提交订单?/li>
  • Java Pet Store有一个传l的HTML前端?/li>

    使用RIA前端的目的是提供更简单和响应更灵敏的GUIQ以及通常更ؓ丰富的Web用户体验。我说明,如何通过Backbase RIA技术极大地改进应用E序的前端,同时无需对后端和Mpȝ需求做M修改?/p>

    Pet Store的RIA前端通过以下方式改善可用性:

  • 把前端变Z个单面的界面(SPIQ?/li>
  • 提供更先q的UI控gQ如模态弹出式菜单Q?/li>
  • 使用可视化效果(例如Q把宠物攑օ购物车)?/li>
  • 更加有效地利用电脑屏q的操作区域?/li>

RIA Pet Store前端

  在这一节中Q我讨论经q改q的新Pet Store RIA前端?/p>

  下面的两个屏q快照演CZ前端的改q。要获得对Backbase RIA前端更直观的感受Q请讉Khttp://www.backbase.com/xmlserver上的在线演示Q或者到http://www.backbase.com/download下蝲BackbaseC֌版本?/p>

下面两个囑֯两个前端q行了可视化的比较。图2昄的是原来静态的多页面HTML前端。图3昄的是新的Backbase SPI前端Q?

?. 原始HTML前端

?. 新Backbase前端

  Backbase为创Z富的单页面Web界面提供了许多可能性。下面列Z一些Pet Store所使用的例子?/p>

  • 选项卡式的单面览
  • 在Web界面上,不同的动物种c(狗、猫{等Q被表示Z同的选项卡。点M个选项卡就会打开相应的类别,昄可供出售的宠物?/p>

    在Backbase SPI中,无需h面可以打开选项卡。BPC只从服务器请求所需的数据,然后更新客户端的视图。SPI机制可以极大地羃短响应时_让客户随心所Ʋ地在类别之间来回穿梭?/p>

  • zd的多功能界面
  • 界面有三个主要功能——类别浏览、购物R和页面引导历史记录,它们在界面上都是一直可见的。因此,购物者L能够查看购物车的当前内容或最q看q的宠物的记录?/p>

    q些功能是高度同步的Q浏览一个宠物时Q历史记录将自动更新为在记录中显C宠物。定购一个宠物时Q它被d到购物R中。上qC切都发生在客L的一个页面上Q例如,无需重新加蝲面可以更新界面的各个部分Q?/p>

  • 界面变化的流畅可视化效果
  • q行览Ӟ客户会看到不断变化的界面视图。例如,他可以按照h格和名称对宠物进行排序。界面需要根据新的排列顺序显C更C后的宠物清单?/p>

    在Backbase RIA前端中,以前的视图被使用可视化效果的新视图所代替Q新视图向最l用hCZ么正在改变。图4说明了如何通过畅的定位效果,把按名称排列的顺序{变ؓ按h格排列的序Q?

    ?.cd视图的排列顺序{?/p>

  • 用于提高转换速度的信息栏验证

  Z执行购买Q购买者必d一份表单中填入个h详细信息。Backbase极大地简化了q个购买q程Q通过客户端的信息栏验证提供即时的反馈Qƈ在提供所有数据的q程中提供逐步的指南和概述?/p>

  ?昄了在填写表单的第一个步骤中Q对于e-mail地址信息栏的验证。当购买者填写下一栏时Q就会提供即时的反馈?

?. 信息栏验证—e-mail?/p>

Backbase RIA Pet Store的架?/strong>

  增强Pet StoreQ或其他MWeb应用E序Q的前端Ӟ我们l依赖于以下两条架构基本原则Q?/p>

  • 最l用户仍然用标准的Web览器访问Pet StoreQ无需dM插g?/li>
  • 由J2EE业务逻辑和数据组成的整个后端保持不变?/li>

  现有的后端在开发期间是完全孤立的,而且不会改变Q这个事实对于架构师和IT理人员十分有利。通过一个规整的、模块化的架构,他们能够控刉险和成本Q同时显著提高Web应用E序的用户友好性?/p>

  Backbase的富表示层技术由两个模块l成Q它们将被加入到架构中。在客户端,BPC理着SPIQƈ通过异步响应事g来处理与最l用户之 间的交互。在服务器端QBackbase XML Serverq个灉|的XML道可以q接CQ意服务器端的数据源,包括Web服务、文件、数据库或本地Java对象。图6说明了BPC和BXS如何共同 为RIA提供一个声明式的、基于XML的端到端表示层?

?. 声明式的端到端表C层

Backbase表示客户?/strong>

  BPC是一个基于Ajax的GUI引擎Q它q行在标准的Web览器中。运行时QBPC被加载到览器中Q然后它会接收BXML代码Q构造对应的B树,q不断地把这U表C{换ؓ览器所呈现的DOM树。图7说明了运行时转换q程?

?. BPCq行?/p>

Backbase XML

  Backbase XML (BXML)是XHTML的扩展。开发h员通过创徏BXML应用E序来开发富前端Q包括BXML标签、标准的XHTML和CSS。BXML是一U声明性语aQ它包含了XHTML中所没有的标{(B标签Q?/p>

  BXML包含用于下列用途的标签Q?/p>

  • 定义屏幕分区(<b:panel>)
  • 交互式客L控制(<b:menu>)
  • 处理标准的用户交互事?onClick)
  • 处理高的用户交互事?拖放和调整大?
  • 理客户端状?/li>
  • 处理可视化效?使修改Q意CSS属性的q程动画?
  • 数据l定
  • 使用XSLT的一个子集进行客L转换

用于J2EE的Backbase XML Server

  Backbase XML Server (BXS)是一个服务器端的引擎Q用于把BPC链接CQ意J2EE后端。和BPC一PBXS是完全基于XML的,其编E是声明性的。它使用一UXML道架构Q提供功能强大的服务器端转换和聚合?/p>

  BXS附带一些用于访问最常用的数据源Q包括Web服务、数据库、文件系l和本地Java对象Q的开即用Q务。我们用Backbase标签对从q些源获得的数据q行聚合Q然后用XSLTq行转换。结果以无格式XML数据或BXML表示代码的Ş式返回给BPC?/p>

  BXSq提供一些应用服务,包括w䆾验证、授权、日志记录和用户跟踪。图8昄了BXS的M架构?/p>

?. BXS架构

Eclipse开发工?/strong>

  Z让J2EE开发h员可以只使用一U开发工具就能创建完整的Web应用E序Q包括富前端QBackbase提供了一个Eclipse插g。如?所C,该插件提供了在Eclipse中突出显C法和Backbase标签代码自动完成的功能?

?. Backbase Eclipse插g

  注意QEclipse的可视化拖放开发插件还处在开发阶Dc?/p>

部v到BEA WebLogic

  BXS是一个与标准兼容的J2EE应用E序Q可以将光|到MJ2EE应用服务器上。图10昄了如何用WebLogic控制台把BXS部v?a target="_blank">BEA WebLogic Server?

?0. 把BXS部v到BEA WebLogic

实现Backbase RIA Pet Store

  下面的顺序图包括更多详细信息Q可以帮助您更好地理解如何实现Backbase pet store。该序图显CZ在应用程序的初始化加载期间BPC与BXS之间的交互,如图11所C,它包括以?个步骤:

  • 初始化:用户在浏览器中输入宠物商店的URLQ对BPCq行初始化?/li>
  • 应用E序布局Q触发正在构造的事gQBPC构徏整体应用E序布局Q宠物类别被加蝲q显C在选项卡中?/li>
  • 默认数据Q默认情况下加蝲狗的cdQ最初显C?张狗的图片,q带有向?向后和排序功能?/li>

  用户交互Q用L击Next按钮便可昄~号??6的狗囄?

?1.序图:富商店前?/p>

  • 初始?/li>

    从用户在览器中输入宠物商店的URL开始,q将D从Web服务器请求一个烦引页面?/p>

    索引面包含用于实例化BPC的代码。烦引页面是XHTML和BXML标签的结合,包含负责启动富前端的初始化事件处理程序?/p>

    BPC初始化代码:

    <...><body onload="bpc.boot('/Backbase/')">

    <...>

    <xmp b:backbase="true"

    style="display:none;height:100%;">

    <s:loading>

    <div style="position:absolute;width:20%;

    top: 50px;left: 35%;">

    <center>Please wait while loading...

    </center>

    </div>

    </s:loading>

    <...>

    <!-- Include petshop specific behaviors -->

    <s:include b:url="petshop.xml"/>
  • 应用E序布局
  • 加蝲面之后QBPC׃处理正在构造的事gQ以便开始构建M的应用程序布局?/p>

    应用E序布局由几个面板组成,它们屏q划分ؓ几个部分。顶行有一个固定高度的宠物商店徽标Q接下来的主行是实际的商店,大小可以调整。主行分Z列,左边一列是产品cdQ右边一列是购物车和历史记录?/p> 产品cd使用选项卡式的导航,每个宠物cd一个选项卡。这些选项卡是动态构造的Q具体过E是通过BXS从一个XML文g加蝲cdQ然后通过一个客L模板把这些类别{换ؓ选项卡,该{换模板的BPC代码如下Q?

    <s:task b:action="transform"

    b:stylesheet="b:xml('categories')"

    b:xmldatasource="b:url('categories.xml')"

    b:destination="id('main-content')"

    b:mode="aslastchild" />

    下面是用于从文gpȝ把类别加载ؓXML的BXS代码Q?/p>

    <bsd:pipeline equals="categories.xml"

    access="public">

    <bsd:readxml input="file:/categories.xml"/>

    </bsd:pipeline>

    下面是用于创建选项卡式D的BPC客户端模板:

    <b:tabrow>

    <s:for-each b:select="categories/category">

    <b:tab>

    <s:attribute b:name="b:followstate">

    id('<s:value-of b:select="name"/>')

    </s:attribute>

    <s:value-of b:select="name"/>

    </b:tab>

    </s:for-each>

    </b:tabrow>

    所有BPC代码Q用蓝色表示Q都在客L执行Q而所有BXS代码Q用U色表示Q都在服务器端执行。注意,在本例中Q我选择了在客户端进行{换,因ؓ 数据集很。下面我会给Z个在服务器端转换的例子。两U{换都要用到XSLT语法。Backbase的一个强大功能就是,前端开发h员可以根据情况选择 在客Lq是服务器端处理表示逻辑。语法似乎允许轻村֜把代码从客户端移到服务器端,或者反之?/p>

    以上的代码示例应该可以您了解到Q借助于BackbaseQAjax~程变得多么L。结合了DHTML的声明性方法则更容易上手。用附加的B 标签不仅可以使界面更加丰富,而且可以使开发h员的效率更高。诸?lt;b:tab>之类的单个标{֏以代替多行HTML和JavaScript 代码Q而且保证可以用于各种览器?/p>

  • 默认数据
  • 昄商店前端Ӟ默认情况下显C的是狗的类别。对于本案例QBXS负责此项操作。BXS从一个Web服务获得数据Q将其放入缓存,然后生成BXML 表示代码Q再把这些表CZ码发回给BPC。服务器q通过一w|设|确定一个页面上可以昄的动物数量,q根据需要加入了Next和Previous? 钮。最后,服务器还提供了按照名U或hq行排序的功能?/p>

    下面的代码片断演CZ服务器功能。外部管道products-overview.xml首先调用catalog.xml子管道。该子管道要么返回缓 存中的宠物信息,要么调用另一个子道catalog.ws。在~存没有命中的情况下Q内部管道catalog.ws会从Web服务获取宠物信息?/p>

    外部道获得宠物信息Q然后进行XSLT转换Q从而以4x2表格昄q些信息Qƈ带有Next和Previouse按钮Q然后把BXML格式的代码发回给BPC。BPC呈现它接收到的BXML?/p>

    ?个嵌套的BXS道分别用于从Web服务获取数据、将其放入缓存,以及通过XSLT转换创徏BXML输出Q?

    <bsd:pipeline equals="products-overview.xml"

    access="public"/>

    <bsd:callpipe pipe="catalog.xml"/>
    <bsd:pipeline equals="catalog.xml" access="private">

    <bsd:exist field="{global:petstore-catalog}">

    <bsd:readxml>{global:petstore-catalog}

    </bsd:readxml>

    <bsd:otherwise>

    <bsd:callpipe pipe="catalog.ws"/>
    <bsd:pipeline equals="catalog.ws"

    access="private">

    <bsd:try>

    <bsd:callws wsdl="PetstoreCatalog.wsdl"

    method="getAll"/>

    <bsd:callpipe pipe="strip-root-ns"/>

    <bsd:catch>

    <bsd:xslt xslt="error.xslt">

    <bsd:param name="errormsg">{error:message}

    </bsd:param>

    <bsd:param name="errorsrc">{error:source}

    </bsd:param>

    </bsd:xslt>

    </bsd:catch>

    </bsd:try>

    </bsd:pipeline>
    <bsd:writexml>{global:petstore-catalog}

    </bsd:writexml>

    </bsd:otherwise>

    </bsd:exist>

    </bsd:pipeline>
    <bsd:extractfilter xpath=

    "category[name/text()='{requestparam:category}']"/>

    <bsd:xslt xslt="products/products-overview.xslt">

    <bsd:param name="category">

    {requestparam:category}

    </bsd:param>

    <bsd:param name="stepsize">

    {global:stepsize}

    </bsd:param>

    <bsd:param name="sortorder">

    {requestparam:sortorder}

    </bsd:param>

    <bsd:param name="sortfield">

    {requestparam:sortfield}

    </bsd:param>

    </bsd:xslt>

    </bsd:pipeline>

    代码CZ再次清楚地说明了Q借助于BackbaseQ以声明性的方式创徏Ajax前端是多么容易的事情。例如,只要使用带有一个WSDL引用作ؓ属性的<bsd:callws>标签Q就可以调用一个Web服务?/p>

  • 用户交互
  • 现在Q最l用户可以与宠物商店cdq行交互。可以用Next或Previous按钮或者排序功能在动物cd中进行浏览。或者,只要点击一下相应的选项卡,可以{到另一个类别中?/p>

    BPC和BXS对这U交互进行了无缝处理。显C已l在客户端上的数据时Q无需与服务器q行M通信。例如,购物者已l从狗类别{C猫类别,然后? 回到狗类别。客L仍然拥有狗类别的数据Q所以可以马上显C出来,q得购物体验变得更完美。其他的cd需要从BXS获取。BXS要么立即从其~存q回? 们,要们讉KWeb服务来获得新数据?/p>

  Z详细说明Backbase Ajax宠物商店的实玎ͼ我把重点攑֜了初始化的步骤上。完整的宠物商店Q可以从http://www.backbase.com/xmlserver下蝲Q还包括以下功能Q?/p>

    • 商店前端
      • 初始化?/li>
      • 使用从文件加载的宠物cd创徏选项卡?/li>
      • 默认情况下从Web服务加蝲Dog选项卡?/li>
      • 通过~存览Dogq对其进行排序?/li>
    • 宠物详细情况
      • 使用跟踪聚合来自~存和数据库的宠物详l情c?/li>
      • 创徏可视化历史记录?/li>
    • 购物?/li>
      • 使用跟踪d到购物R?/li>
    • d
      • d和n份验证?/li>
    • 退?/li>
      • 退出和授权?/li>
      • 认?/li>

l束?/strong>

  最q有很多人都在研IAjax。Ajax的优点已l在实践中得C证明。定制Ajax的缺点在于它的复杂性和不兼Ҏ。大量客L JavaScript的出现意味着开发h员很可能陷入到浏览器实现差别的惔潭中厅R另外,JavaScriptq种语言不适用于复杂的应用E序?/p>

  Z开发易于管理的、可伸羃的和适应未来变化的Ajax解决ҎQ开发h员所需使用的工具应该具有比定制部g开发更多的功能。Backbase Ajax软g提供了一个功能全面的客户端GUI理引擎(Backbase Presentation Client)、一个灵zȝ服务器端XML道(Backbase XML Server)和一U声明性的Z标签的UI语言QBXML(Backbase eXtensible Markup Language)。该Ҏh几个优点?/p>

  首先QBackbae易于使用。它的声明性语a水^地扩展了DHTMLQ它完全对开发h员隐藏了览器兼Ҏ的问题Q而且它带有一套开发和调试工具?/p>

  其次QBackbase是一个功能全面的Ajax GUI理pȝ。Backbase的先q性大大超q了其他Ajax框架Q它完全把重Ҏ在提供一个部件库或客LQ服务器通信Q如DWRQ上。在控g和客 LQ服务器通信的基上,Backbase提供了用于如下用途的标签Q提供电影效果,随需应变的数据加载,数据l定和客L的数据{换,对于Back? Forward按钮的支持,完善的GUI状态管理,{等。所有这些功能对于目前的Ajax Web应用E序来说都是必需的?/p>

  最后,Backbase是以兼容的方式提供所有客L和服务器端的功能。用户可以用富Ajax前端扩展现有的应用程序,同时无需修改后端。对于整个表C层来说Q它的架构是时新的、模块化的,而且它基于XML?/p>

参考资?/strong>

原文出处

A Backbase Ajax Front-end for J2EE Applications

http://dev2dev.bea.com/pub/a/2005/08/backbase_ajax.html

 作者简?/span>

Mark Schiefelbein?005q?月以来一直担任Backbase的品管理主。Mark极大地推动了Backbase Rich Internet Application的全球推qѝ?/td>


Dion 2005-11-23 20:31 发表评论
]]>
[转蝲]AJAX开发简略箋一http://m.tkk7.com/ericwang/archive/2005/11/23/21177.htmlDionDionWed, 23 Nov 2005 12:28:00 GMThttp://m.tkk7.com/ericwang/archive/2005/11/23/21177.htmlhttp://m.tkk7.com/ericwang/comments/21177.htmlhttp://m.tkk7.com/ericwang/archive/2005/11/23/21177.html#Feedback0http://m.tkk7.com/ericwang/comments/commentRss/21177.htmlhttp://m.tkk7.com/ericwang/services/trackbacks/21177.html阅读全文

Dion 2005-11-23 20:28 发表评论
]]>
[转蝲]《AJAX开发简略》配文代?/title><link>http://m.tkk7.com/ericwang/archive/2005/11/23/21176.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Wed, 23 Nov 2005 12:26:00 GMT</pubDate><guid>http://m.tkk7.com/ericwang/archive/2005/11/23/21176.html</guid><wfw:comment>http://m.tkk7.com/ericwang/comments/21176.html</wfw:comment><comments>http://m.tkk7.com/ericwang/archive/2005/11/23/21176.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ericwang/comments/commentRss/21176.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ericwang/services/trackbacks/21176.html</trackback:ping><description><![CDATA[ <p>原文Qhttp://m.tkk7.com/eamoi/archive/2005/11/01/17639.html<br> <br> </p> <p>有网友反映说《AJAX开发简略》配文代码不全。其实应该是全的Q只是要把包括框架和两个CZ的程序都整合h看。这里把全部的代码脓出来Q需要的朋友可以看看?br>sample1_1.jspQ?br><%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %><br><html><br><head><br><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><br><title>无标题文?lt;/title><br><script language="javascript"><br> var http_request = false;<br> function send_request(url) {//初始化、指定处理函数、发送请求的函数<br>  http_request = false;<br>  //开始初始化XMLHttpRequest对象<br>  if(window.XMLHttpRequest) { //Mozilla 览?br>   http_request = new XMLHttpRequest();<br>   if (http_request.overrideMimeType) {//讄MiMEcd<br>    http_request.overrideMimeType('text/xml');<br>   }<br>  }<br>  else if (window.ActiveXObject) { // IE览?br>   try {<br>    http_request = new ActiveXObject("Msxml2.XMLHTTP");<br>   } catch (e) {<br>    try {<br>     http_request = new ActiveXObject("Microsoft.XMLHTTP");<br>    } catch (e) {}<br>   }<br>  }<br>  if (!http_request) { // 异常Q创建对象实例失?br>   window.alert("不能创徏XMLHttpRequest对象实例.");<br>   return false;<br>  }<br>  http_request.onreadystatechange = processRequest;<br>  // 定发送请求的方式和URL以及是否同步执行下段代码<br>  http_request.open("GET", url, true);<br>  http_request.send(null);<br> }<br> // 处理q回信息的函?br>    function processRequest() {<br>        if (http_request.readyState == 4) { // 判断对象状?br>            if (http_request.status == 200) { // 信息已经成功q回Q开始处理信?br>                alert(http_request.responseText);<br>            } else { //面不正?br>                alert("您所h的页面有异常?);<br>            }<br>        }<br>    }<br> function userCheck() {<br>  var f = document.form1;<br>  var username = f.username.value;<br>  if(username=="") {<br>   window.alert("用户名不能ؓI?);<br>   f.username.focus();<br>   return false;<br>  }<br>  else {<br>   send_request('sample1_2.jsp?username='+username);<br>  }<br> }<br></script><br><link href="css/style.css" rel="stylesheet" type="text/css"><br></head></p> <p><body><br><form name="form1" action="" method="post"><br>用户名:<input type="text" name="username" value="">&nbsp;<br><input type="button" name="check" value="唯一性检? onClick="userCheck()"><br><input type="submit" name="submit" value="提交"><br></form><br><!--span style="cursor: pointer; text-decoration: underline" onclick="send_request('2.jsp?username=educhina')">Send a request</span--><br></body><br></html><br><br>sample1_2.jspQ?br><%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %><br><%<br>String playPos = request.getParameter("playPos");<br>if("pos_1".equals(playPos)) out.print("用户名已l被注册Q请更换一个用户名?);<br>else out.print("用户名尚未被使用Q您可以l箋?);<br>%><br><br>sample2_1.jspQ?br><%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %><br><html><br><head><br><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><br><title>无标题文?lt;/title><br><script language="javascript"><br> var http_request = false;<br> var currentPos = null;<br> function send_request(url) {//初始化、指定处理函数、发送请求的函数<br>  http_request = false;<br>  //开始初始化XMLHttpRequest对象<br>  if(window.XMLHttpRequest) { //Mozilla 览?br>   http_request = new XMLHttpRequest();<br>   if (http_request.overrideMimeType) {//讄MiMEcd<br>    http_request.overrideMimeType('text/xml');<br>   }<br>  }<br>  else if (window.ActiveXObject) { // IE览?br>   try {<br>    http_request = new ActiveXObject("Msxml2.XMLHTTP");<br>   } catch (e) {<br>    try {<br>     http_request = new ActiveXObject("Microsoft.XMLHTTP");<br>    } catch (e) {}<br>   }<br>  }<br>  if (!http_request) { // 异常Q创建对象实例失?br>   window.alert("不能创徏XMLHttpRequest对象实例.");<br>   return false;<br>  }<br>  http_request.onreadystatechange = processRequest;<br>  // 定发送请求的方式和URL以及是否同步执行下段代码<br>  http_request.open("GET", url, true);<br>  http_request.send(null);<br> }<br> // 处理q回信息的函?br>    function processRequest() {<br>        if (http_request.readyState == 4) { // 判断对象状?br>            if (http_request.status == 200) { // 信息已经成功q回Q开始处理信?br>                //alert(http_request.responseText);<br>    document.getElementById(currentPos).innerHTML = http_request.responseText;<br>            } else { //面不正?br>                alert("您所h的页面有异常?);<br>            }<br>        }<br>    }<br> //昄部门下的岗位<br> function showRoles(obj) {<br>  document.getElementById(obj).parentNode.style.display = "";<br>  document.getElementById(obj).innerHTML = "正在d数据..."<br>  currentPos = obj;<br>  send_request("sample2_2.jsp?playPos="+obj);<br> }<br></script><br><link href="css/style.css" rel="stylesheet" type="text/css"><br></head></p> <p><body><br><table width="200" border="0" cellspacing="0" cellpadding="0"><br>    <tr><br>        <td height="20"><a href="javascript:void(0)" onClick="showRoles('pos_1')">l理?lt;/a></td><br>    </tr><br>    <tr style="display:none"><br>        <td height="20" id="pos_1">&nbsp;</td><br>    </tr><br>    <tr><br>        <td height="20"><a href="javascript:void(0)" onClick="showRoles('pos_2')">开发部</a></td><br>    </tr><br>    <tr style="display:none "><br>        <td id="pos_2" height="20">&nbsp;</td><br>    </tr><br></table><br><!--a href="javascript:void(0)" onClick="showRoles('pos_1')">试</a--><br><!--span style="cursor: pointer; text-decoration: underline" onclick="send_request('2.jsp?username=educhina')">Send a request</span--><br></body><br></html><br><br>sample2_2.jspQ?br><%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %><br><%<br>String playPos = request.getParameter("playPos");<br>if("pos_1".equals(playPos)) out.print("&nbsp;&nbsp;ȝ?lt;br>&nbsp;&nbsp;副ȝ?);<br>else if("pos_2".equals(playPos)) out.println("&nbsp;&nbsp;dE师<br>&nbsp;&nbsp;软g工程?);<br>%></p> <img src ="http://m.tkk7.com/ericwang/aggbug/21176.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ericwang/" target="_blank">Dion</a> 2005-11-23 20:26 <a href="http://m.tkk7.com/ericwang/archive/2005/11/23/21176.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转蝲]AJAX开发简?/title><link>http://m.tkk7.com/ericwang/archive/2005/11/23/21175.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Wed, 23 Nov 2005 12:25:00 GMT</pubDate><guid>http://m.tkk7.com/ericwang/archive/2005/11/23/21175.html</guid><wfw:comment>http://m.tkk7.com/ericwang/comments/21175.html</wfw:comment><comments>http://m.tkk7.com/ericwang/archive/2005/11/23/21175.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ericwang/comments/commentRss/21175.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ericwang/services/trackbacks/21175.html</trackback:ping><description><![CDATA[     摘要: http://m.tkk7.com/eamoi/archive/2005/10/31/17489.html AJAX开发简?   文档说明   参与人员Q?   作? |名 联络 柯自? eamoi   educhina ...  <a href='http://m.tkk7.com/ericwang/archive/2005/11/23/21175.html'>阅读全文</a><img src ="http://m.tkk7.com/ericwang/aggbug/21175.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ericwang/" target="_blank">Dion</a> 2005-11-23 20:25 <a href="http://m.tkk7.com/ericwang/archive/2005/11/23/21175.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ajax?/title><link>http://m.tkk7.com/ericwang/archive/2005/11/23/21114.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Wed, 23 Nov 2005 04:53:00 GMT</pubDate><guid>http://m.tkk7.com/ericwang/archive/2005/11/23/21114.html</guid><wfw:comment>http://m.tkk7.com/ericwang/comments/21114.html</wfw:comment><comments>http://m.tkk7.com/ericwang/archive/2005/11/23/21114.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ericwang/comments/commentRss/21114.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ericwang/services/trackbacks/21114.html</trackback:ping><description><![CDATA[转自http://dev2dev.bea.com.cn/techdoc/2005110103.html<br> <br> <br> <span id="hrdzdtl" class="h1b">Ajax?/span><br> <br> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody><tr> <td height="64">旉Q?005-11-01<br> 作者:<a >David Teare</a><br> 览ơ数Q? <script language="JavaScript" type="text/JavaScript" src="http://203.81.25.103/cgi-bin/beadevcount.cgi?d_id=681"></script>1786 <br> 本文关键字:<a >ajax</a>, <a >dhtml</a>, <a >dwr</a>, <a > javascript</a></td> <td><table class="box_content" border="0" cellpadding="0" cellspacing="0"> <tbody><tr> <td><span id="bxvrtll" class="h2b">文章工具</span><br> <img src="http://dev2dev.bea.com.cn/images/letter001.gif" alt="推荐l朋? align="middle" height="10" width="19"> <a href="javascript:sendmail()">推荐l朋?/a><br> <img src="http://dev2dev.bea.com.cn/images/print001.gif" alt="打印文章" align="middle" height="18" width="19"> <a href="javascript:window.print()">打印文章</a></td> </tr> </tbody></table></td> </tr> </tbody> </table> <!-- 提取技术文?--> <div id="tnrvhxx" class="beas"><img src="http://dev2dev.bea.com.cn/images/dot6B6B6B.gif" alt="" height="1" width="100%"></div> <p>  作ؓJ2EE开发h员,我们gl常x“后端机Ӟbackend mechanicsQ”。我们通常会忘讎ͼJ2EE的主要成功之处在Web应用E序斚wQ许多原因得h们喜Ƣ利用Web开发应用程序,但主要还是因为其 易于部v的特点允许站点以可能低的成本拥有上百万的用戗遗憄是,在过dq中Q我们在后端投入了太多的旉Q而在使我们的Web用户界面对用戯? 和响应灵敏方面却投入不?/p> <p>  本文介绍一U方法,AjaxQ用它可以构徏更ؓ动态和响应更灵敏的Web应用E序。该Ҏ的关键在于对览器端的JavaScript? DHTML和与服务器异步通信的组合。本文也演示了启用这U方法是多么单:利用一个Ajax框架Q指DWRQ构造一个应用程序,它直接从览器与后端? 务进行通信。如果用得当,q种强大的力量可以应用E序更加自然和响应灵敏,从而提升用L览体验?/p> <p>  该应用程序中所使用的示例代码已打包为单独的WAR文gQ可供下载?/p> <p><strong>?/strong></p> <p>  术语Ajax用来描述一l技术,它ɋ览器可以ؓ用户提供更ؓ自然的浏览体验。在Ajax之前QWeb站点强制用户q入提交/{待/重新昄? 例,用户的动作L与服务器的“思考时间”同步。Ajax提供与服务器异步通信的能力,从而用户从请?响应的@环中解脱出来。借助于AjaxQ可以在 用户单击按钮Ӟ使用JavaScript和DHTML立即更新UIQƈ向服务器发出异步hQ以执行更新或查询数据库。当hq回Ӟ可以? JavaScript和CSS来相应地更新UIQ而不是刷新整个页面。最重要的是Q用L至不知道览器正在与服务器通信QWeb站点看v来是x响应 的?/p> <p>  虽然Ajax所需的基架构已经出现了一D|_但直到最q异步请求的真正威力才得到利用。能够拥有一个响应极其灵敏的Web站点实Ȁ动h 心,因ؓ它最l允许开发h员和设计人员使用标准的HTML/CSS/JavaScript堆栈创徏“桌面风格的Qdesktop-likeQ”可用性?/p> <p>  通常Q在J2EE中,开发h员过于关注服务和持久性层的开发,以至于用L面的可用性已l落后。在一个典型的J2EE开发周期中Q常怼听到q样的话Q“我们没有可投入UI的时间”或“不能用HTML实现”。但是,以下Web站点证明Q这些理由再也站不住脚了Q?/p> <ul> <li><a target="_blank">BackPack</a></li><li><a target="_blank">Google Suggest</a></li><li><a target="_blank">Google Maps</a></li><li><a target="_blank">PalmSphere</a></li> </ul> <p>  所有这些Web站点都告诉我们,Web应用E序不必完全依赖于从服务器重新蝲入页面来向用户呈现更攏V一切似乎就在瞬间发生。简而言之,在涉及到用户界面的响应灵敏度Ӟ基准讑־更高了?/p> <p><strong>定义Ajax</strong></p> <p>  Adaptive Path公司的Jesse James Garrettq样<a target="_blank">定义Ajax</a>Q?/p> <p>  Ajax不是一U技术。实际上Q它由几U蓬勃发展的技术以新的强大方式l合而成。Ajax包含Q?/p> <ul> <li>Z<a target="_blank">XHTML</a>?a target="_blank">CSS</a>标准的表C;</li><li>使用<a target="_blank">Document Object Model</a>q行动态显C和交互Q?/li><li>使用XMLHttpRequest与服务器q行异步通信Q?/li><li>使用JavaScriptl定一切?/li> </ul> <p>  q非常好Q但Z么要以Ajax命名呢?其实术语Ajax是由Jesse James Garrett创造的Q他说它是“Asynchronous JavaScript + XML的简写”?/p> <p><strong>Ajax的工作原?/strong></p> <p>  Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首ơ引入,它是一U支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出hq处理响应,而不 d用户?/p> <p>  在创建Web站点Ӟ在客L执行屏幕更新为用h供了很大的灵zL。下面是使用Ajax可以完成的功能:</p> <ul> <li>动态更新购物R的物品LQ无需用户单击Updateq等待服务器重新发送整个页面?/li><li>提升站点的? 能,q是通过减少从服务器下蝲的数据量而实现的。例如,在Amazon的购物R面Q当更新子中的一物品的数量Ӟ会重新蝲入整个页面,q必M? 32K的数据。如果用Ajax计算新的总量Q服务器只会q回新的总量|因此所需的带宽仅为原来的癑ֈ之一?/li><li>消除了每ơ用戯入时的页面刷新。例如,在Ajax中,如果用户在分列表上单击NextQ则服务器数据只h列表而不是整个页面?/li><li>直接~辑表格数据Q而不是要求用户导航到新的面来编辑数据。对于AjaxQ当用户单击EditӞ可以静态表格刷Cؓ内容可编辑的表格。用户单击Done之后Q就可以发出一个Ajaxh来更新服务器Qƈh表格Q其包含静态、只ȝ数据?/li> </ul> <p>  一切皆有可能!但愿它能够激发您开始开发自qZAjax的站炏V然而,在开始之前,让我们介l一个现有的Web站点Q它遵@传统的提?{待/重新昄的范例,我们q将讨论Ajax如何提升用户体验?/p> <p><strong>Ajax可用于那些场景?——一个例子:MSN Money面</strong></p> <p>  前几天,在浏览MSN Money面的时候,有一?a target="_blank">关于房地产投资的文章</a>引v了我的好奇心。我军_使用站点的“Rate this article”(评h本文Q功能,鼓励其他的用戯一Ҏ间来阅读q篇文章。在我单击vote按钮q等待了一会儿之后Q整个页面被hQ在原来投票问题所在的地方出现了一个漂亮的感谢画面?/p> <p> <img src="http://dev2dev.bea.com.cn/images/051101/0511010101.jpg" height="63" width="303"> </p> <p>  而Ajax能够使用L体验更加愉快Q它可以提供响应更加灉|的UIQƈ消除面h所带来的闪烁。目前,׃要刷新整个页面,需要传送大量的 数据Q因为必重新发送整个页面。如果用AjaxQ服务器可以q回一个包含了感谢信息?00字节的消息,而不是发?6,813字节的消息来h整个 面。即使用的是高速InternetQ传?6K?/2K的差别也非常大。同样重要的是,只需要刷C投票相关的一节Q而不是刷新整个屏q?/p> <p>  让我们利用Ajax实现自己的基本投系l?/p> <p><strong>原始的AjaxQ直接用XmlHttpRequest</strong></p> <p>  如上所qͼAjax的核心是JavaScript对象XmlHttpRequest。下面的CZ文章评hpȝ带您熟悉Ajax的底层基本知识:<a target="_blank">http://tearesolutions.com/ajax-demo/raw-ajax.html</a>。注Q如果您已经在本地WebLogic容器中安装了<a >ajax-demo.war</a>Q可以导航到<a href="http://localhost:7001/ajax-demo/raw-ajax.html" target="_blank">http://localhost:7001/ajax-demo/raw-ajax.html</a>Q?/p> <p>  览应用E序Q参与投,q亲眼看它如何运转。熟悉了该应用程序之后,l箋阅读Q进一步了解其工作原理l节?/p>   首先Q您拥有一些简单的定位Ҏ讎ͼ它连接到一个JavaScriptcastVote(rank)函数? <pre class="code">function castVote(rank) {<br> var url = "/ajax-demo/static-article-ranking.html";<br> var callback = processAjaxResponse;<br> executeXhr(callback, url);<br>}<br></pre> <p>  该函Cؓ您想要与之通信的服务器资源创徏一个URLq调用内部函数executeXhrQ提供一个回调JavaScript函数Q一旦服务器? 应可用,该函数就被执行。由于我希望它运行在一个简单的Apache环境中,“cast vote URL”只是一个简单的HTML面。在实际情况中,被调用的URL记录票数ƈ动态地呈现包含投票L的响应?/p>   下一步是发出一个XmlHttpRequesthQ? <pre class="code">function executeXhr(callback, url) {<br> // branch for native XMLHttpRequest object<br> if (window.XMLHttpRequest) {<br> req = new XMLHttpRequest();<br> req.onreadystatechange = callback;<br> req.open("GET", url, true);<br> req.send(null);<br> } // branch for IE/Windows ActiveX version<br> else if (window.ActiveXObject) {<br> req = new ActiveXObject("Microsoft.XMLHTTP");<br> if (req) {<br> req.onreadystatechange = callback;<br> req.open("GET", url, true);<br> req.send();<br> }<br> }<br>}<br><br></pre> <p>  如您所见,执行一个XmlHttpRequestq不单,但非常直观。和q_一P在JavaScript领域Q大部分的工作量都花在确保浏 览器兼容斚w。在q种情况下,首先要确定XmlHttpRequest是否可用。如果不能用Q很可能要用Internet ExplorerQ这样就要用所提供的ActiveX实现?/p> <p>executeXhr()Ҏ中最关键的部分是q两行: </p> <pre class="code">req.onreadystatechange = callback;<br>req.open("GET", url, true);<br></pre> <p>  W一行定义了JavaScript回调函数Q您希望一旦响应就l它p动执行,而req.open()Ҏ中所指定的“true”标志说明您惌异步执行该请求?/p>   一旦服务器处理完XmlHttpRequestq返回给览器,使用req.onreadystatechange指派所讄的回调方法将被自动调用? <pre class="code">function processAjaxResponse() {<br> // only if req shows "loaded"<br> if (req.readyState == 4) {<br> // only if "OK"<br> if (req.status == 200) {<br> 502 502'votes').innerHTML = req.responseText;<br> } else {<br> alert("There was a problem retrieving the XML data:<br>" +<br> req.statusText);<br> }<br> }<br>} <br></pre> <p>  该代码相当简z,q且使用了几个敎ͼq得难以一下子看出发生了什么。ؓ了弄清楚q一点,下面的表|引用?a target="_blank">http://developer.apple.com/internet/webcontent/xmlhttpreq.html</a>Q列举了常用的XmlHttpRequest对象属性?/p> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="1" width="80%"> <tbody><tr bgcolor="#ffffff"> <td height="22"><p><strong>属?/strong></p></td> <td><p><strong>描述</strong></p></td> </tr> <tr bgcolor="#ffffff"> <td height="22" valign="top"><p>onreadystatechange</p></td> <td valign="top"><p>每次状态改变所触发事g的事件处理程?/p></td> </tr> <tr bgcolor="#ffffff"> <td height="22" valign="top"><p>readyState</p></td> <td valign="top"><p>对象状态| </p><ul><li>0 = 未初始化QuninitializedQ?/li><li>1 = 正在加蝲QloadingQ?/li><li>2 = 加蝲完毕QloadedQ?/li><li>3 = 交互QinteractiveQ?/li><li>4 = 完成QcompleteQ?/li></ul></td> </tr> <tr bgcolor="#ffffff"> <td height="22" valign="top"><p>responseText</p></td> <td valign="top"><p>从服务器q程q回的数据的字符串Ş?/p></td> </tr> <tr bgcolor="#ffffff"> <td height="22" valign="top"><p>responseXML</p></td> <td valign="top"><p>从服务器q程q回的DOM兼容的文档数据对?/p></td> </tr> <tr bgcolor="#ffffff"> <td height="22" valign="top"><p>status</p></td> <td valign="top"><p>从服务器q回的数字代码,比如404Q未扑ֈQ或200Q就l)</p></td> </tr> <tr bgcolor="#ffffff"> <td height="22" valign="top"><p>statusText</p></td> <td valign="top"><p>伴随状态码的字W串信息</p></td> </tr> </tbody> </table> <p>  现在processVoteResponse()函数开始显C出其意义了。它首先查XmlHttpRequest的整体状态以保证它已l完? QreadyStatus == 4Q,然后Ҏ服务器的讑֮询问h状态。如果一切正常(status == 200Q?׃用innerHTML属性重写DOM的“votes”节点的内容?/p> <p>  既然您亲眼看CXmlHttpRequest对象是如何工作的Q就让我们利用一个旨在简化JavaScript与Java应用E序之间的异步通信的框架来对具体的l节q行抽象?/p> <p><strong>Ajax: DWR方式</strong></p> <p>  按照与文章评Ll相同的程Q我们将使用Direct Web RemotingQDWRQ框架实现同L功能?/p> <p>  假定文章和投结果存储在一个数据库中,使用某种对象/关系映射技术来完成抽取工作。ؓ了部|v来尽可能地简单,我们不会使用数据库进行持久? 存储。此外,Z应用E序可能通用Q也不用Web框架。相反,应用E序从一个静态HTML文g开始,可以认ؓ它由服务器动态地呈现。除了这些简化措 施,应用E序q应该用Spring Framework兌一切,以便L看出如何在一个“真实的”应用程序中使用DWR?/p> <p>  现在应该下蝲CZ应用E序q熟悉它。该应用E序被压~ؓ标准的WAR文gQ因此您可以把它攄CQ何一个Web容器中——无需q行配置。部|完毕之后,可以导航到<a href="http://localhost:7001/ajax-demo/dwr-ajax.html" target="_blank">http://localhost:7001/ajax_demo/dwr-ajax.html</a>来运行程序?/p> <p>  可以查看<a target="_blank">HTML 源代?/a>Q了解它如何工作。给人印象最q是,代码如此单——所有与服务器的交互都隐藏在JavaScript对象ajaxSampleSvc的后面。更加o人惊讶的是,ajaxSampleSvc服务不是由手工编写而是完全自动生成的!让我们l,看看q是如何做到的?/p> <p><strong>引入DWR</strong></p> <p>  如同在“原始的Ajax”一节所演示的那P直接使用XmlHttpRequest创徏异步h非常ȝ。不仅JavaScript代码冗长Q而且必须考虑服务器端为定位Ajaxh到适当的服务所需做的工作Qƈ结果封送到览器?/p> <p>  设计DWR的目的是要处理将Web面安装到后端服务上所需的所有信息管道。它是一个Java框架Q可以很L地将它插入到Web应用E序中, 以便JavaScript代码可以调用服务器上的服务。它甚至直接与Spring Framework集成Q从而允许用L接向Web客户机公开bean?/p> <p>  DWR真正的y妙之处是Q在用户配置了要向客h公开的服务之后,它用反来生成JavaScript对象Q以便Web面能够使用q些对象 来访问该服务。然后Web面只需接合到生成的JavaScript对象Q就像它们是直接使用服务一PDWR无缝地处理所有有关Ajax和请求定位的? 细节?/p> <p>  让我们仔l分析一下示例代码,弄清它是如何工作的?/p> <p><strong>应用E序l节QDWR分析</strong></p> <p>  关于应用E序Q首先要注意的是Q它是一个标准的Java应用E序Q用分层架构(Layered ArchitectureQ设计模式。用DWR通过JavaScript公开一些服务ƈ不媄响您的设计? </p> <p> <img src="http://dev2dev.bea.com.cn/images/051101/0511010102.jpg" height="344" width="209"> </p> <p>  下面是一个简单的Java服务Q我们将使用DWR框架直接其向JavaScript代码公开Q?/p> <pre class="code">package com.tearesolutions.service;<br><br>public interface AjaxSampleSvc { <br> Article castVote(int rank);<br>}<br></pre> <p>  q是一个被化到几乎不可能的E度的例子,其中只有一文章可以投。该服务由Spring理Q它使用的bean名是ajaxSampleSvcQ它的持久性需求则依赖于ArticleDao。详情请参见applicationContext.xml?/p> <p>  Z把该服务公开为JavaScript对象Q需要配|DWRQ添加dwr.xml文g到WEB-INF目录下: </p> <pre class="code"><?xml version="1.0" encoding="UTF-8"?><br><!DOCTYPE dwr PUBLIC<br> "-//GetAhead Limited//DTD Direct Web Remoting 0.4//EN"<br> "http://www.getahead.ltd.uk/dwr/dwr.dtd"><br> <br><dwr><br> <allow><br> <create creator="spring" javascript="ajaxSampleSvc"><br> <param name="beanName" value="ajaxSampleSvc" /><br> </create><br> <convert converter="bean" match="com.tearesolutions.model.Article"/><br> <exclude method="toString"/><br> <exclude method="setArticleDao"/><br> </allow><br></dwr><br></pre> <p>  dwr.xml文g告诉DWR哪些服务是要直接向JavaScript代码公开的。注意,已经要求公开Spring bean ajaxSampleSvc。DWR自动找到由应用E序讄的SpringApplicationContext。ؓ此,必须使用标准的servlet qo器ContextLoaderListener来初始化Spring ApplicationContext?/p>   DWR被设|ؓ一个servletQ所以把它的定义d到web.xmlQ? <pre class="code"><?xml version="1.0" encoding="UTF-8"?><br><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD <br> Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"><br><br><web-app><br> <display-name>Ajax Examples</display-name><br><br> <listener><br> <listener-class><br> org.springframework.web.context.ContextLoaderListener<br> </listener-class><br> </listener><br> <br> <servlet><br> <servlet-name>ajax_sample</servlet-name><br> <servlet-class>com.tearesolutions.web.AjaxSampleServlet</servlet-class><br> <load-on-startup>1</load-on-startup><br> </servlet><br><br> <servlet><br> <servlet-name>dwr-invoker</servlet-name><br> <display-name>DWR Servlet</display-name><br> <description>Direct Web Remoter Servlet</description><br> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class><br> <init-param><br> <param-name>debug</param-name><br> <param-value>true</param-value><br> </init-param><br> </servlet><br><br> <servlet-mapping><br> <servlet-name>ajax_sample</servlet-name><br> <url-pattern>/ajax_sample</url-pattern><br> </servlet-mapping><br><br> <servlet-mapping><br> <servlet-name>dwr-invoker</servlet-name><br> <url-pattern>/dwr/*</url-pattern><br> </servlet-mapping><br></web-app><br></pre> <p>   做完q些之后Q可以加?a href="http://localhost:7001/ajax-demo/dwr" target="_blank">http://localhost:7001/ajax-demo/dwr</a>Q看看哪些服务可用。结果如下:</p> <p><img src="http://dev2dev.bea.com.cn/images/051101/0511010103.jpg" height="102" width="305"></p> <p>?. 可用的服?/p>   单击ajaxSampleSvc链接Q查看有兛_何在HTML面内直接用服务的CZ实现。其中包含的两个JavaScript文g完成了大部分的功能: <pre class="code"><script type='text/javascript' <br> src='/ajax-demo/dwr/interface/ajaxSampleSvc.js'></script><br><script type='text/javascript' <br> src='/ajax-demo/dwr/engine.js'></script><br></pre> <p>ajaxSampleSvc.js是动态生成的Q?/p> <pre class="code">function ajaxSampleSvc() { }<br><br>ajaxSampleSvc.castVote = function(callback, p0)<br>{ <br> DWREngine._execute(callback, '/ajax-demo/dwr', <br> 'ajaxSampleSvc', 'castVote', p0);<br>}<br></pre> <p>  现在可以使用JavaScript对象ajaxSampleSvc替换所有的XmlHttpRequest代码Q从而重构raw-ajax.html文g。可以在dwr-ajax.html文g中看到改动的l果Q下面是新的JavaScript函数Q?/p> <pre class="code">function castVote(rank) {<br> ajaxSampleSvc.castVote(processResponse, rank);<br>}<br>function processResponse(data) {<br> var voteText = "<p><strong>Thanks for Voting!</strong></p>"<br> + "<p>Current ranking: " + data.voteAverage <br> + " out of 5</p>" <br> + "<p>Number of votes placed: " <br> + data.numberOfVotes + "</p>";<br> 502 502'votes').innerHTML = voteText; <br>}<br></pre> <p>  惊h地简单,不是吗?由ajaxSampleSvc对象q回的Article域对象序列化Z个JavaScript对象Q允许在它上面调用诸 如numberOfVotes()和voteAverage()之类的方法。在动态生成ƈ插入到DIV元素“votes”中的HTML代码内用这些数 据?/p> <p><strong>下一步工?/strong></p> <p>   在后l文章中Q我l有关Ajax的话题,涉及下面q些斚wQ?/p> <ul> <li>Ajax最佛_?/li> </ul> <p>  像许多技术一PAjax是一把双刃剑。对于一些用例,其应用程序其实没有必要用AjaxQ用了反而有损可用性。我介l一些不适合使用的模式,H出说明Ajax的一些消极方面,q展CZ些有助于~和q些消极斚w的机制。例如,?a >Netflix电媄览?/a>来说QAjax是合适的解决Ҏ吗?或者,如何提示用户实Z一些问题,而再ơ单L钮也无济于事Q?/p> <ul> <li>理跨请求的状?/li> </ul> <p>  在用AjaxӞ最初的文档DOM会发生一些变化,q且有大量的面状态信息存储在客户端变量中。当用户跟踪一个链接到应用E序中的另一个页面时Q状态就丢失了。当用户按照惯例单击Back按钮Ӟ呈现l他们的是缓存中的初始页面。这会用户感到非常qhQ?/p> <ul> <li>调试技?/li> </ul> <p>  使用JavaScript在客L执行更多的工作时Q如果事情不按预期方式进行,需要一些调试工h帮助弄清出现了什么问题?/p> <p><strong>l束?/strong></p> <p>  本文介绍了AjaxҎQƈ展示了如何用它来创Z个动态且响应灉|的Web应用E序。通过使用DWR框架Q可以轻村֜把Ajax融合到站点中Q而无需担心所有必L行的实际道工作?/p> <p>  特别感谢Getahead IT咨询公司的Joe Walker和他的团队开发出DWRq样奇的工兗感谢你们与世界׃n它!</p> <p><strong>下蝲</strong></p> <p>  本文中演C的应用E序源代码可供下载:<a target="_blank">ajax-demo.war</a>Q?.52 MBQ?/p> <p><strong>参考资?/strong></p> <ul> <li><a target="_blank">http://www.getahead.ltd.uk/dwr</a>——Getahead IT咨询公司?/li><li>Jesse James Garrett所撰写的?a target="_blank">Ajax: A New Approach to Web Applications</a>”(Adaptive PathQ?005q二月)?/li><li>?a target="_blank">Dynamic HTML and XML: The XMLHttpRequest Object</a>”(Apple Developer ConnectionQ?/li> </ul> <p><strong>原文出处</strong></p> <p>An Introduction To Ajax</p> <p><a target="_blank">http://dev2dev.bea.com/pub/a/2005/08/ajax_introduction.html</a> </p> <br> <img src ="http://m.tkk7.com/ericwang/aggbug/21114.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ericwang/" target="_blank">Dion</a> 2005-11-23 12:53 <a href="http://m.tkk7.com/ericwang/archive/2005/11/23/21114.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Java2q_企业版中应用异步JavaScript技术和XMLQAJAXQ?/title><link>http://m.tkk7.com/ericwang/archive/2005/11/23/21108.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Wed, 23 Nov 2005 03:43:00 GMT</pubDate><guid>http://m.tkk7.com/ericwang/archive/2005/11/23/21108.html</guid><wfw:comment>http://m.tkk7.com/ericwang/comments/21108.html</wfw:comment><comments>http://m.tkk7.com/ericwang/archive/2005/11/23/21108.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://m.tkk7.com/ericwang/comments/commentRss/21108.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ericwang/services/trackbacks/21108.html</trackback:ping><description><![CDATA[     摘要: 在Java2q_企业版中应用异步JavaScript技术和XMLQAJAXQ? ...  <a href='http://m.tkk7.com/ericwang/archive/2005/11/23/21108.html'>阅读全文</a><img src ="http://m.tkk7.com/ericwang/aggbug/21108.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ericwang/" target="_blank">Dion</a> 2005-11-23 11:43 <a href="http://m.tkk7.com/ericwang/archive/2005/11/23/21108.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://516kd.com" target="_blank">ѹ߹ۿӰԺ</a>| <a href="http://ywjh666.com" target="_blank">91ѽ</a>| <a href="http://yy12345.com" target="_blank">ëƬѹۿվ</a>| <a href="http://www-840012.com" target="_blank">޸Դ߹ۿ</a>| <a href="http://wuhhz.com" target="_blank">һ </a>| <a href="http://wwwjjz.com" target="_blank">պѸһëƬ</a>| <a href="http://zhaosifuwang.com" target="_blank">޹˾Ʒվ</a>| <a href="http://kk600700.com" target="_blank">114ëƬѹۿ</a>| <a href="http://whdysdt.com" target="_blank">޻ɫƵ</a>| <a href="http://www-993789.com" target="_blank">ɫַѴȫ</a>| <a href="http://6006284.com" target="_blank"> ˬ AVˬ</a>| <a href="http://ebanyou.com" target="_blank">Ůڵվ</a>| <a href="http://bjbanjia01.com" target="_blank">337Pձŷ޴ͼ </a>| <a href="http://zf91.com" target="_blank">avƷɫҹĻ </a>| <a href="http://58rjz.com" target="_blank">ŷһ</a>| <a href="http://6878vip.com" target="_blank">þþѹۿ</a>| <a href="http://yzddcpj.com" target="_blank">AV</a>| <a href="http://www-75044.com" target="_blank">޾Ʒ99þþþĻ</a>| <a href="http://www6yg6yg.com" target="_blank">Ѹþ</a>| <a href="http://abab14.com" target="_blank">޾Ʒþþþþþþþþþ </a>| <a href="http://lyaa17.com" target="_blank">hƬѹۿ</a>| <a href="http://91ptv.com" target="_blank">˾Ʒձר6</a>| <a href="http://91ptv.com" target="_blank">ĻӰԺַ</a>| <a href="http://gs168sz.com" target="_blank">ŮƵaƵȫվһ</a>| <a href="http://456jjj.com" target="_blank">ȸAV߲</a>| <a href="http://45-po.com" target="_blank">þþþùɫavѿ</a>| <a href="http://www1616hh.com" target="_blank">޵һ</a>| <a href="http://sewuji.com" target="_blank">޸Ʒһ</a>| <a href="http://4794d.com" target="_blank">˾69ƷƵ</a>| <a href="http://hkcp168.com" target="_blank">޳aƬ߹ۿ</a>| <a href="http://diswooo.com" target="_blank">һѿ</a>| <a href="http://simupiao.com" target="_blank">ѻɫƵ</a>| <a href="http://5656ys.com" target="_blank">޹Ƭ߹ۿ</a>| <a href="http://lanchenews.com" target="_blank">ƵvƬwww</a>| <a href="http://5gi555.com" target="_blank">߾Ʒһ㽶</a>| <a href="http://kkm55.com" target="_blank">ŷղҳ</a>| <a href="http://b2bautoparts.com" target="_blank">ƷҹѸ</a>| <a href="http://45-po.com" target="_blank">ҹѿƬڵ</a>| <a href="http://jyd56.com" target="_blank">һŷĻ</a>| <a href="http://zxbj0471.com" target="_blank">ۺϹƷһҳ</a>| <a href="http://625r.com" target="_blank">һëƬ߹ۿ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>