注册 登录
编程论坛 JavaScript论坛

反向Ajax扫盲贴(3)PiggyBack

wangnannan 发布于 2015-06-01 16:29, 4630 次点击
之前发了两个帖子 关于反向ajax的内容 多谢大家给捧场
但是之前的两贴介绍的技术跟今天咱们要说比起来 那就是boolshit 根本没有可比性
那就是我要说的PiggyBack 但是在这之前 我要跟大家先说一下DWR 就像它自己介绍自己的一样 Easy Ajax for JAVA

首先是官方解释
DWR(Direct Web Remoting)是一个WEB远程调用框架.利用这个框架可以让AJAX开发变得很简单.利用DWR可以在客户端利用JavaScript直接调用服务端的Java方法并返回值给JavaScript就好像直接本地客户端调用一样(DWR根据Java类来动态生成JavaScrip代码).它的最新版本DWR0.6添加许多特性如:支持Dom Trees的自动配置,支持Spring(JavaScript远程调用spring bean),更好浏览器支持,还支持一个可选的commons-logging日记操作.以上摘自open-open,它通过反射,将java翻译成javascript,然后利用回调机制,轻松实现了javascript调用Java代码。

不懂请看下方屌丝解释
看到上面那段您也许会乱了  新手更会说 这都什么跟神马啊 说了这么多废话 一句没懂 那么DWR到底是做什么的呢 下面我通俗的给大家讲一下
首先 DWR是一个框架 你要下载它的最新版本 然后安装 你安装DWR时会配置一个servlet 这个servlet记得吧?他就是负责把前台的JS参数封装成JAVA 去调用你的JAVA类 然后将返回结果(JAVA类型)再翻译成JS生成到你的JSP页面上(这块是它的NB之处)给你的错觉就是你用JS直接调用了JAVA方法  不懂servlet的朋友可以看这里
http://blog.
那DWR又和反向ajax有什么关系呢 ???
DWR包含两个主要的部分:允许JavaScript从WEB服务器上一个遵循了AJAX原则的Servlet
中获取数据.
另外一方面一个JavaScript库可以帮助网站开发人员轻松地利用获取的数据来
动态改变网页的内容.

看到这里您是不是有点明白了 既然DWR支持ajax 那我是不是可以用它来搞一个推送呢 答案是完全可以
给大家找了两个例子 咱们先说第一个 告诉大家怎么配置一下DWR 因为毕竟是不是VS没有那么智能 但也不是特别难

还是重复之前那几句话
DWR是一个Open Source的 java项目。DWR可以让JavaScript调用运行在Web服务器里面的JAVA程序。简单一点或者专业一点就是Easy AJAX for JAVA.
官方网站:http://
下面将一步一步的介绍怎么完成一个简单DEMO :TestDwr
一、从官方网站下载DWR.jar包
    把他直接放到apache-tomcat-7.0.27\lib目录下面
二、新建Web Project工程
编写一个TestDwr.Java类如下:
package com.test.ajax;
publicclass TestDwr
{  

    public String getMyName()
    {     

        return"Hello Casco!";

    }     

}  

这个类方法不用多说了 就是返回一个Hello Casco!
三、修改web.xml
程序代码:
<?xml version="1.0" encoding="UTF-8"?>  

<web-app version="3.0"   

    xmlns="http://java. xmlns:xsi="http://www. xsi:schemaLocation="http://java. http://java. <servlet-name>dwr-invoker</servlet-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>  

  <welcome-file-list>  

    <welcome-file>index.jsp</welcome-file>  

  </welcome-file-list>  

</web-app>  





20 回复
#2
wangnannan2015-06-01 16:31
配置文件不用多说了 就是配置servlet
#3
wangnannan2015-06-01 16:32
四、新建dwr.xml文件
把TestDwr类配置在dwr.xml中,dwr.xml是DWR的配置文件,所有需要在JavaScript中调用的java的类都必须在这个文件中描述 (必须与web.xml同级)
关键代码如下
程序代码:
<?xml version="1.0" encoding="UTF-8"?>  

<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http:// creator="new" javascript="CASCO" scope="application">

<param name="class" value="com.test.ajax.TestDwr"/>

</create>

</allow>

</dwr>

