Dwr 实例教程

2024-02-16 04:32
文章标签 实例教程 dwr

本文主要是介绍Dwr 实例教程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者:  永恒の_☆ 地址:  http://blog.csdn.net/chenghui0317/article/details/9842873

一、Dwr的介绍

       Dwr 简称 Direct Web Remoting ,它是一个 Java Ajax远程调用的框架,利用这个框架开发可以让Ajax开发变得非常简单、快捷。 Dwr框架与匈奴开发人员在客户端都过javascript代码调用服务器段的java方法,这都依靠于服务器上运行的Dwr核心Servlet负责处理客户端的请求,将客户端请求委托到实际的java 对象中进行处理,并将结果返回给客户端。  另外Dwr能够很好的与spring集成,直接调用spring中注入的bean。

二、Dwr的准备条件

    dwr2.0.jar  下载地址:  http://download.csdn.net/detail/ch656409110/5894411

    commons-logging.jar (查看源码可以看到Dwr运行时依赖于common-logging库)

三、Dwr执行的流程

1、首先客户端发送一个javascript的请求,dwr识别该请求之后会将请求委托到Dwr中和核心Servlet;

2、核心Servlet 会根据请求的对象以及方法去WEB-INF 下的dwr.xml中找到具体的关联对象;

3、如果满足调用的条件,那么服务器会执行该方法,并返回对应的结果,这里返回的结果会被客户端发送请求的回调函数接收;

4、客户端收到返回结果之后,做出对应的处理,整个请求结束。

四、使用Dwr做一个简单的demo

1、建立Web 工程,添加Dwr的支持,这里以现有的支持struts2为基础的项目为例;

2、添加dwr配置文件,必须放在WEB-INF的分目录下,具体如下:

<?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="dwrDate">
      <param name="class" value="java.util.Date"></param>
    </create>
  </allow>
</dwr>

根目录是<dwr>标签,里面的<allow>表示允许的方法列表,配置每一个对象都是<create>来区分的。

    creator :表示创建方式,取值有new,bean等等,其中new表示新建,bean表示取现有的对象。

    javascript :表示在js客户端调用的对象引用,比如这里配置的对象是java.util.Date,那么dwrDate 就是创建的对象引用,等价于 java.util.Date dwrDate = new java.util.Date();

<create>里面的<param> 表示指定创建对象的声明;

    name :表示声明的name的形式;

    value :表示根据name绑定的具体值; 

    name取值有class,beanName等等,其中 name="class" 表示value中绑定的是类的完整限定名, name="beanName" 表示value绑定的是spring中注入的对象的引用。 

