【DWR系列01】-DWR簡介及入門例子


一、DWR簡介

  dwr是一個Ajax框架,官方網站:http://directwebremoting.org/dwr/,最新版本3.0.1,要求jdk1.6及以上。

  如下圖所示,可以通過DWR來調用Java方法,並通過DWR封裝的工具類來對頁面元素進行簡單處理:

  上面的展示是對Ajax的封裝,簡化了用戶的操作,當然最常用的還是逆向Ajax(需要DWR2.0及以上版本),就是俗稱的服務器端推送:

  逆向Ajax相對比較難一點,下面先展示js調用Java方法的例子。

二、DWR示例-js調用Java方法

2.1 創建Web項目

  創建Web項目,並將dwr-3.0.1-RELEASE.jarcommons-logging-1.2.jar放入WEB-INF/lib下,dwr-3.0.1-RELEASE.jar是DWR必須要的jar包,最新版本為3.0.1-RELEASE,它依賴commons-logging-1.2.jar日志包。最終項目結構如下:

  若使用Maven,則Maven坐標如下:

<dependency>
    <groupId>org.directwebremoting</groupId>
    <artifactId>dwr</artifactId>
    <version>3.0.1-RELEASE</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

  Maven創建Web項目查看(待續)。本項目使用jdk1.7,tomcat7搭建。

2.2 修改web.xml

  DWR的js調用Java代碼,本質上還是通過Ajax來訪問,因此需要在web.xml中配置DWR接收js請求的servlet,配置如下:

<?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>testweb</display-name>
    <servlet>
        <servlet-name>dwr-invoker</servlet-name>
        <!-- 接收js的Ajax請求的servlet -->
        <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>dwr-invoker</servlet-name>
        <!-- 攔截指定的URL -->
        <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

  若使用的不是jdk1.7及Tomcat7注意修改web.xml的頭信息,為低版本。

2.3 創建被調用的Java類

  創建一個普通的Java類即可,如下:

package yiwangzhibujian;

import java.util.Date;

/**
 * @author yiwangzhibujian
 */
@SuppressWarnings("deprecation")
public class HelloWorld{

    /**
     * 無參無返回值
     */
    public void helloNN(){
        System.out.println(new Date().toLocaleString() + " js訪問helloNN方法");
    }

    /**
     * 有參無返回值
     */
    public void helloYN(String name){
        System.out.println(new Date().toLocaleString() + " js訪問helloYN方法,name=" + name);
    }

    /**
     * 無參有返回值
     */
    public String helloNY(){
        System.out.println(new Date().toLocaleString() + " js訪問helloNY方法");
        return "Hello World!";
    }

    /**
     * 有參有返回值
     */
    public String helloYY(String name){
        System.out.println(new Date().toLocaleString() + " js訪問helloYY方法,name=" + name);
        return "Hello " + name;
    }
}

  通過DWR調用Java方法使用普通的Java類即可,不需要訪問servlet。 

2.4 創建DWR配置文件

  在WEB-INF根路徑下創建DWR的配置文件,dwr.xml

<!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
    "http://getahead.org/dwr/dwr30.dtd">

<dwr>
    <allow>
        <create creator="new" javascript="HelloWorld">
            <param name="class" value="yiwangzhibujian.HelloWorld" />
        </create>
    </allow>
</dwr>

  create=“new”,即通過默認的構造方法使用new來創建對象,javascript="HelloWorld",HelloWorld表示調用類的名稱,即在js中Java對象的名字,<param>即用來配置DWR訪問的類。簡單來說,value就是js要調用的類,javascript屬性即是為這個類起一個簡單的別名。

2.5 創建JSP頁面

  本示例簡單的在index.jsp中編寫:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path=request.getContextPath();
    String basePath=request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<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/HelloWorld.js'></script>
<style type="text/css">
td{
    border: solid 1px;
}
</style>
</head>

<body>
    <table>
        <tr>
            <td>無參無返回值</td>
            <td colspan="3"><input type="button" value="helloNN" onclick="helloNN();"></td>
        </tr>
        <tr>
            <td>有參無返回值</td>
            <td colspan="2"><input type="text" id="helloYNName"></td>
            <td><input type="button" value="helloYN" onclick="helloYN();"></td>
        </tr>
        <tr>
            <td>無參有返回值</td>
            <td><input type="button" value="helloNY" onclick="helloNY();"></td>
            <td colspan="2"><input type="text" id="helloNYValue"></td>
        </tr>
        <tr>
            <td>有參有返回值</td>
            <td><input type="text" id="helloYYName"></td>
            <td><input type="button" value="helloYY" onclick="helloYY();"></td>
            <td><input type="text" id="helloYYValue"></td>
        </tr>
    </table>
