AJAX   的  client/server   溝通機制探究 馮彥文 隨想行動科技
講師介紹 <ul><li>馮彥文 </li></ul><ul><li>隨想行動科技 </li></ul><ul><li>Javaworld.tw :  tempo </li></ul><ul><li>Email:  [email_address...
這個故事 ,  就從兩個技術人在一次研討會中的偶然相遇開始…
傑克 :   Hi  珍妮佛 , 你知道這個  session  最主要是講 ?
內容主題 <ul><li>AJAX </li></ul><ul><ul><li>利用  AJAX  提高網站與使用者的互動性  (Rich Internet Application) </li></ul></ul><ul><ul><li>Use...
我們的目標 <ul><li>即時股市報價 </li></ul><ul><ul><li>http:// www.marketwatch.com </li></ul></ul><ul><ul><li>http://localhost:8080/dw...
我們的目標 <ul><li>Web  聊天室 </li></ul><ul><ul><li>http:// gabbly.com/http://www.pocketshark.com/blog/page/tempo / </li></ul></u...
What We Will Focus on Here Browser Compatibility,   Cross-Domains, Java Data Marshalling,   JSON , JSON-RPC,   DOJO,   DWR...
AJAX  非同步傳輸 1:35
珍妮佛 :   什麼是  AJAX?  什麼又是非同步傳輸 ?
AJAX <ul><li>A synchronous </li></ul><ul><li>J avaScript </li></ul><ul><li>A nd </li></ul><ul><li>X ML </li></ul>XHTML&CSS...
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) <ul><li>JavaScript  版的  HttpConnection </li></ul><ul><li>介面 </li></ul><ul><ul><li>open(string url,stri...
XHR <ul><li>使用者輸入觸動  XHR </li></ul>//  建立  XHR request = new XMLHttpRequest(); //  設定回呼函式 request. onreadystatechange =han...
XHR <ul><li>接收資料後立刻更新 UI </li></ul>function handleResponse () { //  檢查  XHR  狀態 if(request. readyState  == 4){ //  檢查  htt...
DEMO: Hello World <ul><li>http://localhost:8080/xhr/index.jsp </li></ul>
Tips & Tricks about XHR 1:40
珍妮佛 :   傑克 ,  這真是太神奇了 ,  但傳輸的資料一定要是  XML  格式嗎 ?
XHR  接受的資料型態 <ul><li>不 , XHR  除了  XML  資料之外 ,  還可以傳送  text ,  所以也包括了  HTML ,  JavaScript (JSON) </li></ul>[{author:‘tempo’...
傑克 :   那所有的瀏覽器都有支援  XHR  嗎 ?
瀏覽器支援 <ul><li>XHR  支援以下瀏覽器 </li></ul><ul><ul><li>IE 5.0+ </li></ul></ul><ul><ul><li>Mozilla 1.0+ </li></ul></ul><ul><ul><l...
瀏覽器支援 function httpRequest (reqType,url){ if(window. XMLHttpRequest ){  // Mozilla, Opera, Safari, … request = new XMLHttp...
珍妮佛 :   真奇怪 ,  我使用  XHR,  瀏覽器卻一直跳出安全性問題 ?
跨網域支援 <ul><li>有可能是其他問題 ,  但  XHR  限制僅能存取該網站上的資料 ,  無法存取其他網站的資料 </li></ul><ul><li>For example,  若此網頁的網址為  http:// www.abc.c...
傑克 :   少來了  tempo,  明明除了  XHR  之外 ,  還有其它方式來存取網站資料
<iframe> 與 <script> <ul><li>是的 ,  利用  < iframe >  與  < script >  也可以達到相同的功能 ,  但需要轉幾個彎 </li></ul>
<iframe> 與 <script> 使用 <ul><li>< iframe > </li></ul><ul><li>< script > </li></ul>var sObj = document. createElement (' scr...
<iframe> 與 <script> 資料接收 <ul><li>< iframe > </li></ul><ul><ul><li>回傳資料為  HTML  格式 </li></ul></ul><ul><li>< script > </li><...
<iframe> 與 <script> 優缺點 <ul><li>優點 </li></ul><ul><ul><li>可以 跨網域 存取資料 ,  不像  XHR  有限制 </li></ul></ul><ul><ul><li>< iframe >...
tempo:   那我來做個整理吧
各種方法比較
小細節需要注意 <ul><li>三種傳輸方式 </li></ul><ul><ul><li>XHR , < iframe >, < script > </li></ul></ul><ul><li>三種資料格式 </li></ul><ul><ul>...
珍妮佛 :   好吧  tempo,  這太複雜了 ,  我只是想要存取網站上的資料而已
透過  AJAX Framework  來做非同步傳輸 <ul><li>XHR , < iframe >, < script >  各有不同的優點與缺點 </li></ul><ul><li>瀏覽器有不同的  bugs   與 標準 </li><...
透過  AJAX Framework  來做非同步傳輸 <ul><li>現有的 AJAX Framework 都有提供自己的 XHR Utility 或包裝 </li></ul><ul><ul><li>Framework:  Google We...
D irect  W eb  R emoting 1:50
傑克 :   什麼是  DWR  呢 ?
DWR(Direct Web Remoting) <ul><li>RPC-Style AJAX </li></ul><ul><li>Easy AJAX for Java </li></ul><ul><li>Easy to integrate <...
DWR From:  http://getahead.ltd.uk/dwr/overview/dwr
珍妮佛 :   我也想試試  DWR,  我該如何安裝呢 ?
Step 1: Download <ul><li>從網站下載  DWR:  http:// getahead.ltd.uk/dwr/download </li></ul><ul><li>Copy  dwr.jar  into WEB-INF/l...
Step 2: web.xml <ul><li>< servlet > </li></ul><ul><li>< servlet-name > dwr-invoker </ servlet-name > </li></ul><ul><li>< d...
Step 3: dwr.xml <ul><li>< dwr > </li></ul><ul><li>< allow > </li></ul><ul><li>< create  creator = &quot;new&quot;  javascr...
DEMO: Installation <ul><li>http://localhost:8080/dwr-minimal/dwr/ </li></ul>
DWR  除錯視窗 <ul><li>在  web.xml  設定  init-param, ‘ debug ’ =  true </li></ul><ul><li>顯示註冊在  dwr.xml   的物件與提供直接測試用 </li></ul><...
建民 :   那  tempo,  你應該要講怎麼做  Hello World  了吧 ? 2:05
Step1:  建立伺服器端的  Java  物件 package  com.willmobile.ajaxtm; public class  HelloWorld { public String  sayHelloWorldTo (Strin...
Step2:  在  dwr.xml  中註冊類別 <dwr> <allow> <create  creator =&quot; new “ javascript =&quot; HelloWorld &quot;  scope =&quot;...
Step3:  在網頁中  include JavaScript <head> <script  type =' text/javascript ' src =' /dwr-helloworld/dwr/interface/HelloWorld...
Step4:  撰寫  client  端  JavaScript <head> <script  type =&quot; text/javascript &quot;> window.onload =  function()  { func...
遠端物件方法呼叫方式 <ul><li>參數與一般呼叫方式相同 </li></ul><ul><li>回傳值使用  callback function ,  放在最後一個參數 </li></ul><ul><li>用  Meta-data Objec...
Demo: Hello World <ul><li>http://localhost:8080/dwr-helloworld/ </li></ul><ul><li>http://localhost:8080/dwr-helloworld/dwr...
Tips & Tricks about DWR 2:15
傑克 :   可以讓遠端  Java  物件存放在  session  或  application scope  嗎 ?
設定遠端物件的  Scope <ul><li>物件的  scope  可以透過  dwr.xml  內的  create  屬性設定 </li></ul><ul><ul><li>application, session, request, pa...
珍妮佛 :   參數可以是自訂的類別嗎 ?
Converters <ul><li>定義在  dwr.xml  中描述  remote  物件 </li></ul><ul><li>var  r  =  Remote .method( param ); </li></ul>Uses a Co...
Converters <ul><li>自動轉換 </li></ul><ul><ul><li>Primitive Type  ( 與他們對應的  class  型態 ) </li></ul></ul><ul><ul><li>String </li...
Converters 設定 <dwr> <allow> <create> … </create> <convert  converter =&quot; bean “ match =&quot; com.willmobile.ajaxtm.Us...
傑克 :   任何遠端  Java  物件上的方法都可以呼叫嗎 ?
<include>, <exclude> <ul><li>可在  dwr.xml  中設定遠端  Java  物件存取的權限 </li></ul><dwr> <allow> <create creator=&quot;new“ javascri...
tempo:   那該輪到做一個  Web Form  來試試看 2:20
Step1:  建立伺服器端的  Java  物件 public class  User  { private String  id ; private String  password ; private String  name ; pri...
Step2:  建立伺服器端的  Java  物件 public class  UserManager  { private final List<User> users = new ArrayList<User>(); public sync...
Step3: client script function  addUser () { var user = { id:&quot;&quot;, name:&quot;&quot;, title:&quot;&quot; }; DWRUtil...
Demo: DWR Form <ul><li>http://localhost:8080/dwr-form/ </li></ul>
Reverse AJAX 2:25
珍妮佛 :   我也會做  jsp  的聊天室呀 ,  你前面的  Demo  有比較好嗎 ?
Reverse AJAX <ul><li>AJAX ( 與一般  WEB  應用 ) </li></ul><ul><ul><li>由瀏覽器發動每個需求 ,  伺服器不能主動傳給瀏覽器任何資料 </li></ul></ul><ul><ul><li...
Polling 瀏覽器 伺服器 N 秒送出一個 request 1. 新資料到 2. 新資料傳至瀏覽器 3. 顯示 req1 req2 req3 req4
Comet 瀏覽器 伺服器 1. 新資料到 2. 新資料傳至瀏覽器 3. 顯示 req1 req2
Reverse AJAX <ul><li>DWR </li></ul><ul><ul><li>將這些複雜的操作隱藏起來 </li></ul></ul><ul><ul><li>Comet (Long Live HTTP) </li></ul></...
Reverse AJAX <ul><li>適合需要即時回應的網路應用 </li></ul><ul><ul><li>股市資訊 </li></ul></ul><ul><ul><li>線上遊戲 </li></ul></ul><ul><ul><li>聊...
珍妮佛 :   我也想做像前面  Demo  那樣的聊天室 ~~
Step1:  建立伺服器端的  Java  物件 public void addMessage (String text) { … final WebContext wctx = WebContextFactory. get (); // F...
Step1:  建立伺服器端的  Java  物件 <script type=&quot;text/javascript&quot;> window.onload = function() { DWREngine. setReverseAjax...
Demo: DWR Chat <ul><li>http://localhost:8080/dwr-chat/before.jsp </li></ul><ul><li>http://localhost:8080/dwr-chat/after.js...
傑克 :   那你之前  Demo  的股市報價 ,  也是用同一種技術囉 ? 2:30
Step1:  建立伺服器端的  Java  物件 private class  SendTickerDataTask extends TimerTask { public void run() { ServerContext sctx = S...
Demo: DWR Reverse <ul><li>http://localhost:8080/dwr-reverse/before.jsp   </li></ul><ul><li>http://localhost:8080/dwr-rever...
Web Framework Integration 2:35
珍妮佛 :  我不想呼叫物件 ,  我想把整個網頁  include  進來 ,  這可以嗎 ?
AJAX Includes <ul><li>可以 , DWR  提供  Server-side Include </li></ul><ul><li>Server </li></ul><ul><li>Browser </li></ul>publi...
傑克 : 這樣也行 ,  那我想要呼叫我伺服器上的  spring beans,  不會也可以吧 ?
Spring Integration <ul><li>SpringCreator </li></ul><ul><li>web.xml </li></ul><allow> <create creator=&quot; spring &quot; ...
珍妮佛 : 好吧 ,  那像  Struts, Webwork  應該也不是問題囉 ?
Struts Integration <ul><li>StrutsCreator </li></ul><ul><li>Webwork </li></ul><ul><ul><li>整合至  Action  層 ,  可透過  JavaScript...
其他的功能 2:40
傑克 :  我想要連續呼叫三個遠端函式 ,  這樣使用者會等比較久嗎 ?
Batching <ul><li>會的 ,  所以若需要將數個  dwr  功能一次送出 ,  請將需要在同一個交易內的功能放到  Batch  中 </li></ul>beginBatch (); … endBatch ();
珍妮佛 :  我看你的網頁右上方都有像  gmail  一樣的  loading message,  我也要
Loading Message <ul><li>請在網頁  onLoad  時呼叫  useLoadingMessage()  即可 </li></ul>DWRUtils.useLoadingMessage(); Or DWRUtils.use...
傑克 :  你都沒有提到錯誤處理機制  :(
Error Handling <ul><li>Global Error (Exception) Handling </li></ul><ul><li>Meta Data </li></ul>function handler(msg) { ale...
傑克 :  哇 , DWR/AJAX  真棒 ,  可是 back/forward  鍵沒用了  :(
瀏覽器歷史紀錄問題 <ul><li>XHR   或是  < script >  都無法將連線網頁加入瀏覽器歷史紀錄內 </li></ul><ul><li>Really Simple History </li></ul><ul><ul><li>h...
珍妮佛 :  以上提到的方法所有瀏覽器都支援嗎 ?
瀏覽器支援 <ul><li>DWR  支援以下瀏覽器 </li></ul><ul><ul><li>IE 5.5+ </li></ul></ul><ul><ul><li>Firefox 1.0+ </li></ul></ul><ul><ul><l...
傑克 :  我已經有使用其他  framework  了 ,  那我該如何整合  DHR  呢 ?
DWR  與其它  AJAX Framework <ul><li>JavaScript Libraries  不會有影響 </li></ul><ul><ul><li>Dojo Toolkit </li></ul></ul><ul><ul><li...
Thank you! 如果你流落荒島 ,  但是只能帶一個  AJAX Framework,  建議你帶  DWR   馮彥文 [email_address]
我想請教關於 ..
Upcoming SlideShare
Loading in …5
×

Ajax Transportation Methods

3,306 views
3,216 views

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,306
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
30
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Ajax Transportation Methods

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

×