輕松

          記述我學習java的里程

          常用鏈接

          統計

          積分與排名

          友情鏈接

          最新評論

          DWR的注釋(annotations)使用及反向調用(Reverse Ajax)

                  最近也不是很忙花了點時間再仔細研究了一下DWR,其實兩三年前就已經開始使用它了。不過一直用的也比較簡單DWR,沒花過太多的心思在上面(呵呵,主要還是項目沒需求?。2挥迷俣嗾f了,相信大家都知道,配置和使用都非常簡單。今天要說的是DWR的一些高級一點用法。當然也不難。只是為了防止自己忘記,同時也和其他人分享一下。 言歸正傳開始吧。



          先說說注釋語法,省掉dwr.xml。(自從用了java 5 之后,現在越看一堆堆的配置文件越煩,越來越喜歡注釋方式來的直接簡單了)

           

          首先下載最新的穩定版本的dwr.jar文件放到你的工程中。(還有需要其它的嗎?不需要了,dwr就是這么簡單)
          然后在web.xml中添加如下一段
           <!-- DWRServlet -->
           <servlet>
            <servlet-name>dwr-invoker</servlet-name>
            <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
            <init-param>
          <!-- 默認為false,調試用,可以訪問http://地址:端口/上下文/dwr 來進行測試 -->
             <param-name>debug</param-name>
             <param-value>true</param-value>
            </init-param>
          <!--這就是傳說中的DWR反轉調用的開關了,默認也是false -->
            <init-param>
             <param-name>activeReverseAjaxEnabled</param-name>
             <param-value>true</param-value>
            </init-param>
          <!--日志級別不多說了-->
            <init-param>
             <param-name>logLevel</param-name>
             <param-value>WARN</param-value>
            </init-param>
          <!--這塊注意了,關鍵來了,把使用DWR注釋的類都要加在這里,2.0的DWR好像還不支持包掃描,希望以后能提供這個功能,3.0我還沒注意有沒有這個功能,現在還沒出正式版-->
            <init-param>
             <param-name>classes</param-name>
             <param-value>
                          org.relax.service.SectionManager,
              org.relax.service..entity.Section
                      </param-value>
            </init-param>
           </servlet>
          <!--這塊不用多說了吧,如果看不懂,哪涼快哪呆著去吧-->
           <servlet-mapping>
            <servlet-name>dwr-invoker</servlet-name>
            <url-pattern>/dwr/*</url-pattern>
           </servlet-mapping>
          在這里再說明一下有的文章用的是uk.ltd.getahead.dwr.DWRServlet,其實他只是繼承了一下org.directwebremoting.servlet.DwrServlet自己什么也沒做,所以這兩個類用哪個都行(這么做應該是為了兼容以前的版本,猜的,1.0我沒用過)。
          下面看具體的類吧。

          @Service
          @RemoteProxy(creator = SpringCreator.class, name = "sectionManager", creatorParams = @Param(name = "beanName", value = "sectionManager"))
          public class SectionManager extends DefaultEntityManager<Section, Integer> {

           @Autowired
           OriginCollectDataManager originCollectDataManager;

           @RemoteMethod
           public Section get(Integer id) {
            return super.get(id);
           }

           @RemoteMethod
           public List<Section> getAll() {
            return super.getAll();
           }

          }

          我的測試環境里還用到了spring和hibernate,所以里面還摻雜了一些spring的注釋標記,當然如果你沒用也無所謂。
          這里主要解釋一下DWR的幾個Annotations
          @RemoteProxy標在類上的就是使類可以運程訪問
          @RemoteProxy(creator = SpringCreator.class, name = "sectionManager", creatorParams = @Param(name = "beanName", value = "sectionManager")),
          上面因為使用了spring所以寫的是springCreator.class, 其它還有BeanCreator, Ejb3Creator, JsfCreator, NewCreator, NullCreator, PageFlowCreator, ScriptedCreator, SingletonCreator, SpringCreator, StrutsCreator。看自己的具體需求。最常用的就是newCreator了吧。
          @RemoteMethod標在方法上,不用多說可以使方法能遠程訪問
          @DataTransferObject標在類上,注明需要轉換的VO類了
          @RemoteProperty標在類的屬性上,標明哪些可以訪問(我試了試不標,好像全都可以訪問了)
          常用的就這么多了,其它幾個不太常用,如果用到的時候再研究吧。
          還有什么要做的嗎?好像就這么多了。DWR就是簡單。如果標好了可以試試訪問上下文路徑加上/dwr來訪問試試了。好像好用了哎。如下圖
          點進去看看都有什么方法

          看上去方法好像挺多,其實真正能訪問用的只有用@RemoteMethod標注過的。
          測試已經好用了下面就是加到頁面了。那不就更簡單了嗎。按著上圖收到JSP文件中。然后像調用普通javascript對象一樣就可以了。咱不是做普及的,今天主要講注釋的用法。這部分就到這吧。

          下面說反向調用了,這個還是挺復雜的,首先解釋幾個概念。

          dwr的逆向ajax其實主要包括兩種模式:主動模式和被動模式。其中主動模式包括Polling和Comet兩種,被動模式只有Piggyback這一種。

              所謂的Piggyback指的是如果后臺有什么內容需要推送到前臺(即調用頁面的js方法),是要等到那個頁面進行下一次ajax請求的時候,將需要推送的內容附加在該次請求之后,傳回到頁面。

              polling指的是由瀏覽器定時向服務端發送ajax請求,詢問后臺是否有什么內容需要推送,有的話就會由服務端返回推送內容。這種方式和我們直接在頁面通過定時器發送ajax請求,然后查詢后臺是否有變化內容的實現是類似的。只不過用了dwr之后這部分工作由框架幫我們完成了。

              comet模式指的的當服務端建立和瀏覽器的連接,將頁面內容發送到瀏覽器之后,對應的連接并不關閉,只是暫時掛起。如果后面有什么新的內容需要推送到客戶端的時候直接通過前面掛起的連接再次傳送數據。

              通過上面的解釋我們可以看到,這三種模式都有各自的優缺點。從客戶端請求次數的角度來說,當然是piggyback的模式最好。這個里面完全沒有額外的網絡請求,只有等到下次請求頁面主動發起了,中間的變化內容才傳遞回頁面。但是這也導致了這推送內容的延時,因為你完全沒辦法知道頁面的下一次請求將在什么時候發起,也許頁面永遠都沒有下一次請求。polling模式的網絡請求最為頻繁了,因為這時候頁面不管后臺有沒有更新的內容,都需要發送請求詢問。雖然這種模式可以通過增加請求間隔的時間來減少單位時間內的請求次數,但是這樣同樣會導致頁面響應后臺內容變化的間隔時間增長,這中間就產生了矛盾,具體的請求間隔時間還是要根據具體項目的需求來配置。比如服務器能承受的請求間隔和頁面內容所需要的刷新頻率。comet方式的響應速度應該是最快的,后臺一旦有內容需要推送可以通過前面沒有關閉的連接馬上推送到前臺。但是服務器所能提供的連接數目是一定的,在大量的掛起的連接沒有關閉的情況下,可能造成新的連接請求不能接入,從而影響到服務質量。

          以上摘自dwr的Reverse Ajax(推技術的實現之一)
          概念說清楚了,下面做一吧。
          前面已經說完了注釋方式了,以下還用注釋的方式,方便直觀呀。
           @RemoteMethod
           public synchronized  void start() {
            WebContext wctx = WebContextFactory.get();
            String currentPage = wctx.getCurrentPage();
            running=true;
            for (int i = 0; i < 1000; i++) {
             if (!running) {
              break;
             }
             ScriptBuffer script = new ScriptBuffer();
             script.appendScript("receiveMessages(").appendData(i).appendScript(");");//調用頁面的javascript方法把值添到頁面上。
             // Loop over all the users on the current page
             Collection pages = wctx.getScriptSessionsByPage(currentPage);//循環出所有的會話頁面并執行
             for (Iterator it = pages.iterator(); it.hasNext();) {
              System.err.println(i);
              ScriptSession otherSession = (ScriptSession) it.next();
              otherSession.addScript(script);
             }
             try {
              Thread.sleep(3000);
             } catch (InterruptedException e) {
              e.printStackTrace();
             }
            }
           }
           
           @RemoteMethod
           public  void stop() {
            running=false;
           }
          這是個簡單的程序進行之后就是用個循環來更新頁面的數字。
          下面也貼一下JSP的代碼吧。也算補充下第一部分了。

          <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
              pageEncoding="UTF-8"%>
          <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
          <html>
          <head>
            <script type='text/javascript' src='/dymc-web/dwr/interface/sectionManager.js'></script>
            <script type='text/javascript' src='/dymc-web/dwr/engine.js'></script>
          <script type="text/javascript">

          function receiveMessages(msg) {
           //alert(msg);
           document.getElementById("content").innerHTML=msg;
          }
          </script>
          <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
          <title>Insert title here</title>
          </head>
          <body onload="dwr.engine.setActiveReverseAjax(true)">
          <button onclick="sectionManager.start()">start</button>
          <button onclick="sectionManager.stop()">stop</button>
          <div id="content"></div>
          </body>
          </html>

          頁面包括兩個鈕一個開始一個停止。大家來試試吧。這里不添圖了太浪費空間
          運行起來后點start按鈕,看看頁面上是不是自己開始變了。新打開個IE,用另外的機器訪問此面,疑?怎么都有數字在變換,這就是DWR Reverse Ajax的厲害所在了。再點一下stop,呀,所有打個IE里數字都不變了吧。
          注意:代碼用的是主動的方式,所以注意頁面onload中的<body onload="dwr.engine.setActiveReverseAjax(true)">沒有這句可就不好用了。當然 web.xml中也不能少了
            <init-param>
             <param-name>activeReverseAjaxEnabled</param-name>
             <param-value>true</param-value>
            </init-param>
          該說的都說了就到這吧。這篇文章不是給初學者看的。所以不是特別的完整。如果你是初學者,就先去看看基礎吧??赡苡悬c不適合你。

          posted on 2009-08-13 14:37 輕松 閱讀(2930) 評論(3)  編輯  收藏 所屬分類: 其他文章

          評論

          # re: DWR的注釋(annotations)使用及反向調用(Reverse Ajax)[未登錄] 2009-08-16 11:02 XXX

          樓主把自己形容得好牛一樣.  回復  更多評論   

          # re: DWR的注釋(annotations)使用及反向調用(Reverse Ajax) 2009-08-16 22:56 修人為主

          貌似servlet中要加DWRSpringServlet?。?nbsp; 回復  更多評論   

          # re: DWR的注釋(annotations)使用及反向調用(Reverse Ajax) 2009-08-17 09:19 輕松

          沒什么好牛的。寫個篇文件是為給其它同事和自己看的。
          回第二個DWRSpringServlet,加那個是讓DWR可以spring的配置文件里可以配置。
          我這里在注釋里用springcreator就可以了。完全沒有必要用DWRSpringServlet,那是for spring2.0的。  回復  更多評論   

          主站蜘蛛池模板: 河曲县| 新民市| 三河市| 广丰县| 蓝山县| 大宁县| 庆安县| 桂林市| 昆明市| 桐梓县| 达州市| 修武县| 濉溪县| 图木舒克市| 兴国县| 安陆市| 镇赉县| 麻阳| 余干县| 三河市| 揭西县| 阳高县| 鱼台县| 平陆县| 临沂市| 宾川县| 中卫市| 南和县| 上高县| 凤翔县| 青铜峡市| 包头市| 唐海县| 报价| 阿克陶县| 观塘区| 洪雅县| 邵阳市| 翁牛特旗| 科尔| 虞城县|