前言環(huán)境搭建建立工程jar包填裝下載dwrjar下載commons-loggingjar項(xiàng)目目錄webxmldwrxmljava文件jsp頁面調(diào)試運(yùn)行文字展示圖片展示解惑篇關(guān)于自動生成的js文件如何配置頁面腳本客戶端怎么調(diào)用服務(wù)器端方法總結(jié)
昨天晚上偶然咋慕課網(wǎng)上看到了一個(gè)DWR的視頻,一開始我還以為是DreamWaver的縮寫,后來發(fā)現(xiàn)我錯(cuò)了,原來人家是Direct Web Remoting的縮寫。
DWR說白了是一個(gè)用于改善web頁面與Java類交互的遠(yuǎn)程服務(wù)器端Ajax開源框架,可以幫助開發(fā)人員開發(fā)包含AJAX技術(shù)的網(wǎng)站。它可以允許在瀏覽器里的代碼使用運(yùn)行在WEB服務(wù)器上的JAVA函數(shù),就像它就在瀏覽器里一樣。
后來跟著慕課網(wǎng)上的那個(gè)視頻動手測試,發(fā)現(xiàn)錯(cuò)誤百出,視頻上的代碼和他本人講解的稍有出入,而且有點(diǎn)含糊不清的感覺。為了給自己一個(gè)交代,于是寫下這篇經(jīng)過本人親自測試的文章,希望不會誤人子弟,(^__^) 嘻嘻……
我個(gè)人覺得環(huán)境搭建的這個(gè)過程,對于新人而言,最好是能有一個(gè)清晰的項(xiàng)目目錄,這樣不至于讓人摸不著頭腦(這個(gè)文件放哪個(gè)目錄啊,這個(gè)依賴放哪啊等等)。
為了防止出現(xiàn)這些問題,我決定來個(gè)手把手教學(xué)。一步步搭建這個(gè)小項(xiàng)目。



