SlideShare a Scribd company logo
AJAX   的  client/server   溝通機制探究 馮彥文 隨想行動科技
講師介紹 馮彥文 隨想行動科技 Javaworld.tw :  tempo Email:  [email_address] Blog:  http:// www.pocketshark.com/blog/page/tempo
這個故事 ,  就從兩個技術人在一次研討會中的偶然相遇開始…
傑克 :   Hi  珍妮佛 , 你知道這個  session  最主要是講 ?
內容主題 AJAX 利用  AJAX  提高網站與使用者的互動性  (Rich Internet Application) User Interface: DHTML 非同步傳輸 : XMLHttpRequest (XHR)  與其他方式 ,  與他們的黑暗面 AJAX Framework 學習如何利用  DWR(Direct Web Remoting)   來簡化  AJAX  與  Java  間的網路存取 ,  且為網站增添更多功能 AJAX /  Reverse AJAX
我們的目標 即時股市報價 http:// www.marketwatch.com http://localhost:8080/dwr-reverse/before.jsp http://localhost:8080/dwr-reverse/after.jsp
我們的目標 Web  聊天室 http:// gabbly.com/http://www.pocketshark.com/blog/page/tempo / http://localhost:8080/dwr-chat/before.jsp http://localhost:8080/dwr-chat/after.jsp
What We Will Focus on Here Browser Compatibility,   Cross-Domains, Java Data Marshalling,   JSON , JSON-RPC,   DOJO,   DWR,  GWT,   iframe ,   Prototype,   Timeout & Error Handling,  Reverse AJAX,  History & Bookmarks,   scriptTag ,   Web Framework Integration,  XHR,  XML
AJAX  非同步傳輸 1:35
珍妮佛 :   什麼是  AJAX?  什麼又是非同步傳輸 ?
AJAX A synchronous J avaScript A nd X ML XHTML&CSS DOM JavaScript XMLHttpRequest AJAX = DHTML + XHR
Classic Web Applications From: http://adaptivepath.com/publications/essays/archives/000385.php
AJAX Web Applications From: http://adaptivepath.com/publications/essays/archives/000385.php
傑克 :   那我該如何利用  AJAX  存取遠端網站資料呢 ?
XHR(XMLHttpRequest) JavaScript  版的  HttpConnection 介面 open(string url,string asynch):  開啟網頁 send(string):  傳送資料 onreadystatechange :  狀態改變回呼函式 status: HTTP  狀態 responseXML :  回傳的  XML DOM responseText :  回傳的文字內容
XHR 使用者輸入觸動  XHR //  建立  XHR request = new XMLHttpRequest(); //  設定回呼函式 request. onreadystatechange =handleResponse; //  開啟連結 request. open ("GET","http://abc.com",true); //  傳送資料 request. send (null);
XHR 接收資料後立刻更新 UI function handleResponse () { //  檢查  XHR  狀態 if(request. readyState  == 4){ //  檢查  http  狀態 if(request. status  == 200){ //  讀取回傳  XML  資料 var doc = request. responseXML ; //  取得網頁上需被更新的  node  位置 var node = document. getElementById (“resp"); //  設定該  node  的內容 node. innerHTML  = doc.documentElement.childNodes[0].nodeValue; } } }
DEMO: Hello World http://localhost:8080/xhr/index.jsp
Tips & Tricks about XHR 1:40
珍妮佛 :   傑克 ,  這真是太神奇了 ,  但傳輸的資料一定要是  XML  格式嗎 ?
XHR  接受的資料型態 不 , XHR  除了  XML  資料之外 ,  還可以傳送  text ,  所以也包括了  HTML ,  JavaScript (JSON) [{author:‘tempo’, title:‘ 智者的對談 '}, {author:‘browser,koji’, title:‘JSP 技術手冊 '}, {author:‘caterpillar’, title:‘Spring 技術手冊 '}, {author:‘piggy’, title:’Java2 全方位學習’ ];
傑克 :   那所有的瀏覽器都有支援  XHR  嗎 ?
瀏覽器支援 XHR  支援以下瀏覽器 IE 5.0+ Mozilla 1.0+ Safari 1.2 Konqueor Opera 8.0 但不同的瀏覽器  XHR  建立方式不同 IE:  ActiveX Others:  JavaScript
瀏覽器支援 function httpRequest (reqType,url){ if(window. XMLHttpRequest ){  // Mozilla, Opera, Safari, … request = new XMLHttpRequest(); } else if (window. ActiveXObject ){  // IE request=new ActiveXObject("Msxml2.XMLHTTP"); if (!request){ request=new ActiveXObject("Microsoft.XMLHTTP"); } } if(request){ … } else { alert(" Your browser does not permit the use of all "+ "of this application's features! "); } }
珍妮佛 :   真奇怪 ,  我使用  XHR,  瀏覽器卻一直跳出安全性問題 ?
跨網域支援 有可能是其他問題 ,  但  XHR  限制僅能存取該網站上的資料 ,  無法存取其他網站的資料 For example,  若此網頁的網址為  http:// www.abc.com/test.jsp ,  則  XHR: 不可存取 : test.abc.com/*, abc.com/* 可存取 :  www.abc.com/* AJAX SOA?
傑克 :   少來了  tempo,  明明除了  XHR  之外 ,  還有其它方式來存取網站資料
<iframe> 與 <script> 是的 ,  利用  < iframe >  與  < script >  也可以達到相同的功能 ,  但需要轉幾個彎
<iframe> 與 <script> 使用 < iframe > < script > var sObj = document. createElement (' script '); sObj. src  = ‘ http://www.abc.com ’; document. body . appendChild ( sObj ); var sObj = document. createElement (' iframe '); sObj. src  = ‘ http://www.abc.com ’; sObj. onload  =  function() { iframe_loaded( sObj ); }; document. body . appendChild ( sObj );
<iframe> 與 <script> 資料接收 < iframe > 回傳資料為  HTML  格式 < script > 回傳資料為  JavaScript  格式 但都可以經過額外的步驟轉換為  XML   或  JavaScript
<iframe> 與 <script> 優缺點 優點 可以 跨網域 存取資料 ,  不像  XHR  有限制 < iframe >  瀏覽過的網頁會被加入瀏覽器的歷史紀錄內 支援較多的瀏覽器 缺點 使用起來較繁瑣 僅支援  HTTP GET
tempo:   那我來做個整理吧
各種方法比較
小細節需要注意 三種傳輸方式 XHR , < iframe >, < script > 三種資料格式 XML ,  HTML ,  JavaScript 跨網域 問題 瀏覽器支援問題 上一頁 / 下一頁與書籤問題 *
珍妮佛 :   好吧  tempo,  這太複雜了 ,  我只是想要存取網站上的資料而已
透過  AJAX Framework  來做非同步傳輸 XHR , < iframe >, < script >  各有不同的優點與缺點 瀏覽器有不同的  bugs   與 標準 自行維護非同步傳輸底層不容易
透過  AJAX Framework  來做非同步傳輸 現有的 AJAX Framework 都有提供自己的 XHR Utility 或包裝 Framework:  Google Web Toolkit, ZK, Dojo, … RPC:  DWR, JSON-RPC, … Libraries:  Prototype, … DWR   是其中最專業也是支援最廣的  AJAX  非同步傳輸  Framework
D irect  W eb  R emoting 1:50
傑克 :   什麼是  DWR  呢 ?
DWR(Direct Web Remoting) RPC-Style AJAX Easy AJAX for Java Easy to integrate AJAX : Expose  Java  to the  Browser Reverse AJAX : Expose  JavaScript  to the  Server
DWR From:  http://getahead.ltd.uk/dwr/overview/dwr
珍妮佛 :   我也想試試  DWR,  我該如何安裝呢 ?
Step 1: Download 從網站下載  DWR:  http:// getahead.ltd.uk/dwr/download Copy  dwr.jar  into WEB-INF/lib 2:00
Step 2: web.xml < servlet > < servlet-name > dwr-invoker </ servlet-name > < display-name > DWR Servlet </ display-name > < servlet-class > org.directwebremoting.servlet.DwrServlet </ servlet-class > < init-param > < param-name > debug </ param-name > < param-value > true </ param-value > </ init-param > </ servlet > < servlet-mapping > < servlet-name > dwr-invoker </ servlet-name > < url-pattern > /dwr/* </ url-pattern > </ servlet-mapping > 修改  web.xml,  新增  DwrServlet
Step 3: dwr.xml < dwr > < allow > < create  creator = &quot;new&quot;  javascript = &quot;JDate&quot; > < param  name = &quot;class&quot;  value = &quot;java.util.Date&quot; /> </ create > </ allow > </ dwr > 將遠端  Java  物件註冊到  dwr.xml
DEMO: Installation http://localhost:8080/dwr-minimal/dwr/
DWR  除錯視窗 在  web.xml  設定  init-param, ‘ debug ’ =  true 顯示註冊在  dwr.xml   的物件與提供直接測試用 請不要在正式環境使用 !!! < init-param > < param-name > debug </ param-name > < param-value > true </ param-value > </ init-param >
建民 :   那  tempo,  你應該要講怎麼做  Hello World  了吧 ? 2:05
Step1:  建立伺服器端的  Java  物件 package  com.willmobile.ajaxtm; public class  HelloWorld { public String  sayHelloWorldTo (String name) { return &quot; Hello World  &quot; + name + &quot; ! &quot;; } }
Step2:  在  dwr.xml  中註冊類別 <dwr> <allow> <create  creator =&quot; new “ javascript =&quot; HelloWorld &quot;  scope =&quot; page &quot;> <param  name =&quot; class &quot; value =&quot; com.willmobile.ajaxtm.HelloWorld &quot; /> </create> </allow> </dwr> 在  dwr.xml  的  <allow>  內建立  <create>
Step3:  在網頁中  include JavaScript <head> <script  type =' text/javascript ' src =' /dwr-helloworld/dwr/interface/HelloWorld.js'/> <script  type ='text/javascript‘ src =' /dwr-helloworld/dwr/engine.js ‘/> <script  type ='text/javascript‘ src =' /dwr-helloworld/dwr/util.js ‘/> </script> </head> engine.js  與  util.js  是  dwr  的公用  script HelloWorld.js  是我們註冊的遠端物件  script
Step4:  撰寫  client  端  JavaScript <head> <script  type =&quot; text/javascript &quot;> window.onload =  function()  { functon callback (str) { $('output'). innerHTML  = str; } HelloWorld. sayHelloWorldTo (&quot; JavaTwo 2006 &quot;,  callback ); } </script> </head>
遠端物件方法呼叫方式 參數與一般呼叫方式相同 回傳值使用  callback function ,  放在最後一個參數 用  Meta-data Object  定義  callback function public class  Remote { public String  getData (int  index ) { ... } } function handleGetData (str) { alert(str); } Remote.getData(42,  handleGetData );
Demo: Hello World http://localhost:8080/dwr-helloworld/ http://localhost:8080/dwr-helloworld/dwr/
Tips & Tricks about DWR 2:15
傑克 :   可以讓遠端  Java  物件存放在  session  或  application scope  嗎 ?
設定遠端物件的  Scope 物件的  scope  可以透過  dwr.xml  內的  create  屬性設定 application, session, request, page <dwr> <allow> <create creator=&quot;new“ javascript=&quot;HelloWorld&quot;  scope =&quot; page &quot;> <param name=&quot;class&quot; value=&quot;com.willmobile.ajaxtm.HelloWorld&quot; /> </create> </allow> </dwr>
珍妮佛 :   參數可以是自訂的類別嗎 ?
Converters 定義在  dwr.xml  中描述  remote  物件 var  r  =  Remote .method( param ); Uses a Converter Uses a Creator From:  http://getahead.ltd.uk/dwr/overview/dwr
Converters 自動轉換 Primitive Type  ( 與他們對應的  class  型態 ) String Date 預設  Converters Bean/Object Converter Array/Collection Converter Dom Objects Enum Converter
Converters 設定 <dwr> <allow> <create> … </create> <convert  converter =&quot; bean “ match =&quot; com.willmobile.ajaxtm.User &quot;> </convert> </allow> </dwr> 在  dwr.xml  的  <allow>  內建立  <convert>
傑克 :   任何遠端  Java  物件上的方法都可以呼叫嗎 ?
<include>, <exclude> 可在  dwr.xml  中設定遠端  Java  物件存取的權限 <dwr> <allow> <create creator=&quot;new“ javascript=&quot;HelloWorld&quot; scope=&quot;page&quot;> <param name=&quot;class&quot; value=&quot;com.willmobile.ajaxtm.HelloWorld&quot; /> < exclude   method =“ noUse &quot;/> </create> <convert converter=&quot;bean“ match=&quot;com.willmobile.ajaxtm.User&quot;> < param   name =&quot; exclude &quot;  value =&quot; password &quot;/> </convert> </allow> </dwr>
tempo:   那該輪到做一個  Web Form  來試試看 2:20
Step1:  建立伺服器端的  Java  物件 public class  User  { private String  id ; private String  password ; private String  name ; private String  title ; … }
Step2:  建立伺服器端的  Java  物件 public class  UserManager  { private final List<User> users = new ArrayList<User>(); public synchronized void  add (User user) { users. add (user); } public synchronized List<User>  getAll () { return new ArrayList<User>(users); } }
Step3: client script function  addUser () { var user = { id:&quot;&quot;, name:&quot;&quot;, title:&quot;&quot; }; DWRUtil.getValues(user); UserManager.add(user); UserManager.getAll(fillTable); } var cellFuncs = [ function(data) { return data.id; }, function(data) { return data.name; }, function(data) { return data.title; } ]; function  fillTable (users) { DWRUtil.removeAllRows(&quot;usersBody&quot;); DWRUtil.addRows(&quot;usersBody&quot;, users, cellFuncs); }
Demo: DWR Form http://localhost:8080/dwr-form/
Reverse AJAX 2:25
珍妮佛 :   我也會做  jsp  的聊天室呀 ,  你前面的  Demo  有比較好嗎 ?
Reverse AJAX AJAX ( 與一般  WEB  應用 ) 由瀏覽器發動每個需求 ,  伺服器不能主動傳給瀏覽器任何資料 Pull  Model Reverse AJAX 伺服器可主動傳送資訊至瀏覽器顯示或執行 Push  Model ( 但其實是用  pull  模擬 ) Polling Comet (Long Live HTTP)
Polling 瀏覽器 伺服器 N 秒送出一個 request 1. 新資料到 2. 新資料傳至瀏覽器 3. 顯示 req1 req2 req3 req4
Comet 瀏覽器 伺服器 1. 新資料到 2. 新資料傳至瀏覽器 3. 顯示 req1 req2
Reverse AJAX DWR 將這些複雜的操作隱藏起來 Comet (Long Live HTTP) Polling Server Push  JavaScript   至  Client ScriptSession. addScript (&quot; alert('Hi') &quot;);
Reverse AJAX 適合需要即時回應的網路應用 股市資訊 線上遊戲 聊天交友 會員客戶服務
珍妮佛 :   我也想做像前面  Demo  那樣的聊天室 ~~
Step1:  建立伺服器端的  Java  物件 public void addMessage (String text) { … final WebContext wctx = WebContextFactory. get (); // For all the browsers on the current page: String currentPage = wctx. getCurrentPage (); Collection sessions = wctx. getScriptSessionsByPage (currentPage); DwrUtil utilAll = new DwrUtil(sessions); utilAll.removeAllOptions(&quot;chatlog&quot;); utilAll.addOptions(&quot;chatlog&quot;, messages, &quot;text&quot;); }
Step1:  建立伺服器端的  Java  物件 <script type=&quot;text/javascript&quot;> window.onload = function() { DWREngine. setReverseAjax (true); Chatroom. getAllMessages (function(messages) { DWRUtil.removeAllOptions('chatlog'); DWRUtil.addOptions( 'chatlog', messages, 'text'); }); } function sendMessage() { Chatroom. addMessage (DWRUtil.getValue(&quot;text&quot;)); } </script>
Demo: DWR Chat http://localhost:8080/dwr-chat/before.jsp http://localhost:8080/dwr-chat/after.jsp
傑克 :   那你之前  Demo  的股市報價 ,  也是用同一種技術囉 ? 2:30
Step1:  建立伺服器端的  Java  物件 private class  SendTickerDataTask extends TimerTask { public void run() { ServerContext sctx = ServerContextFactory. get (servletContext); Collection sessions = sctx. getScriptSessionsByPage ( “ /dwr-reverse/after.jsp ”); DwrUtil pages = new DwrUtil( sessions, servletContext); pages.setValue(symbol, RandomStockSnapshot. getRandomStockSnapshotString(symbol)); } }
Demo: DWR Reverse http://localhost:8080/dwr-reverse/before.jsp   http://localhost:8080/dwr-reverse/after.jsp
Web Framework Integration 2:35
珍妮佛 :  我不想呼叫物件 ,  我想把整個網頁  include  進來 ,  這可以嗎 ?
AJAX Includes 可以 , DWR  提供  Server-side Include Server Browser public String getInclude () { return WebContextFactory. get () . forwardToString (&quot; /forward.jsp &quot;); } function update () { Demo.getInclude(function(html) { DWRUtil. setValue (&quot; somediv &quot;, html); } );
傑克 : 這樣也行 ,  那我想要呼叫我伺服器上的  spring beans,  不會也可以吧 ?
Spring Integration SpringCreator web.xml <allow> <create creator=&quot; spring &quot; javascript=&quot;Fred&quot;> <param name=&quot;beanName&quot; value=&quot;Shiela&quot;/> </create> </allow> <context-param> <param-name> contextConfigLocation </param-name> <param-value>/WEB-INF/classes/beans.xml</param-value> </context-param>
珍妮佛 : 好吧 ,  那像  Struts, Webwork  應該也不是問題囉 ?
Struts Integration StrutsCreator Webwork 整合至  Action  層 ,  可透過  JavaScript  直接將  form  丟給  Action <allow> <create creator=&quot; struts &quot; javascript=&quot;Fred&quot;> <param name=&quot;beanName&quot; value=&quot;Shiela&quot;/> </create> </allow>
其他的功能 2:40
傑克 :  我想要連續呼叫三個遠端函式 ,  這樣使用者會等比較久嗎 ?
Batching 會的 ,  所以若需要將數個  dwr  功能一次送出 ,  請將需要在同一個交易內的功能放到  Batch  中 beginBatch (); … endBatch ();
珍妮佛 :  我看你的網頁右上方都有像  gmail  一樣的  loading message,  我也要
Loading Message 請在網頁  onLoad  時呼叫  useLoadingMessage()  即可 DWRUtils.useLoadingMessage(); Or DWRUtils.useLoadingMessage(‘Waiting…’);
傑克 :  你都沒有提到錯誤處理機制  :(
Error Handling Global Error (Exception) Handling Meta Data function handler(msg) { alert(msg); } DWREngine.setErrorHandler(handler); Remote.method(params, { callback:function(data) { ... }, errorHandler:handler });
傑克 :  哇 , DWR/AJAX  真棒 ,  可是 back/forward  鍵沒用了  :(
瀏覽器歷史紀錄問題 XHR   或是  < script >  都無法將連線網頁加入瀏覽器歷史紀錄內 Really Simple History http:// codinginparadise.org/projects/dhtml_history/README.html
珍妮佛 :  以上提到的方法所有瀏覽器都支援嗎 ?
瀏覽器支援 DWR  支援以下瀏覽器 IE 5.5+ Firefox 1.0+ Mozilla 1.7+ Safari 1.2+ Konqueor Opera 7.5.4+ ( 但現在不支援  Reverse AJAX)
傑克 :  我已經有使用其他  framework  了 ,  那我該如何整合  DHR  呢 ?
DWR  與其它  AJAX Framework JavaScript Libraries  不會有影響 Dojo Toolkit Prototype Script.aculo.us AJAX Framework  則請使用原本提供的存取方式 GWT ZK 2:45
Thank you! 如果你流落荒島 ,  但是只能帶一個  AJAX Framework,  建議你帶  DWR   馮彥文 [email_address]
我想請教關於 ..

More Related Content

PPTX
张所勇:前端开发工具推荐
PPT
让我们的页面跑得更快
PPTX
Xsd培训资料
PPT
Jsp
PPT
Jsp讲义
PDF
Ajax框架:Dwr》实战(包括整合)
PDF
Ajax新手快车道
PPTX
TBAD F2E 2010 review
张所勇:前端开发工具推荐
让我们的页面跑得更快
Xsd培训资料
Jsp
Jsp讲义
Ajax框架:Dwr》实战(包括整合)
Ajax新手快车道
TBAD F2E 2010 review

What's hot (16)

PPTX
Flash对象在(X)Html中的格式和参数及安全性
PPTX
JavaScript 80+ Programming and Optimization Skills
PDF
恶意网页分析实战
PPTX
WEB 安全基础
 
DOC
由浅到深了解Java Script类
PDF
Introduction to Parse JavaScript SDK
PDF
RESTful API Design
PPT
Asp.net mvc 培训
DOCX
Javascript 性能优化总结.docx
PDF
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
PPT
缓存技术浅谈
PDF
2021.laravelconf.tw.slides3
PDF
Prototype开发手册
PPT
Json知识分享
Flash对象在(X)Html中的格式和参数及安全性
JavaScript 80+ Programming and Optimization Skills
恶意网页分析实战
WEB 安全基础
 
由浅到深了解Java Script类
Introduction to Parse JavaScript SDK
RESTful API Design
Asp.net mvc 培训
Javascript 性能优化总结.docx
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
缓存技术浅谈
2021.laravelconf.tw.slides3
Prototype开发手册
Json知识分享
Ad

Viewers also liked (20)

PDF
Perfiles profesionales Consultor Mercado de la Energía
PDF
Cogmaster_Ep4
PDF
Compendio de derecho_sucesoral_-_mario_echeverria_esquivel
PDF
Understanding And Managing Memory
PDF
CONGEP 2009 - 8 Dez
PDF
Sandrogreco Energetic Aspects Of Cyclic Pi Electron Delocalization Evaluation...
PPT
Role of family in international assignment
PDF
Workplace Stress Risk Management
PDF
Central Sacramento Workshop Challenges And Successes
PDF
Monografia Erivaldo pedagogia 2010
PPT
PDF
Voluntariado corporativo
PPT
CSS Methodology
PDF
H42023442
KEY
Digital citizenship 1
PPTX
Dutch, French, English, & Stuff
PDF
DOC
Agenda arquidiocesana n° 170
PDF
PDF
Healthy Eating and Physical Activity: Addressing Inequities in Urban Environm...
Perfiles profesionales Consultor Mercado de la Energía
Cogmaster_Ep4
Compendio de derecho_sucesoral_-_mario_echeverria_esquivel
Understanding And Managing Memory
CONGEP 2009 - 8 Dez
Sandrogreco Energetic Aspects Of Cyclic Pi Electron Delocalization Evaluation...
Role of family in international assignment
Workplace Stress Risk Management
Central Sacramento Workshop Challenges And Successes
Monografia Erivaldo pedagogia 2010
Voluntariado corporativo
CSS Methodology
H42023442
Digital citizenship 1
Dutch, French, English, & Stuff
Agenda arquidiocesana n° 170
Healthy Eating and Physical Activity: Addressing Inequities in Urban Environm...
Ad

Similar to Ajax Transportation Methods (20)

PDF
用JAX-RS和Jersey完成RESTful Web Services
PDF
從 Web Site 到 Web Application,從 Web Services 到 Mobile Services
ODP
AJAX Search & Cross Domain Survey
PDF
Non-MVC Web Framework
PPTX
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
PDF
Backbone.js and MVW 101
PDF
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
PPTX
Ch03 請求與回應
PDF
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
PDF
Yahoo! 應用程式 (YAP) 在前端的開發
PDF
Dwr中文文档
PDF
Res tful api design tw-2.0
PDF
2015.07.17 新人報告(2)
PPT
[DCTPE2010] Drupal 遇上行動網路服務
PPTX
CH1. 簡介 Web 應用程式
PPTX
Java API for WebSocket 實作介紹
PDF
從open data角度談網站api應用
PPTX
Ch02 撰寫與設定 Servlet
PDF
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
PDF
淺談後端概念
用JAX-RS和Jersey完成RESTful Web Services
從 Web Site 到 Web Application,從 Web Services 到 Mobile Services
AJAX Search & Cross Domain Survey
Non-MVC Web Framework
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
Backbone.js and MVW 101
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Ch03 請求與回應
Servlet & JSP 教學手冊第二版試讀 - 撰寫與設定 Servlet
Yahoo! 應用程式 (YAP) 在前端的開發
Dwr中文文档
Res tful api design tw-2.0
2015.07.17 新人報告(2)
[DCTPE2010] Drupal 遇上行動網路服務
CH1. 簡介 Web 應用程式
Java API for WebSocket 實作介紹
從open data角度談網站api應用
Ch02 撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
淺談後端概念

More from yiditushe (20)

DOC
Spring入门纲要
PDF
J Bpm4 1中文用户手册
PPT
性能测试实践2
PPT
性能测试实践1
PPT
性能测试技术
PPT
Load runner测试技术
PPT
J2 ee性能测试
PPT
面向对象的Js培训
PDF
Flex3中文教程
PDF
开放源代码的全文检索Lucene
PDF
基于分词索引的全文检索技术介绍
PDF
Lucene In Action
DOC
Lucene2 4学习笔记1
DOC
Lucene2 4 Demo
PDF
Lucene 全文检索实践
PDF
Lucene 3[1] 0 原理与代码分析
PPT
7 面向对象设计原则
PPT
10 团队开发
PPT
9 对象持久化与数据建模
PPT
8 Uml构架建模
Spring入门纲要
J Bpm4 1中文用户手册
性能测试实践2
性能测试实践1
性能测试技术
Load runner测试技术
J2 ee性能测试
面向对象的Js培训
Flex3中文教程
开放源代码的全文检索Lucene
基于分词索引的全文检索技术介绍
Lucene In Action
Lucene2 4学习笔记1
Lucene2 4 Demo
Lucene 全文检索实践
Lucene 3[1] 0 原理与代码分析
7 面向对象设计原则
10 团队开发
9 对象持久化与数据建模
8 Uml构架建模

Ajax Transportation Methods

  • 1. AJAX 的 client/server 溝通機制探究 馮彥文 隨想行動科技
  • 2. 講師介紹 馮彥文 隨想行動科技 Javaworld.tw : tempo Email: [email_address] Blog: http:// www.pocketshark.com/blog/page/tempo
  • 3. 這個故事 , 就從兩個技術人在一次研討會中的偶然相遇開始…
  • 4. 傑克 : Hi 珍妮佛 , 你知道這個 session 最主要是講 ?
  • 5. 內容主題 AJAX 利用 AJAX 提高網站與使用者的互動性 (Rich Internet Application) User Interface: DHTML 非同步傳輸 : XMLHttpRequest (XHR) 與其他方式 , 與他們的黑暗面 AJAX Framework 學習如何利用 DWR(Direct Web Remoting) 來簡化 AJAX 與 Java 間的網路存取 , 且為網站增添更多功能 AJAX / Reverse AJAX
  • 6. 我們的目標 即時股市報價 http:// www.marketwatch.com http://localhost:8080/dwr-reverse/before.jsp http://localhost:8080/dwr-reverse/after.jsp
  • 7. 我們的目標 Web 聊天室 http:// gabbly.com/http://www.pocketshark.com/blog/page/tempo / http://localhost:8080/dwr-chat/before.jsp http://localhost:8080/dwr-chat/after.jsp
  • 8. What We Will Focus on Here Browser Compatibility, Cross-Domains, Java Data Marshalling, JSON , JSON-RPC, DOJO, DWR, GWT, iframe , Prototype, Timeout & Error Handling, Reverse AJAX, History & Bookmarks, scriptTag , Web Framework Integration, XHR, XML
  • 10. 珍妮佛 : 什麼是 AJAX? 什麼又是非同步傳輸 ?
  • 11. AJAX A synchronous J avaScript A nd X ML XHTML&CSS DOM JavaScript XMLHttpRequest AJAX = DHTML + XHR
  • 12. Classic Web Applications From: http://adaptivepath.com/publications/essays/archives/000385.php
  • 13. AJAX Web Applications From: http://adaptivepath.com/publications/essays/archives/000385.php
  • 14. 傑克 : 那我該如何利用 AJAX 存取遠端網站資料呢 ?
  • 15. XHR(XMLHttpRequest) JavaScript 版的 HttpConnection 介面 open(string url,string asynch): 開啟網頁 send(string): 傳送資料 onreadystatechange : 狀態改變回呼函式 status: HTTP 狀態 responseXML : 回傳的 XML DOM responseText : 回傳的文字內容
  • 16. XHR 使用者輸入觸動 XHR // 建立 XHR request = new XMLHttpRequest(); // 設定回呼函式 request. onreadystatechange =handleResponse; // 開啟連結 request. open (&quot;GET&quot;,&quot;http://abc.com&quot;,true); // 傳送資料 request. send (null);
  • 17. XHR 接收資料後立刻更新 UI function handleResponse () { // 檢查 XHR 狀態 if(request. readyState == 4){ // 檢查 http 狀態 if(request. status == 200){ // 讀取回傳 XML 資料 var doc = request. responseXML ; // 取得網頁上需被更新的 node 位置 var node = document. getElementById (“resp&quot;); // 設定該 node 的內容 node. innerHTML = doc.documentElement.childNodes[0].nodeValue; } } }
  • 18. DEMO: Hello World http://localhost:8080/xhr/index.jsp
  • 19. Tips & Tricks about XHR 1:40
  • 20. 珍妮佛 : 傑克 , 這真是太神奇了 , 但傳輸的資料一定要是 XML 格式嗎 ?
  • 21. XHR 接受的資料型態 不 , XHR 除了 XML 資料之外 , 還可以傳送 text , 所以也包括了 HTML , JavaScript (JSON) [{author:‘tempo’, title:‘ 智者的對談 '}, {author:‘browser,koji’, title:‘JSP 技術手冊 '}, {author:‘caterpillar’, title:‘Spring 技術手冊 '}, {author:‘piggy’, title:’Java2 全方位學習’ ];
  • 22. 傑克 : 那所有的瀏覽器都有支援 XHR 嗎 ?
  • 23. 瀏覽器支援 XHR 支援以下瀏覽器 IE 5.0+ Mozilla 1.0+ Safari 1.2 Konqueor Opera 8.0 但不同的瀏覽器 XHR 建立方式不同 IE: ActiveX Others: JavaScript
  • 24. 瀏覽器支援 function httpRequest (reqType,url){ if(window. XMLHttpRequest ){ // Mozilla, Opera, Safari, … request = new XMLHttpRequest(); } else if (window. ActiveXObject ){ // IE request=new ActiveXObject(&quot;Msxml2.XMLHTTP&quot;); if (!request){ request=new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;); } } if(request){ … } else { alert(&quot; Your browser does not permit the use of all &quot;+ &quot;of this application's features! &quot;); } }
  • 25. 珍妮佛 : 真奇怪 , 我使用 XHR, 瀏覽器卻一直跳出安全性問題 ?
  • 26. 跨網域支援 有可能是其他問題 , 但 XHR 限制僅能存取該網站上的資料 , 無法存取其他網站的資料 For example, 若此網頁的網址為 http:// www.abc.com/test.jsp , 則 XHR: 不可存取 : test.abc.com/*, abc.com/* 可存取 : www.abc.com/* AJAX SOA?
  • 27. 傑克 : 少來了 tempo, 明明除了 XHR 之外 , 還有其它方式來存取網站資料
  • 28. <iframe> 與 <script> 是的 , 利用 < iframe > 與 < script > 也可以達到相同的功能 , 但需要轉幾個彎
  • 29. <iframe> 與 <script> 使用 < iframe > < script > var sObj = document. createElement (' script '); sObj. src = ‘ http://www.abc.com ’; document. body . appendChild ( sObj ); var sObj = document. createElement (' iframe '); sObj. src = ‘ http://www.abc.com ’; sObj. onload = function() { iframe_loaded( sObj ); }; document. body . appendChild ( sObj );
  • 30. <iframe> 與 <script> 資料接收 < iframe > 回傳資料為 HTML 格式 < script > 回傳資料為 JavaScript 格式 但都可以經過額外的步驟轉換為 XML 或 JavaScript
  • 31. <iframe> 與 <script> 優缺點 優點 可以 跨網域 存取資料 , 不像 XHR 有限制 < iframe > 瀏覽過的網頁會被加入瀏覽器的歷史紀錄內 支援較多的瀏覽器 缺點 使用起來較繁瑣 僅支援 HTTP GET
  • 32. tempo: 那我來做個整理吧
  • 34. 小細節需要注意 三種傳輸方式 XHR , < iframe >, < script > 三種資料格式 XML , HTML , JavaScript 跨網域 問題 瀏覽器支援問題 上一頁 / 下一頁與書籤問題 *
  • 35. 珍妮佛 : 好吧 tempo, 這太複雜了 , 我只是想要存取網站上的資料而已
  • 36. 透過 AJAX Framework 來做非同步傳輸 XHR , < iframe >, < script > 各有不同的優點與缺點 瀏覽器有不同的 bugs 與 標準 自行維護非同步傳輸底層不容易
  • 37. 透過 AJAX Framework 來做非同步傳輸 現有的 AJAX Framework 都有提供自己的 XHR Utility 或包裝 Framework: Google Web Toolkit, ZK, Dojo, … RPC: DWR, JSON-RPC, … Libraries: Prototype, … DWR 是其中最專業也是支援最廣的 AJAX 非同步傳輸 Framework
  • 38. D irect W eb R emoting 1:50
  • 39. 傑克 : 什麼是 DWR 呢 ?
  • 40. DWR(Direct Web Remoting) RPC-Style AJAX Easy AJAX for Java Easy to integrate AJAX : Expose Java to the Browser Reverse AJAX : Expose JavaScript to the Server
  • 41. DWR From: http://getahead.ltd.uk/dwr/overview/dwr
  • 42. 珍妮佛 : 我也想試試 DWR, 我該如何安裝呢 ?
  • 43. Step 1: Download 從網站下載 DWR: http:// getahead.ltd.uk/dwr/download Copy dwr.jar into WEB-INF/lib 2:00
  • 44. Step 2: web.xml < servlet > < servlet-name > dwr-invoker </ servlet-name > < display-name > DWR Servlet </ display-name > < servlet-class > org.directwebremoting.servlet.DwrServlet </ servlet-class > < init-param > < param-name > debug </ param-name > < param-value > true </ param-value > </ init-param > </ servlet > < servlet-mapping > < servlet-name > dwr-invoker </ servlet-name > < url-pattern > /dwr/* </ url-pattern > </ servlet-mapping > 修改 web.xml, 新增 DwrServlet
  • 45. Step 3: dwr.xml < dwr > < allow > < create creator = &quot;new&quot; javascript = &quot;JDate&quot; > < param name = &quot;class&quot; value = &quot;java.util.Date&quot; /> </ create > </ allow > </ dwr > 將遠端 Java 物件註冊到 dwr.xml
  • 47. DWR 除錯視窗 在 web.xml 設定 init-param, ‘ debug ’ = true 顯示註冊在 dwr.xml 的物件與提供直接測試用 請不要在正式環境使用 !!! < init-param > < param-name > debug </ param-name > < param-value > true </ param-value > </ init-param >
  • 48. 建民 : 那 tempo, 你應該要講怎麼做 Hello World 了吧 ? 2:05
  • 49. Step1: 建立伺服器端的 Java 物件 package com.willmobile.ajaxtm; public class HelloWorld { public String sayHelloWorldTo (String name) { return &quot; Hello World &quot; + name + &quot; ! &quot;; } }
  • 50. Step2: 在 dwr.xml 中註冊類別 <dwr> <allow> <create creator =&quot; new “ javascript =&quot; HelloWorld &quot; scope =&quot; page &quot;> <param name =&quot; class &quot; value =&quot; com.willmobile.ajaxtm.HelloWorld &quot; /> </create> </allow> </dwr> 在 dwr.xml 的 <allow> 內建立 <create>
  • 51. Step3: 在網頁中 include JavaScript <head> <script type =' text/javascript ' src =' /dwr-helloworld/dwr/interface/HelloWorld.js'/> <script type ='text/javascript‘ src =' /dwr-helloworld/dwr/engine.js ‘/> <script type ='text/javascript‘ src =' /dwr-helloworld/dwr/util.js ‘/> </script> </head> engine.js 與 util.js 是 dwr 的公用 script HelloWorld.js 是我們註冊的遠端物件 script
  • 52. Step4: 撰寫 client 端 JavaScript <head> <script type =&quot; text/javascript &quot;> window.onload = function() { functon callback (str) { $('output'). innerHTML = str; } HelloWorld. sayHelloWorldTo (&quot; JavaTwo 2006 &quot;, callback ); } </script> </head>
  • 53. 遠端物件方法呼叫方式 參數與一般呼叫方式相同 回傳值使用 callback function , 放在最後一個參數 用 Meta-data Object 定義 callback function public class Remote { public String getData (int index ) { ... } } function handleGetData (str) { alert(str); } Remote.getData(42, handleGetData );
  • 54. Demo: Hello World http://localhost:8080/dwr-helloworld/ http://localhost:8080/dwr-helloworld/dwr/
  • 55. Tips & Tricks about DWR 2:15
  • 56. 傑克 : 可以讓遠端 Java 物件存放在 session 或 application scope 嗎 ?
  • 57. 設定遠端物件的 Scope 物件的 scope 可以透過 dwr.xml 內的 create 屬性設定 application, session, request, page <dwr> <allow> <create creator=&quot;new“ javascript=&quot;HelloWorld&quot; scope =&quot; page &quot;> <param name=&quot;class&quot; value=&quot;com.willmobile.ajaxtm.HelloWorld&quot; /> </create> </allow> </dwr>
  • 58. 珍妮佛 : 參數可以是自訂的類別嗎 ?
  • 59. Converters 定義在 dwr.xml 中描述 remote 物件 var r = Remote .method( param ); Uses a Converter Uses a Creator From: http://getahead.ltd.uk/dwr/overview/dwr
  • 60. Converters 自動轉換 Primitive Type ( 與他們對應的 class 型態 ) String Date 預設 Converters Bean/Object Converter Array/Collection Converter Dom Objects Enum Converter
  • 61. Converters 設定 <dwr> <allow> <create> … </create> <convert converter =&quot; bean “ match =&quot; com.willmobile.ajaxtm.User &quot;> </convert> </allow> </dwr> 在 dwr.xml 的 <allow> 內建立 <convert>
  • 62. 傑克 : 任何遠端 Java 物件上的方法都可以呼叫嗎 ?
  • 63. <include>, <exclude> 可在 dwr.xml 中設定遠端 Java 物件存取的權限 <dwr> <allow> <create creator=&quot;new“ javascript=&quot;HelloWorld&quot; scope=&quot;page&quot;> <param name=&quot;class&quot; value=&quot;com.willmobile.ajaxtm.HelloWorld&quot; /> < exclude method =“ noUse &quot;/> </create> <convert converter=&quot;bean“ match=&quot;com.willmobile.ajaxtm.User&quot;> < param name =&quot; exclude &quot; value =&quot; password &quot;/> </convert> </allow> </dwr>
  • 64. tempo: 那該輪到做一個 Web Form 來試試看 2:20
  • 65. Step1: 建立伺服器端的 Java 物件 public class User { private String id ; private String password ; private String name ; private String title ; … }
  • 66. Step2: 建立伺服器端的 Java 物件 public class UserManager { private final List<User> users = new ArrayList<User>(); public synchronized void add (User user) { users. add (user); } public synchronized List<User> getAll () { return new ArrayList<User>(users); } }
  • 67. Step3: client script function addUser () { var user = { id:&quot;&quot;, name:&quot;&quot;, title:&quot;&quot; }; DWRUtil.getValues(user); UserManager.add(user); UserManager.getAll(fillTable); } var cellFuncs = [ function(data) { return data.id; }, function(data) { return data.name; }, function(data) { return data.title; } ]; function fillTable (users) { DWRUtil.removeAllRows(&quot;usersBody&quot;); DWRUtil.addRows(&quot;usersBody&quot;, users, cellFuncs); }
  • 68. Demo: DWR Form http://localhost:8080/dwr-form/
  • 70. 珍妮佛 : 我也會做 jsp 的聊天室呀 , 你前面的 Demo 有比較好嗎 ?
  • 71. Reverse AJAX AJAX ( 與一般 WEB 應用 ) 由瀏覽器發動每個需求 , 伺服器不能主動傳給瀏覽器任何資料 Pull Model Reverse AJAX 伺服器可主動傳送資訊至瀏覽器顯示或執行 Push Model ( 但其實是用 pull 模擬 ) Polling Comet (Long Live HTTP)
  • 72. Polling 瀏覽器 伺服器 N 秒送出一個 request 1. 新資料到 2. 新資料傳至瀏覽器 3. 顯示 req1 req2 req3 req4
  • 73. Comet 瀏覽器 伺服器 1. 新資料到 2. 新資料傳至瀏覽器 3. 顯示 req1 req2
  • 74. Reverse AJAX DWR 將這些複雜的操作隱藏起來 Comet (Long Live HTTP) Polling Server Push JavaScript 至 Client ScriptSession. addScript (&quot; alert('Hi') &quot;);
  • 75. Reverse AJAX 適合需要即時回應的網路應用 股市資訊 線上遊戲 聊天交友 會員客戶服務
  • 76. 珍妮佛 : 我也想做像前面 Demo 那樣的聊天室 ~~
  • 77. Step1: 建立伺服器端的 Java 物件 public void addMessage (String text) { … final WebContext wctx = WebContextFactory. get (); // For all the browsers on the current page: String currentPage = wctx. getCurrentPage (); Collection sessions = wctx. getScriptSessionsByPage (currentPage); DwrUtil utilAll = new DwrUtil(sessions); utilAll.removeAllOptions(&quot;chatlog&quot;); utilAll.addOptions(&quot;chatlog&quot;, messages, &quot;text&quot;); }
  • 78. Step1: 建立伺服器端的 Java 物件 <script type=&quot;text/javascript&quot;> window.onload = function() { DWREngine. setReverseAjax (true); Chatroom. getAllMessages (function(messages) { DWRUtil.removeAllOptions('chatlog'); DWRUtil.addOptions( 'chatlog', messages, 'text'); }); } function sendMessage() { Chatroom. addMessage (DWRUtil.getValue(&quot;text&quot;)); } </script>
  • 79. Demo: DWR Chat http://localhost:8080/dwr-chat/before.jsp http://localhost:8080/dwr-chat/after.jsp
  • 80. 傑克 : 那你之前 Demo 的股市報價 , 也是用同一種技術囉 ? 2:30
  • 81. Step1: 建立伺服器端的 Java 物件 private class SendTickerDataTask extends TimerTask { public void run() { ServerContext sctx = ServerContextFactory. get (servletContext); Collection sessions = sctx. getScriptSessionsByPage ( “ /dwr-reverse/after.jsp ”); DwrUtil pages = new DwrUtil( sessions, servletContext); pages.setValue(symbol, RandomStockSnapshot. getRandomStockSnapshotString(symbol)); } }
  • 82. Demo: DWR Reverse http://localhost:8080/dwr-reverse/before.jsp http://localhost:8080/dwr-reverse/after.jsp
  • 84. 珍妮佛 : 我不想呼叫物件 , 我想把整個網頁 include 進來 , 這可以嗎 ?
  • 85. AJAX Includes 可以 , DWR 提供 Server-side Include Server Browser public String getInclude () { return WebContextFactory. get () . forwardToString (&quot; /forward.jsp &quot;); } function update () { Demo.getInclude(function(html) { DWRUtil. setValue (&quot; somediv &quot;, html); } );
  • 86. 傑克 : 這樣也行 , 那我想要呼叫我伺服器上的 spring beans, 不會也可以吧 ?
  • 87. Spring Integration SpringCreator web.xml <allow> <create creator=&quot; spring &quot; javascript=&quot;Fred&quot;> <param name=&quot;beanName&quot; value=&quot;Shiela&quot;/> </create> </allow> <context-param> <param-name> contextConfigLocation </param-name> <param-value>/WEB-INF/classes/beans.xml</param-value> </context-param>
  • 88. 珍妮佛 : 好吧 , 那像 Struts, Webwork 應該也不是問題囉 ?
  • 89. Struts Integration StrutsCreator Webwork 整合至 Action 層 , 可透過 JavaScript 直接將 form 丟給 Action <allow> <create creator=&quot; struts &quot; javascript=&quot;Fred&quot;> <param name=&quot;beanName&quot; value=&quot;Shiela&quot;/> </create> </allow>
  • 91. 傑克 : 我想要連續呼叫三個遠端函式 , 這樣使用者會等比較久嗎 ?
  • 92. Batching 會的 , 所以若需要將數個 dwr 功能一次送出 , 請將需要在同一個交易內的功能放到 Batch 中 beginBatch (); … endBatch ();
  • 93. 珍妮佛 : 我看你的網頁右上方都有像 gmail 一樣的 loading message, 我也要
  • 94. Loading Message 請在網頁 onLoad 時呼叫 useLoadingMessage() 即可 DWRUtils.useLoadingMessage(); Or DWRUtils.useLoadingMessage(‘Waiting…’);
  • 95. 傑克 : 你都沒有提到錯誤處理機制 :(
  • 96. Error Handling Global Error (Exception) Handling Meta Data function handler(msg) { alert(msg); } DWREngine.setErrorHandler(handler); Remote.method(params, { callback:function(data) { ... }, errorHandler:handler });
  • 97. 傑克 : 哇 , DWR/AJAX 真棒 , 可是 back/forward 鍵沒用了 :(
  • 98. 瀏覽器歷史紀錄問題 XHR 或是 < script > 都無法將連線網頁加入瀏覽器歷史紀錄內 Really Simple History http:// codinginparadise.org/projects/dhtml_history/README.html
  • 99. 珍妮佛 : 以上提到的方法所有瀏覽器都支援嗎 ?
  • 100. 瀏覽器支援 DWR 支援以下瀏覽器 IE 5.5+ Firefox 1.0+ Mozilla 1.7+ Safari 1.2+ Konqueor Opera 7.5.4+ ( 但現在不支援 Reverse AJAX)
  • 101. 傑克 : 我已經有使用其他 framework 了 , 那我該如何整合 DHR 呢 ?
  • 102. DWR 與其它 AJAX Framework JavaScript Libraries 不會有影響 Dojo Toolkit Prototype Script.aculo.us AJAX Framework 則請使用原本提供的存取方式 GWT ZK 2:45
  • 103. Thank you! 如果你流落荒島 , 但是只能帶一個 AJAX Framework, 建議你帶 DWR  馮彥文 [email_address]