#4
wangnannan2015-06-01 16:32
有点乱了 感觉没说明白 我在琢磨琢磨怎么让大家理解 今天先说到这儿
#5
hu9jj2015-06-01 20:21
看来得下点功夫才能跟得上。
#6
wmf20142015-06-01 20:38
我是绝对跟不上的。
唉,果真是没需求就没学习动力哦。
#7
冰镇柠檬汁儿2015-06-01 20:42
以下是引用wmf2014在2015-6-1 20:38:41的发言:

我是绝对跟不上的。
唉,果真是没需求就没学习动力哦。

那我现在的动力来自哪里?绝对不是需求,是追求
#8
冰镇柠檬汁儿2015-06-01 21:51
#9
wp2319572015-06-02 08:11
我也没动力
#10
wangnannan2015-06-02 08:38
接着昨天的说
程序代码:
<?xml version="1.0" encoding="UTF-8"?>  

<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http:// creator="new" javascript="CASCO" scope="application">

<param name="class" value="com.test.ajax.TestDwr"/>

</create>

</allow>

</dwr>
 <allow>标签中包括可以暴露给javascript访问的东西。
 <create>标签中指定javascript中可以访问的java类,并定义DWR应当如何获得要进行远程的类的实例。creator="new"属性指定java类实例的生成方式,new意味着DWR应当调用类的默认构造函数来获得实例,其他的还有spring方式,通过与IOC容器Spring进行集成来获得实例等等。javascript=" CASCO"属性指定javascript代码访问对象时使用的名称。
 
  标签指定要公开给javascript的java类名。
 
  <include>标签指定要公开给javascript的方法。不指定的话就公开所有方法。
 
  <exclude>标签指定要防止被访问的方法。


[ 本帖最后由 wangnannan 于 2015-6-2 08:40 编辑 ]
#11
wangnannan2015-06-02 08:49
OK这是配置文件就算搞定了 下面我说一下DWR调用原理 借用网上现成的 我觉得他这个说的相当全面
1 编写业务代码,该代码是和dwr无关的。(这个咱们做了TestDwr类和方法 )
2.确认业务代码中哪些类、哪些方法是要由javascript直接访问的。(这个也做了 TestDwr中的getMyName方法要被访问)
3.编写dwr组件,对步骤2的方法进行封装。 (配置文件已经设置了)
4.配置dwr组件到dwr.xml文件中,如果有必要,配置convert,进行java和javascript类型互转。
这步还没开始 如何进行转换呢 也很简单 看下边
首先,引入javascript脚本
5.通过反射机制,dwr将步骤4的类转换成javascript代码,提供给前台页面调用。
6.编写网页,调用步骤5的javascript中的相关方法(间接调用服务器端的相关类的方法),执行业务逻辑,将执行结果利用回调函数返回。
  <script src='dwr/interface/ CASCO.js'></script>
 
  <script src='dwr/engine.js'></script>
 
  <script src='dwr/util.js'></script>
 
  其中TestClass.js是dwr根据配置文件自动生成的,engine.js和util.js是dwr自带的脚本文件。
 
  其次,编写调用java方法的javascript函数
 
  Function callTestMethod2(){
 
  CASCO.getMyName(callBackFortestMethod2);
 
  }
 
  Function callBackFortestMethod2(data){
 
  //其中data接收方法的返回值
 
  //可以在这里对返回值进行处理和显示等等
 
  alert("the return value is " + data);
 
  }