這樣,一個(gè)純粹的javeee項(xiàng)目就創(chuàng)建好了。
接下來就需要添加項(xiàng)目依賴的jar包什么的了。這個(gè)過程也比較的簡單。下面分幾個(gè)小步驟來實(shí)現(xiàn)。
到官網(wǎng)http://directwebremoting.org/dwr/index.html。下載這個(gè)jar即可。 
官網(wǎng)上清晰的說明了dwr工作的時(shí)候需要依賴于commons-logging,所以還需要下載一下這個(gè)jar包。下載地址: http://commons.apache.org/proper/commons-logging/download_logging.cgi
把上面下載好的jar包放到剛才創(chuàng)建的項(xiàng)目的WebContent/lib目錄下。
依照dwr的功能:
瀏覽器可以調(diào)用服務(wù)器端的java方法。
那么我們不難理解,項(xiàng)目中有自己寫的java方法,有一個(gè)jsp頁面。然后項(xiàng)目本身添加一些配置(具體是web.xml和dwr.xml)。最后完整的項(xiàng)目目錄就是這樣了。 
是的,就這樣就足夠了。待會我還會講到為什么這樣就夠了。
大家寫javaweb的,對于web.xml一定是不陌生了。那么我也就不廢話了,看下面的配置代碼吧。
官網(wǎng)上示例<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> <!-- 使用服務(wù)器反轉(zhuǎn)AJAX --> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <!-- 是能夠從其他域請求true:開啟; false:關(guān)閉 --> <init-param> <param-name>crossDomainsessionSecurity</param-name> <param-value>false</param-value> </init-param> <!-- 允許遠(yuǎn)程調(diào)用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>大差不差,其實(shí)按照官網(wǎng)上的示例來進(jìn)行配置就足夠了,我添加的那些可以做下參考。
關(guān)于dwr.xml的配置,其實(shí)還是很需要技巧的。當(dāng)然了,這個(gè)小項(xiàng)目本身不需要配置得多么復(fù)雜,如果有興趣,建議還是到官網(wǎng)上自習(xí)的閱讀文檔,相信一定會讓你有所收獲。
我的配置(由于我的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> <!-- 這個(gè)標(biāo)簽可以寫也可以不寫,無所謂的--> <include method="Send"/> </create> </allow></dwr>這里需要特別注意的是create標(biāo)簽中的javascript屬性。這個(gè)值就作為你在頁面上直接調(diào)用的js的名稱,比如我這里寫的是DwrPush,那么待會我在jsp文件中寫js代碼的時(shí)候,就得這個(gè)名稱來寫,比如:
var data = document.getElementById("data").value;//這個(gè)DwrPush就是剛才聲明的javascript屬性的值,切記切記DwrPush.Send(data);$("#data").value = "";好了,下面開始寫被調(diào)用的后臺java文件了。這些代碼其實(shí)都是這么個(gè)套路,原理就是:
獲取到服務(wù)器上當(dāng)前在線的所有的session會話,然后組裝一下js代碼,最后發(fā)送給所有的這些用戶。
這個(gè)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(); // 構(gòu)建發(fā)送所需的JS腳本 ScriptBuffer scriptBuffer = new ScriptBuffer(); // 調(diào)用客戶端的js腳本函數(shù) scriptBuffer.appendScript("callback("); // 這個(gè)msg可以被過濾處理一下,或者做其他的處理操作。這視需求而定。 scriptBuffer.appendData(msg); scriptBuffer.appendScript(")"); // 為所有的用戶服務(wù) @SuppressWarnings("deprecation") Util util = new Util(sessions); util.addScript(scriptBuffer); }}我在看慕課網(wǎng)上那個(gè)視頻的時(shí)候就被那個(gè)老師給誤導(dǎo)了,他本人并沒有講清楚util.js和engine.js的來源或者如何放置。
今天我在官網(wǎng)上找到了答案。util.js和engine.js是dwr.jar中本來就存在的,但是使用的時(shí)候需要注意一下。相信大家看完這個(gè)圖就會明白了。 
那還等什么,咱們也來試一下吧。注意一下訪問的鏈接是在web.xml中配置好的,切記切記!!! 
果不其然,現(xiàn)在知道util.js和engine.js還有另外的那個(gè)生成的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>首次環(huán)境搭建</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!'); // 頁面加載的時(shí)候進(jìn)行反轉(zhuǎn)的激活 /* dwr.engine.setActiveReverseAjax(true); */ dwr.engine.setActiveReverseAjax(true) ; // 點(diǎn)擊頁面按鈕的時(shí)候觸發(fā)的方法 $("#button").click(function(){ // 此類即為根據(jù)java文件生成的js文件 var data = document.getElementById("data").value; DwrPush.Send(data); });});//////////////////////////////////////用于后臺調(diào)取的函數(shù)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' /> <input type='button' id="button" value="publish"></body></html>好了,萬事俱備,只欠東風(fēng)了。下面準(zhǔn)備測試一下吧。


最后需要注意的是我們可以在后臺的那個(gè)java方法中對于前臺傳過來的數(shù)據(jù)進(jìn)行深度的檢驗(yàn),過濾等等。這點(diǎn)視自己需求而定。
經(jīng)過了昨晚對于慕課網(wǎng)上的視頻的學(xué)習(xí),我認(rèn)識到了傳到授業(yè)解惑的重要性。
單純的演示誰不會呢?關(guān)鍵是把原理講清楚咯。讓別人知其然更知其所以然。這才能稱之為一個(gè)好老師。當(dāng)然了,那個(gè)老師其實(shí)也蠻棒棒的,下面我就把那位老師沒講清楚的地方大致的梳理一下吧,希望剛好能解決看到這篇文章的你的疑惑。
自動生成?其實(shí)這就是一句空談,子虛烏有的事嘛。剛才通過 http://localhost:8080/dwrtest/dwr/test/DwrPush 這個(gè)本地鏈接大家也看到了,只需要按照提示的來書寫就夠了,這個(gè)框架會自動的幫助我們處理這些問題,而不是真的有這么個(gè)項(xiàng)目目錄。
多么直觀啊,其中“/dwrtest/dwr/util.js”這些是下面的這個(gè)格式:
/您的項(xiàng)目名稱/dwr/util.js 后面的dwr/util.js是固定的表達(dá),項(xiàng)目名稱按照自己的需求來寫就行了。
通過剛才的js腳本配置,瀏覽器這端就可以調(diào)用WEB服務(wù)器的Java方法了。核心就是通過
<script type='text/javascript'src='/dwrtest/dwr/interfae/DwrPush.js'></script>來實(shí)現(xiàn)的。DwrPush就是我們寫的那個(gè)Java類,而這個(gè)Send函數(shù)就是類中的方法咯。
按照代碼一步步的看下去,發(fā)現(xiàn)Send方法中構(gòu)建了一段腳本調(diào)用了前端的一個(gè)函數(shù),然后發(fā)送給所有會話用戶。
這說明前后端已經(jīng)全部打通了。前后端都可以自由的調(diào)用。
最后,來總結(jié)一下本次實(shí)驗(yàn)的收獲。一方面是了解了服務(wù)器推送技術(shù)的實(shí)現(xiàn),另一方面讓我對于技術(shù)的看法有了更深的認(rèn)識“知其然,更要知其所以然”。
關(guān)于DWR,這里也只不過是蜻蜓點(diǎn)水,它有很多優(yōu)秀的設(shè)計(jì)值得我們?nèi)W(xué)習(xí)。
新聞熱點(diǎn)
疑難解答