微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

还是太年轻!DWR进一步学习

昨天研究了一下用DWR框架,做了一个消息推送的demo。根据网上的资料,写一个demo并不难。当demo跑起来并能成功向客户端推送消息的时候,我以为会用DWR了。

但是当我把DWR集成到springMVC中的时候,又走了一些弯路。根本原因是对DWR的机制原理不了解。DWR做消息推送只是它的一种功能,如果把它理解成消息推送就太狭隘了。

当我们研究一门新技术的时候,需要搞清楚几个问题。这个技术用来解决什么问题?内部实现机制?怎么在项目中使用?

1、介绍

一个框架,允许Javascript通过DWR访问服务器上的Java代码

2、组成和原理

基于AJAX的框架,包含两个主要部分:
一个运行在服务器端的JavaServlet,它处理请求并且向浏览器发回响应;
一个运行在浏览器端的Javascript,它发送请求而且能动态更新网页。

DWR的工作原理是,通过反射,将java翻译成javascript,然后利用回调机制,轻松实现了javascript调用Java代码
大大简化了编写ajax的工作量,它不需要任何网页浏览器插件就能运行在网页上。

3:优点

(1)浏览器兼容;
(2)json的封装;
(3)多种对象的转换;
(4)可以写更少的JS代码,做更多的事情。

4:应用

注意怎么应用,可以参考前一篇文章。《DWR消息推送技术》
(这个标题有点狭隘O(∩_∩)O~)

<script type='text/javascript' src='dwr/engine.js'></script>
<script type='text/javascript' src='dwr/util.js'></script>
<script type="text/javascript" src="dwr/interface/MessagePush.js"></script>

页面引用了三个js,第一个js是dwr的引擎,第二个js是dwr的工具类,第三个js是dwr自动生成的。

当访问页面时,并执行engine.js时,由于在web.xml配置了/dwr路径。
(注意:在web.xml中配置DwrServlet的url-pattern,需要指到engine.js引擎所在的目录,否则DWR无法自动生成js文件)

DWR的DwrServlet会处理请求,然后将engine.js以流的形式发送给浏览器,
根据dwr.xml配置的class路径,找到对应的java类,根据java类自动生成MessagePush.js,并同样以流的形式发送给浏览器,MessagePush.js都可以在浏览器的缓存里找到。

dwr.xml

<dwr>
<allow>
      <create creator="new" javascript="MessagePush">
       <param name="class" value="com.huatech.messageremind.service.MessagePush"/>
    </create>

     <create creator="new" javascript="TestPush">
       <param name="class" value="com.huatech.messageremind.service.Test"/>
    </create>
</allow>
</dwr>

java代码

public class MessagePush {

  /** * 接收上线用户 * @param userId */
  public void onPageLoad(String userId) {
    ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
    scriptSession.setAttribute(userId,userId);
    DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();
    try {
      dwrScriptSessionManagerUtil.init();
    } catch (servletexception e) {
      e.printstacktrace();
    }

  }

  /** * 单个设备推送 * @param userid * @param message */
  public static void sendMessageSingle(String userid,String message) {
    final String userId = userid;
    final String autoMessage = message;
    browser.withAllSessionsFiltered(new ScriptSessionFilter() {
      public boolean match(ScriptSession session) {
        if (session.getAttribute("username") == null)
          return false;
        else
          return (session.getAttribute("username")).equals(userId);
      }
    },new Runnable() {
      private ScriptBuffer script = new ScriptBuffer();

      public void run() {
        script.appendCall("showMessage",autoMessage);
        Collection<ScriptSession> sessions = browser
            .getTargetSessions();
        for (ScriptSession scriptSession : sessions) {
          scriptSession.addScript(script);
        }
      }
    });
  }

//广播
public static void sendbroadcastMessage(final String message) {
browser.withPage(“/dwr/”,new Runnable(){
public void run(){
ScriptSessions.addFunctionCall(“showMessage”,message);
}
});
}

}

自动生成的MessagePush.js

if (typeof dwr == 'undefined' || dwr.engine == undefined) throw new Error('You must include DWR engine before including this file');

(function() {
  if (dwr.engine._getobject("MessagePush") == undefined) {
    var p;

    p = {};
    p._path = '/dwr/dwr';

    /** * @param {class java.lang.String} p0 a param * @param {function|Object} callback callback function or options object */
    p.onPageLoad = function(p0,callback) {
      return dwr.engine._execute(p._path,'MessagePush','onPageLoad',arguments);
    };

    /** * @param {class java.lang.String} p0 a param * @param {class java.lang.String} p1 a param * @param {function|Object} callback callback function or options object */
    p.sendMessageSingle = function(p0,p1,'sendMessageSingle',arguments);
    };

    /** * @param {class java.lang.String} p0 a param * @param {function|Object} callback callback function or options object */
    p.sendbroadcastMessage = function(p0,'sendbroadcastMessage',arguments);
    };

    dwr.engine._setobject("MessagePush",p);
  }
})();

可见,当我们在页面中使用MessagePush.sendMessageSingle(param); 调用服务器端Java的方法sendMessageSingle()时,实际上是执行是 dwr.engine._execute(p._path,‘MessagePush’,‘sendMessageSingle’,arguments);该请求同样被DwrServlet处理,然后在dwr.xml中查询到MessagePush的对应项目,然后根据配置信息,自己根据反射生成对象或者由Spring注入对象,然后调用方法sendMessageSingle() ,将处理结果返回给浏览器,最后执行回调函数. ​

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