#12
wangnannan2015-06-02 08:49
DWR的配置和原理算是给大家说完了 下边我说一下推送 毕竟这是大家最关心的话题
#13
wangnannan2015-06-02 08:52
DWR推送是相当NB的 是可以在配置文件进行设置的
下边我给大家截取一段
<servlet>
  <servlet-name>dwr-invoker</servlet-name>
  <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  <init-param>
   <param-name>debug</param-name>
   <param-value>true</param-value>
  </init-param>
  <init-param>
   <param-name>logLevel</param-name>
   <param-value>ERROR</param-value>
  </init-param>
  <init-param>
   <param-name>crossDomainSessionSecurity</param-name>
   <param-value>false</param-value>
  </init-param>
  <init-param>
   <param-name>allowScriptTagRemoting</param-name>
   <param-value>true</param-value>
  </init-param>
  <!--
   <init-param> <param-name>crossDomainSessionSecurity</param-name>
   <param-value>false</param-value> </init-param> <init-param>
   <param-name>allowScriptTagRemoting</param-name>
   <param-value>true</param-value> </init-param>
  -->
  <init-param>
   <param-name>classes</param-name>
   <param-value>java.lang.Object</param-value>
  </init-param>
  <!-- 开启反转Ajax 即所谓推技术 -->
  <init-param>
   <param-name>activeReverseAjaxEnabled</param-name>
   <param-value>true</param-value>
  </init-param>
   <init-param>
       <param-name>initApplicationScopeCreatorsAtStartup</param-name>
       <param-value>true</param-value>
     </init-param>
  <init-param>
     <param-name>maxWaitAfterWrite</param-name>
     <param-value>1000</param-value>
  </init-param>
  <!-- 对dwr scriptSession 自定义管理 -->
  <init-param>
   <param-name>org.directwebremoting.extend.ScriptSessionManager</param-name>
   <param-value>com.xx.xx.util.DwrScriptSessionManagerUtil</param-value>
  </init-param>
 </servlet>
 <servlet-mapping>
  <servlet-name>dwr-invoker</servlet-name>
  <url-pattern>/dwr/*</url-pattern>
 </servlet-mapping>
#14
wangnannan2015-06-02 08:53
程序代码:
<!-- 开启反转Ajax 即所谓推技术 -->
  <init-param>
   <param-name>activeReverseAjaxEnabled</param-name>
   <param-value>true</param-value>
  </init-param>
   <init-param>
       <param-name>initApplicationScopeCreatorsAtStartup</param-name>
       <param-value>true</param-value>
     </init-param>
  <init-param>
     <param-name>maxWaitAfterWrite</param-name>
     <param-value>1000</param-value>
  </init-param>
  <!-- 对dwr scriptSession 自定义管理 -->
  <init-param>
   <param-name>org.directwebremoting.extend.ScriptSessionManager</param-name>
   <param-value>com.xx.xx.util.DwrScriptSessionManagerUtil</param-value>
  </init-param>
这段就是重要的代码 只要配置就可以了
#15
wangnannan2015-06-02 08:54
另外推送当中的 涉及到 scriptsession优化问题 不再本帖讨论范围内 有兴趣的可以自己百度
#16
wangnannan2015-06-02 08:54
js中开启dwr推功能
 
在window.onload中使用dwr.engine.setActiveReverseAjax(true);
#17
wangnannan2015-06-02 08:56
DWR很少是做全推送的 基本都是有针对性的半推 所以需要自己写一个过滤器
一个过滤器来过滤要推送的scriptsession
给大家一个代码片段
程序代码:
Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
   
    public boolean match(ScriptSession session) {
     Long loginUserId = (Long) session.getAttribute(Constant.LG_USER_ID);
     if(loginUserId!=null && targetIdList.contains(loginUserId))
     {
      targetIdList.remove(loginUserId);//如果找到了,说明将被推送,所以不用再处理,剩下的都是要被处理的
      return true;
     }
     return false;
    }
    }, new Runnable() {
   
     private ScriptBuffer script = new ScriptBuffer();
     public void run()
     {
      script.appendCall("这里写你页面的js函数", 这个参数是传给js函数的);
      Collection<ScriptSession> sessions = Browser.getTargetSessions();
               for (ScriptSession scriptSession : sessions)
               {
                   scriptSession.addScript(script);
               }
     //ScriptSessions.addFunctionCall("ExtTalk.updateMegGroup", data);//之所以不用这个方法,是因为这个

//方法有bug的存在,会对所有不论过不过滤的scriptsession进行推送,相当于全推送,没有起到过滤的作用
    }
   });
#18
wangnannan2015-06-02 08:56
这个有一点点麻烦 我自己都没法跟大家详细的说明白 另外DWR还可以和SSH框架结合使用 希望本帖能给大家一点起始 完
#19
wangnannan2015-06-02 10:47
差点忘记了重要的
肯定会问 什么是Piggyback Piggyback到底是什么

简单明了的解释让你明白
 Piggyback 就是如果后台有什么内容需要推送到前台(即调用页面的js方法)
是要等到那个页面进行下一次ajax请求的时候
将需要推送的内容附加在该次请求之后,传回到页面 可以完美的替代我以前用的Jquery等的ajax方式
#20
love云彩2015-06-10 11:23
刚接触SSH的时候就听说过DWR这个框架了,做WEB项目的时候,经常想在前端动态获取服务器数据,但是觉得ajax有点麻烦,知道DWR可以简化但当时并没有深入了解
#21
wangnannan2015-06-18 15:23
别加精了 我嫌丢人
1