DWR3.0 服务器推送及解惑

前言

昨天晚上偶然咋慕课网上看到了一个DWR的视频,一开始我还以为是DreamWaver的缩写,后来发现我错了,原来人家是Direct Web Remoting的缩写。

DWR说白了是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJAX技术的网站。它可以允许在浏览器里的代码使用运行在WEB服务器上的JAVA函数,就像它就在浏览器里一样。

后来跟着慕课网上的那个视频动手测试,发现错误百出,视频上的代码和他本人讲解的稍有出入,而且有点含糊不清的感觉。为了给自己一个交代,于是写下这篇经过本人亲自测试的文章,希望不会误人子弟,(__) 嘻嘻……

环境搭建

我个人觉得环境搭建的这个过程,对于新人而言,最好是能有一个清晰的项目目录,这样不至于让人摸不着头脑(这个文件放哪个目录啊,这个依赖放哪啊等等)。

为了防止出现这些问题,我决定来个手把手教学。一步步搭建这个小项目。

建立工程

  • 打开您的eclipse,然后新建一个Dynamic Web Project。
建立工程
  • 然后写上您的项目名称,我这里写的是dwrtest。其他选项按照您自己的安装环境来选择吧,这一点应该是很基础的了。
写上项目名称
  • 选中“生成web.xml”选项,待会要进行配置。


    选中web.xml选项

这样,一个纯粹的javeee项目就创建好了。

jar包填装

接下来就需要添加项目依赖的jar包什么的了。这个过程也比较的简单。下面分几个小步骤来实现。

下载dwr.jar

到官网http://directwebremoting.org/dwr/index.html。下载这个jar即可。

下载dwr.jar

下载commons-logging.jar

官网上清晰的说明了dwr工作的时候需要依赖于commons-logging,所以还需要下载一下这个jar包。下载地址:
http://commons.apache.org/proper/commons-logging/download_logging.cgi

项目目录

把上面下载好的jar包放到刚才创建的项目的WebContent/lib目录下。

依照dwr的功能:

浏览器可以调用服务器端的java方法。

那么我们不难理解,项目中有自己写的java方法,有一个jsp页面。然后项目本身添加一些配置(具体是web.xml和dwr.xml)。最后完整的项目目录就是这样了。


完整的项目目录

是的,就这样就足够了。待会我还会讲到为什么这样就够了。

web.xml

大家写javaweb的,对于web.xml一定是不陌生了。那么我也就不废话了,看下面的配置代码吧。

  • 官网上示例
<servlet>
  <display-name>DWR Servlet</display-name>
  <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>
  • 我的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>dwrtest</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <listener>  
    <listener-class>org.directwebremoting.servlet.DwrListener</listener-class>  
  </listener> 
  
  <servlet>
      <servlet-name>dwr</servlet-name>
      <!-- version 2 * -->
      <!-- <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> -->
      <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
      <init-param>
          <param-name>debug</param-name>
          <param-value>true</param-value>
      </init-param>
      <!-- 使用服务器反转AJAX  -->
      <init-param>
          <param-name>activeReverseAjaxEnabled</param-name>
          <param-value>true</param-value>
      </init-param>
      <!-- 是能够从其他域请求true:开启; false:关闭 -->
      <init-param>
          <param-name>crossDomainSessionSecurity</param-name>
          <param-value>false</param-value>
      </init-param>
      <!-- 允许远程调用js -->
      <init-param>
          <param-name>allowScriptTagRemoting</param-name>
          <param-value>true</param-value>
      </init-param>
      
      <load-on-startup>1</load-on-startup>  
  </servlet>
  <servlet-mapping>
      <servlet-name>dwr</servlet-name>
      <url-pattern>/dwr/*</url-pattern>
  </servlet-mapping>
</web-app>

大差不差,其实按照官网上的示例来进行配置就足够了,我添加的那些可以做下参考。

dwr.xml

关于dwr.xml的配置,其实还是很需要技巧的。当然了,这个小项目本身不需要配置得多么复杂,如果有兴趣,建议还是到官网上自习的阅读文档,相信一定会让你有所收获。

我的配置(由于我的jave文件在utils包下的DwrPush.java,所以我可以这么配置。)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd">
<dwr>
    <allow>
        <create creator="new" javascript="DwrPush">
            <param name="class" value="utils.DwrPush"></param>
            <!-- 这个标签可以写也可以不写,无所谓的-->
            <include method="Send"/>
        </create>
    </allow>
</dwr>

这里需要特别注意的是create标签中的javascript属性。这个值就作为你在页面上直接调用的js的名称,比如我这里写的是DwrPush,那么待会我在jsp文件中写js代码的时候,就得这个名称来写,比如:

var data = document.getElementById("data").value;
//这个DwrPush就是刚才声明的javascript属性的值,切记切记
DwrPush.Send(data);
$("#data").value = "";

java文件

好了,下面开始写被调用的后台java文件了。这些代码其实都是这么个套路,原理就是:

获取到服务器上当前在线的所有的session会话,然后组装一下js代码,最后发送给所有的这些用户。

这个java类文件可以随意的放置,只要按照刚才的dwr.xml中声明的那样放置就行了。

package utils;

import java.util.Collection;

import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.proxy.dwr.Util;

public class DwrPush {
    
    @SuppressWarnings("deprecation")
    public static void Send(String msg){
        WebContext webContext = WebContextFactory.get();
        @SuppressWarnings("deprecation")
        Collection<ScriptSession> sessions = webContext.getAllScriptSessions();
        
        // 构建发送所需的JS脚本
        ScriptBuffer scriptBuffer = new ScriptBuffer();
        // 调用客户端的js脚本函数
        scriptBuffer.appendScript("callback(");
        // 这个msg可以被过滤处理一下,或者做其他的处理操作。这视需求而定。
        scriptBuffer.appendData(msg);
        scriptBuffer.appendScript(")");
        // 为所有的用户服务
        @SuppressWarnings("deprecation")
        Util util = new Util(sessions);
        util.addScript(scriptBuffer);
        
        
    }

}

jsp页面

我在看慕课网上那个视频的时候就被那个老师给误导了,他本人并没有讲清楚util.js和engine.js的来源或者如何放置。

今天我在官网上找到了答案。util.js和engine.js是dwr.jar中本来就存在的,但是使用的时候需要注意一下。相信大家看完这个图就会明白了。


官网提示

那还等什么,咱们也来试一下吧。注意一下访问的链接是在web.xml中配置好的,切记切记!!!


访问dwr/

果不其然,现在知道util.js和engine.js还有另外的那个生成的js文件怎么写了吧。


醍醐灌顶的设置

最后来完整的写一下jsp页面的代码吧。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首次环境搭建</title>
<script type='text/javascript' src='/dwrtest/dwr/util.js'></script>
<script type='text/javascript' src='/dwrtest/dwr/engine.js'></script>
  <script type='text/javascript' src='/dwrtest/dwr/interface/DwrPush.js'></script>
<script type="text/javascript" src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
<script>

$(document).ready(function(){
    alert('can get here!');
    // 页面加载的时候进行反转的激活
    /* dwr.engine.setActiveReverseAjax(true); */
    dwr.engine.setActiveReverseAjax(true) ;

    // 点击页面按钮的时候触发的方法
    $("#button").click(function(){
        // 此类即为根据java文件生成的js文件
        var data = document.getElementById("data").value;
        DwrPush.Send(data);
    });
});



//////////////////////////////////////用于后台调取的函数
function callback(msg){
    //alert('test!');
    $("#ul").html($("#ul").html()+"<br />"+msg);
}
</script>
</head>
<body>
<ul id="ul">

</ul>

<br/>
<hr>
<input type="text" id="data" name='data' />&nbsp;&nbsp;&nbsp;&nbsp;
<input type='button' id="button" value="publish">

</body>
</html>

调试运行

好了,万事俱备,只欠东风了。下面准备测试一下吧。

文字展示

文字展示篇

图片展示

上传图片试试

最后需要注意的是我们可以在后台的那个java方法中对于前台传过来的数据进行深度的检验,过滤等等。这点视自己需求而定。

解惑篇

经过了昨晚对于慕课网上的视频的学习,我认识到了传到授业解惑的重要性。

单纯的演示谁不会呢?关键是把原理讲清楚咯。让别人知其然更知其所以然。这才能称之为一个好老师。当然了,那个老师其实也蛮棒棒的,下面我就把那位老师没讲清楚的地方大致的梳理一下吧,希望刚好能解决看到这篇文章的你的疑惑。

关于自动生成的js文件?

自动生成?其实这就是一句空谈,子虚乌有的事嘛。刚才通过
http://localhost:8080/dwrtest/dwr/test/DwrPush
这个本地链接大家也看到了,只需要按照提示的来书写就够了,这个框架会自动的帮助我们处理这些问题,而不是真的有这么个项目目录。

如何配置页面脚本?

配置页面脚本

多么直观啊,其中“/dwrtest/dwr/util.js”这些是下面的这个格式:

/您的项目名称/dwr/util.js
后面的dwr/util.js是固定的表达,项目名称按照自己的需求来写就行了。

客户端怎么调用服务器端方法?

通过刚才的js脚本配置,浏览器这端就可以调用WEB服务器的Java方法了。核心就是通过

<script type='text/javascript'src='/dwrtest/dwr/interfae/DwrPush.js'></script>

来实现的。DwrPush就是我们写的那个Java类,而这个Send函数就是类中的方法咯。

按照代码一步步的看下去,发现Send方法中构建了一段脚本调用了前端的一个函数,然后发送给所有会话用户。

这说明前后端已经全部打通了。前后端都可以自由的调用。

总结

最后,来总结一下本次实验的收获。一方面是了解了服务器推送技术的实现,另一方面让我对于技术的看法有了更深的认识“知其然,更要知其所以然”。

关于DWR,这里也只不过是蜻蜓点水,它有很多优秀的设计值得我们去学习。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容