zoukankan      html  css  js  c++  java
  • 【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的用法。

  • 相关阅读:
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-17 MyBatis 数据库逆向生成工具
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-16 数据源连接数详解
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-14 数据层HikariCP与MyBatis整合
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-13 HikariCP数据源简述
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-12 SpringBoot自动装配简述
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-10 聚合工程整合SpringBoot
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-9 数据库物理外键移除原因讲解
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-8 生产环境增量与全量脚本迭代讲解
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-7 PDMan数据库建模工具使用
    阶段一-01.万丈高楼,地基首要-第2章 单体架构设计与准备工作-2-6 构建聚合工程-2
  • 原文地址:https://www.cnblogs.com/yiwangzhibujian/p/6145371.html
Copyright © 2011-2022 走看看