3、修改web.xml 配置文件,配置Dwr的核心servlet,具体如下:

  <!-- 配置dwr框架的核心servlet --><servlet><servlet-name>dwr</servlet-name><servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class><!-- 添加调试模式,方便调试方法,正式发布的时候可以改为false 默认值为fasle--><init-param><param-name>debug</param-name><param-value>true</param-value></init-param></servlet><servlet-mapping><servlet-name>dwr</servlet-name><url-pattern>/dwr/*</url-pattern></servlet-mapping>

如上配置,所有以/dwr/ 结尾的请求都会被DwrServlet匹配 执行相应的请求。

好了,接下可以调试我们的Dwr了,启动服务器,打开浏览器输入: http://localhost:8080/house/dwr   (这个是Dwr入口,将展示所有在dwr.xml中配置完的对象列表,点击进去会看到 配置的对象允许方法的方法等)

结果报错,具体如下:

严重: Allocate exception for servlet dwr 
org.xml.sax.SAXException: Failed to resolve: arg0=-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN arg1=http://getahead.org/dwr/dwr30.dtd 

这是因为添加的jar包是2.0版本的,但是却引用了3.0的dtd文件,所以报错了,改为如下配置即可:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://www.getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
  <allow>
    <create creator="new" javascript="dwrDate">
      <param name="class" value="java.util.Date"></param>
    </create>
  </allow>
</dwr>

修改之后再次打开dwr地址,又报错了: 

Struts Problem Report 

Struts has detected an unhandled exception: 
Messages:      
There is no Action mapped for namespace / and action name dwr. 
Stacktraces 
There is no Action mapped for namespace / and action name dwr. - [unknown location] 

意思就是说找不到namespace为 / 并且action名称为dwr的Action 类,这里是因为struts2 的核心控制器StrutsPrepareAndExecuteFilter,拦截了所有的请求去找action方法了,所以404。

现在要在struts.xml中过滤掉所有的以 /dwr/ 这样子结尾的请求才行,添加一个不包括访问的参数即可,具体如下:
    <!-- 核心控制器在处理页面跳转时是拦截所有跳转,当跳转到house/dwr/下进行方法测试时,struts核心控制把它看成是一个action,所以就跳不过去了,可以通过配置一个常量struts.action.excludePattern,值里面用正则表达式匹配,.  表示除了换行以外其他所有的字符 *  表示字符或表达式出现的次数零次或多次    --><constant name="struts.action.excludePattern" value="/dwr.*"></constant>
保存struts.xml 再次启动服务器,打开地址,效果如下:


这个就表示 我们在dwr.xml中配置的dwrDate对象成功了。点击dwrDate超链接,效果如下:


这里面列出了所有的java.util.Date中所有允许访问的放,点击每一个execute 表示测试该方法。。

ok....现在在Action类中添加一个方法dwrDemo() 并且对应创建一个dwrDemo.jsp 专门用于测试dwr。

具体如下:

<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ include file="/common/taglib.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>永恒租房 - 首页</title><!-- 这三个js导入项必不可少 --><!-- 每一个对象都会有以一个对象为名称的那个js库 --><script type='text/javascript' src='${ctx}/dwr/interface/dwrDate.js'></script><!-- Dwr 引擎库 --><script type='text/javascript' src='${ctx}/dwr/engine.js'></script><!-- Dwr 工具库 --><script type='text/javascript' src='${ctx}/dwr/util.js'></script><script>window.onload = function(){            //输出当前时间//需要说明的是,如果在客户端输出dwrDate 对象将返回undefined,除非调用完整的函数(也就是服务器端的方法)才会调用成功//客户端接收参数的方法都是通过回调函数来获取的。dwrDate.getYear(function(data){//在回调函数里面不能使用document.write("")输出,因为第一次输出之后,浏览器会一直处于加载的状态,f12看不出在加载什么,然后后面的document.write("")也不会再执行了。document.getElementById("showTime").innerHTML += 1900 + data + " 年 ";});dwrDate.getMonth(function(data){document.getElementById("showTime").innerHTML += 1 + data + " 月 ";});dwrDate.getDate(function(data){document.getElementById("showTime").innerHTML += data + " 日 ";});};</script>
</head>
<body>
<div id="showTime">当前时间:</div>
</body>
</html>
在地址栏输入:  http://localhost:8080/house/house/dwrDemo.action  ,结果alert了三个文本都是 Session Error 。

这里需要在dwrServlet中添加参数crossDomainSessionSecurity,具体配置如下:

<!-- 这个crossDomainSessionSecurity必须配置,应该是跨区域提交设置,默认是ture,如果不设置为false就会报错:Session Error --><init-param><param-name>crossDomainSessionSecurity</param-name>   <param-value>false</param-value>   
  </init-param>

然后再次重启服务器打开dwrDemo页面,效果如下: 


接下来,新创建一个类,里面有setValue(),getValue()等等方法,具体如下:

private String value = "default";
  
  public String getValue(){
    return value;
  }
  
  public void setValue(String value){
    this.value = value;
  }

然后在dwr.xml中自己再配置一个自己定义的对象,具体如下:

         <create creator="new" javascript="houseDwrBiz"><param name="class" value="com.struts2.biz.impl.HouseBizImpl"></param><include method="getValue,setValue"/><exclude method="getListPage"/></create>
在配置文件中 ,新添加了 <include>和<exclude>标签,他们分别表示该对象中允许客户端访问的方法,和不允许访问的方法。

好了,然后打开服务器 启动调试窗口,结果直接报错,具体如下: 

[ERROR] [http-apr-8080-exec-5] - Failed to add creator: type=new, javascript=houseDwrBiz 
java.lang.IllegalArgumentException: The Creator houseDwrBiz uses mixed include and exclude statements

意思是说 <include>和<exclude>不能共存,也就是一山不容二虎。

并且实践证明,<include>标签里面只能绑定一个方法,如果配置了<include>那么其他就都不允许访问,如果配置了<exclude>那么其他的方法就都允许访问。

是否允许访问可以在调试页面中的方法下面注明,如下:

(Warning: getListPage() is excluded: Method access is denied by rules in dwr.xml. See below ) 

这样子的话 每允许访问一个方法就要加一个<inclue>标签,具体如下:

         <create creator="new" javascript="houseDwrBiz"><param name="class" value="com.struts2.biz.impl.HouseBizImpl"></param><include method="getValue"/><include method="setValue"/><!-- <exclude method="getListPage"/> --></create>

添加测试的页面,具体如下:
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ include file="/common/taglib.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>永恒租房 - 首页</title><!-- 这三个js导入项必不可少 --><!-- 每一个对象都会有以一个对象为名称的那个js库 --><script type='text/javascript' src='${ctx}/dwr/interface/dwrDate.js'></script><script type='text/javascript' src='/house/dwr/interface/houseDwrBiz.js'></script><!-- Dwr 引擎库 --><script type='text/javascript' src='${ctx}/dwr/engine.js'></script><!-- Dwr 工具库 --><script type='text/javascript' src='${ctx}/dwr/util.js'></script><script>//这里故意命名为setValue getValue ,看是否与houseDwrBiz冲突,事实发现没有问题function setValue(){var value = document.getElementById("set").value;houseDwrBiz.getValue(value,function(data){//set success});}function getValue(){houseDwrBiz.getValue(function(data){//get successdocument.getElementById("get").value = data;});}</script>
</head>
<body>
<div id="showTime">当前时间:</div>
<input id="set" value=""/><input type="button" value="setValue" onclick="setValue()"/><br/>
<input id="get" value=""/><input type="button" value="getValue" onclick="getValue()"/></body>
</html>

实践证明,每一个houseDwrBiz 发出的请求都是多例的,都会重新产生一个新的实例,以为上面例子 我先setValue ,然后在getValue 得到依旧是default。

上面都是一些非常简单的例子,如果涉及比如复杂的需求,比如接受一个集合 或者保存一个对象到服务器呢?接下里简单介绍下如何去做。

HouseBizImpl 添加方法,具体如下:

public int saveDwrHouse(House house){
    return house==null?0:1; //1 成功,0失败
  }  public List<House> getDwrHouseList(int dwrId){
    List<House> houseList = new ArrayList<House>();
    House house = new House();
    if(dwrId==1){
      house.setId(1);
      house.setDescription("好房子便宜出租!");
      house.setPubDate(new Date());
      house.setTitle("便宜的房子");
      house.setContact("132312312");
    }else{
      house.setId(2);
      house.setDescription("好房子确实很便宜!");
      house.setPubDate(new Date());
      house.setTitle("全区最低价格特价出租");
      house.setContact("123456789");
    }
    houseList.add(house);
    
    return houseList;
  }
同时,dwr.xml也要把这两个方法 包含进去,否则不允许访问。具体如下:
<create creator="new" javascript="houseDwrBiz">
      <param name="class" value="com.struts2.biz.impl.HouseBizImpl"></param>
      <include method="getValue"/>
      <include method="setValue"/>
      <!-- <exclude method="getListPage"/> -->
      <include method="saveDwrHouse"/>
      <include method="getDwrHouseList"/>
    </create>
    <convert converter="bean" match="com.struts2.entity.House"></convert>
在<create>标签的同级目录多了一个<convert>转换器标签,

converter :转换器类型,一般是javabean,直接指定converter="bean"就好了;

match :表示转换器匹配的类的完整限定名。

配置完毕之后,然后再在dwrDemo.jsp调用,具体如下:

//得到house集合
      houseDwrBiz.getDwrHouseList(1,function(data){
        if(data != null){
          for(var i=0; i<data.length; i++){
            document.getElementsByTagName("body")[0].innerHTML = "id:"+ data[i].id + "。<br/>"
              + "description:" + data[i].description + "。<br/>"
              + "attachUrl:" + data[i].attachUrl + "。<br/>"
              + "contact:" + data[i].contact + "。<br/>"
              + "floorage:" + data[i].floorage + "。<br/>";
          }
        }
      });
      //保存house对象
      var house = {id:111,contact:"12345"};
      houseDwrBiz.saveDwrHouse(house,function(data){
        alert(data==1?"添加成功":"添加失败");
      });
测试可知  getDwrHouseList返回的是一个json格式的集合,同样保存house对象的时候也要手动封装数组传递。

    现在对Dwr一定已经有一定的理解,这些小demo虽然非常简单,即使不使用强大的Dwr也可以非常容易的实现上面的功能,但是这些小程序是为了更加友好的体验和使用Dwr框架给我们带来的好处。 

这篇关于Dwr 实例教程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/713491

相关文章

YOLOv8改进 | Conv篇 | YOLOv8引入DWR

1. DWR介绍 1.1  摘要:当前的许多工作直接采用多速率深度扩张卷积从一个输入特征图中同时捕获多尺度上下文信息,从而提高实时语义分割的特征提取效率。 然而,这种设计可能会因为结构和超参数的不合理而导致多尺度上下文信息的访问困难。 为了降低多尺度上下文信息的绘制难度,我们提出了一种高效的多尺度特征提取方法,将原始的单步方法分解为区域残差-语义残差两个步骤。 在该方法中,多速率深度扩张卷积

React入门实例教程

文章转自:阮一峰 现在最热门的前端框架,毫无疑问是 React 。 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑。 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西

DWR+SpringMVC整合的3种方式之三

方式三:这种方式和方式二差不多,主要使用annotation配置和注解  说明:这种的耦合度也是和方式二差不多,本人最推荐用方式一,写的清楚,配置也清楚。这种方式的时候也遇到了一个很无语的问题,我原来使用的是maven下载的dwr-3.0.M1.jar包,然后运行jetty没错,显示jsp的时候就一直报下面这个错误: org.springframework.beans.factory.p

web前端开发实例教程:从基础到进阶的全方位探索

web前端开发实例教程:从基础到进阶的全方位探索 在数字化时代,web前端开发已成为构建互联网应用不可或缺的一环。本文旨在通过实例教程的形式,带领读者从基础到进阶,全方位探索web前端开发的奥秘。我们将从四个方面、五个方面、六个方面和七个方面展开详细的讲解,让你在学习过程中充满困惑与挑战,同时激发你的学习热情和创造力。 四个方面:前端基础知识的构建 首先,我们需要掌握HTML、CSS和Jav

刷机维修进阶教程-----红米k30 nv损坏故障 修复实例教程步骤解析

小米红米系列机型在米8起始就有了串码校验。不得随意更改参数限制。不同于其他机型,可以任意刷入同芯片的基带qcn来修复基带和串码丢失。米系列刷入同芯片基带qcn会提示nv损坏故障。是因为有串码校验。一般在于格机或者全檫除分区后写新参数出现的故障。 这种解决方法通常有两种  第一种就是软修复。通过一些步骤进行修复参数,可以保持双串码【教程以修复双串码为例】 第二

这是一篇让你少走弯路的 JNI/NDK 实例教程

作者: 夏至 欢迎转载,但保留这段申明 http://blog.csdn.net/u011418943/article/details/79449108 关于 JNI 的基础就不多说了,这篇文章主要讲解如何在 AS 中用 ndk-build 和 用 cmake 去构建我们的 JNI 工程,并总结他们的特点以及优缺点。 本文代码链接:https://github.com/LillteZhe

Python Lambda函数的应用实例教程

在Python编程中,lambda函数是一种简洁且强大的工具,用于创建小型匿名函数。它们在需要快速定义简单函数时特别有用。本文将详细介绍lambda函数的语法及其多种应用实例,帮助读者更好地理解和使用lambda函数。 一、lambda函数的基本概念 1.1 什么是lambda函数 lambda函数,也称为匿名函数,是一种无需命名的简单函数。它们使用lambda关键字定义,并且通常

在Android中扫描wifi热点演示实例教程

早上发了一段扫描wifi热点的代码,有同学反馈说编译不通过,晚上有点时间,重新试了一下,发现没啥问题,想汇总下测试过程,给需要的人参考。1、首先新建了布局模板XML文件vifi.xml,代码很简单,如下: <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/

实例教程六:创建数据库与完成数据添删改查--第一种写法

短信小助手(附源码)http://www.eoeandroid.com/thread-207835-1-1.html 备忘录+SQLite的实现http://www.eoeandroid.com/thread-208013-1-1.html 音乐波形图http://www.eoeandroid.com/thread-207796-1-1.html <?xml version="1.0" e

实例教程四:采用Pull解析器解析和生成XML内容

Android——activity生命周期Demohttp://www.eoeandroid.com/thread-207556-1-1.html Android——service生命周期Demohttp://www.eoeandroid.com/thread-207558-1-1.html android spinner 基础小实例http://www.eoeandroid.com/thre