</body>
<script type="text/javascript">
//無參無返回值
function helloNN(){
    HelloWorld.helloNN();
}
//有參無返回值
function helloYN(){
    var name = dwr.util.getValue("helloYNName");
    HelloWorld.helloYN(name);
}
//無參有返回值
function helloNY(){
    HelloWorld.helloNY(function(data) {
        dwr.util.setValue("helloNYValue", data);
    });
}
//有參有返回值
function helloYY(){
    var name = dwr.util.getValue("helloYYName");
    HelloWorld.helloYY(name, function(data) {
        dwr.util.setValue("helloYYValue", data);
    });
}
</script>
</html>

  必須引入的兩個js,第二個js不是真實存在的js文件,而是項目啟動訪問后動態生成的js,這個js的名稱HelloWorld,需與dwr.xml配置文件中javascript屬性值一樣,以下兩個文件的順序不能變:

<script type='text/javascript' src='dwr/engine.js'></script>
<script type='text/javascript' src='dwr/interface/HelloWorld.js'></script>

  使用DWR還可以使用它的一個工具js:

<script type='text/javascript' src='dwr/util.js'></script>

  引入此js后,可以使用它的一些簡單的方法,比如獲取元素的值,設置元素的值等,也可以使用普通js或者jquery來獲取:

//獲取指定id元素的值
var name = dwr.util.getValue("helloYYName");
//設置指定id元素的值為data
dwr.util.setValue("helloYYValue", data);

  若不是用DWR的util工具,可以不需要引入util.js工具js。

+提示    

  engine.js在jar包中,具體位置為:org.directwebremoting包內

  util.js也在jar包中,具體路徑為:org.directwebremoting.ui.servlet包內

2.6 啟動項目訪問測試

  最終項目目錄結構如下:

  啟動項目后訪問:http://localhost:8080/dwr/,將有如下頁面:

  按順序測試並輸入指定的值,最終結果如下:

  控制台輸出內容如下:

  經測試無誤。

三、原理簡單分析

3.1.訪問頁面時

  當訪問帶有DWR頁面的時候,引入js的請求會被,匹配到web.xml中的DWR的servlet(org.directwebremoting.servlet.DwrServlet):

<servlet>
    <servlet-name>dwr-invoker</servlet-name>
    <!-- 接收js的Ajax請求的servlet -->
    <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>dwr-invoker</servlet-name>
    <!-- 攔截指定的URL -->
    <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

  servlet會動態創建engine.js文件,並根據dwr/interface/HelloWorld.js,這種特定路徑的文件名HelloWorld,去DWR配置文件dwr.xml中去查找相關配置:

<create creator="new" javascript="HelloWorld">
    <param name="class" value="yiwangzhibujian.HelloWorld" />
</create>

  查找到配置的對象后,並根據對象的所有方法動態創建HelloWorld對象,也會將所有方法生成相應的js方法,生成的HelloWorld.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("HelloWorld") == undefined) {
var p;

p = {};

p.helloNN = function(callback) {
return dwr.engine._execute(p._path, 'HelloWorld', 'helloNN', arguments);
};

p.helloNY = function(callback) {
return dwr.engine._execute(p._path, 'HelloWorld', 'helloNY', arguments);
};

p.helloYN = function(p0, callback) {
return dwr.engine._execute(p._path, 'HelloWorld', 'helloYN', arguments);
};

p.helloYY = function(p0, callback) {
return dwr.engine._execute(p._path, 'HelloWorld', 'helloYY', arguments);
};

dwr.engine._setObject("HelloWorld", p);
}
})();

  可以看到動態生成的對象包含java對象的所有方法,調用js方法會通過底層的Ajax調用相應的Java方法。

3.2 使用原因

  • DWR是開源免費的
  • 封裝Ajax實現,可以很方便的調用
  • 除此以外還有反向Ajax,即服務器推送功能,后續介紹

 

  這一篇簡單的介紹了DWR,並展示了一個js調用Java的例子,可以看出DWR對Ajax封裝的非常好,調用起來很方便。下面一篇將會介紹逆向Ajax的用法。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM