使用Dojo和JSON构建Ajax应用

 

简单意义上来说,Ajax可以用来在服务器端和WEB客户端之间交换数据,它是利用JavaScript来装载WEB页面的。更深一层来讲,它可以利用异步JavaScript脚本来避免页面请求刷新,让Request/Response过程更加明了。实现Ajax的方法有很多,最原始的办法是用JavaScript脚本来实现这个过程,此外,我们还可以用比较成熟的功能库,比如说Dojo.

Dojo是什么
Dojo是一个强大的JavaScript类库,利用它提供的许多简单的API去实现一些比较复杂的页面功能。其中,利用Dojo来实现HTTP Request/Response不能不说是他的一个最大的亮点。除了提供Ajax功能之外,Dojo还提供了字符串操作、DOM操作、页面拖拽支持、以及数据结构(如列表,队列,堆栈等)。

JSON是什么
JSON是一个Java类库,专门用来转换Java对象为标准字符串。当这个字符串被传至客户端之后,可以通过JavaScript的eval()方法来产生一个数组,这个数组里面包含了所有关于服务端Java对象的信息。

JSON的标准语法可以用来加密许多嵌入对象的结构,这种语法产生的结果比相应的XML要小不少,而且用来很方便的传入eval()函数处理,因此JSON是一个高效、快速的浏览器/服务器数据传输媒介。既然服务端代码可以以多种语言形式存在,JSON也提供了对C#,Python,PHP等语言的支持。

利用Dojo处理HTTP请求

在下面的例子中,我们用Dojo来实现一个简单的功能:当用户按下一个button之后,页面弹出一个来自服务端的欢迎信息。让
我们看看以下的部分代码:

Html代码 复制代码  收藏代码
  1. <html>     
  2. <body onLoad="onLoad();">     
  3. <head>     
  4.  <title>Example 1</title>     
  5.  <script language="javascript" src="js/dojo.js"></script>     
  6.  <script language="javascript">     
  7.   dojo.require("dojo.io.*");      
  8.   dojo.require("dojo.event.*");      
  9.      
  10.   function onLoad() {      
  11.    var buttonObj = document.getElementById("myButton");      
  12.    dojo.event.connect(buttonObj, "onclick",      
  13.           this, "onclick_myButton");      
  14.   }      
  15.      
  16.   function onclick_myButton() {      
  17.    var bindArgs = {      
  18.     url: "welcome.jsp",      
  19.     error: function(type, data, evt){      
  20.      alert("An error occurred.");      
  21.     },      
  22.     load: function(type, data, evt){      
  23.      alert(data);      
  24.     },      
  25.     mimetype: "text/plain",      
  26.     formNode: document.getElementById("myForm")      
  27.    };      
  28.    dojo.io.bind(bindArgs);      
  29.   }      
  30.  </script>     
  31. </head>     
  32. <body>     
  33. <form id="myForm">     
  34.  <input type="text" name="name"/>     
  35.  <input type="button" id="myButton" value="Submit"/>     
  36. </form>     
  37. </body>     
  38. </html>    
<html>  
<body onLoad="onLoad();">  
<head>  
 <title>Example 1</title>  
 <script language="javascript" src="js/dojo.js"></script>  
 <script language="javascript">  
  dojo.require("dojo.io.*");   
  dojo.require("dojo.event.*");   
  
  function onLoad() {   
   var buttonObj = document.getElementById("myButton");   
   dojo.event.connect(buttonObj, "onclick",   
          this, "onclick_myButton");   
  }   
  
  function onclick_myButton() {   
   var bindArgs = {   
    url: "welcome.jsp",   
    error: function(type, data, evt){   
     alert("An error occurred.");   
    },   
    load: function(type, data, evt){   
     alert(data);   
    },   
    mimetype: "text/plain",   
    formNode: document.getElementById("myForm")   
   };   
   dojo.io.bind(bindArgs);   
  }   
 </script>  
</head>  
<body>  
<form id="myForm">  
 <input type="text" name="name"/>  
 <input type="button" id="myButton" value="Submit"/>  
</form>  
</body>  
</html>  
 

首先,页面会导入Dojo库dojo.js,其中包含了所有必须的Dojo类。Dojo库类似于我们Java代码中的Package的概念,象这个例子中所描述的,此处导入了两个包:dojo.io包中含有一些相关的类,可以通过类似于XMLHTTPTransport的协议发出HTTP Request请求;dojo.event包则是用来为网页DOM对象提供一个统一的事件处理方式。

 

其次,需要注意的是,我们为button指定了一个onclick事件。传统的做法一般都是:

Html代码 复制代码  收藏代码
  1. <input type="submit" onclick="someFunc();"/>     
<input type="submit" οnclick="someFunc();"/>   

 

这样可以达到事件绑定的效果,但是遗憾的是,这种方式始终一次只能最多绑定一个事件。而例子中的dojo.event.connect()方法可以让我们关联到不同类中的多个function。例如此处,我们就将onclick_myButton作为myButton的处理句柄。

 

当onclick_myButton事件执行的时候,系统将会访问welcome.jsp页面,然后返回一个响应。dojo.io.bind()函数在这里起到了强大的作用,参数bindArgs是一个键值对数组。在这个例子中,我们指定了以下五对键值组合:
1、url:请求的目标URL;
2、mimetype:响应的类型类型,默认是"text/plain";
3、load:执行成功之后响应的方法;
4、error:执行发生错误的时候响应的方法;
5、formNode:一个Form的ID,其中的所有fields都将作为参数传递给url处理。

 

一旦dojo.io.bind(bindArgs)被处理,load或error中的事件将在指定情况下被触发,仔细观察,会发现这两个方法都有三个共有的参数:
1、type:函数的返回类型值,一般load()事件对应"load",而error()事件对应"error";
2、data:得到的响应内容,如果mimetype被指定为text/plain,data内容将是一个字符串响应;如果mimetype是text/json,data的内容理论上就是eval('('+responseReceived+')')的值,这里responseReceived即是响应返回过来的一个JSON字串。
3、evt:HTML DOM Event Object,用来标示一个事件的状态,如事件发生的对象,键盘鼠标的状态等。
除了例子中的这种绑定方式之外,还可以用dojo.event.connect()的来关联一个含有(type,data.evt)参数的function,如:

Js代码
var req = dojo.io.bind(bindArgs);      
  1. dojo.event.connect(req, "load"this"handleResponse");       
  2. //handleResponse即是一个预定义的JavaScript function     

 

 

注:
考虑到安全的因素,Fixfox不支持给bindArgs中url参数给定一个外部URL地址,而IE在这方面是没有限制的。

使用JSON传输Java对象
在前面的部分我们间接提到了JSON,它可以将Java对象通过eval()函数转换成一个Javascript理解的对象。

 一般我们喜欢在服务端写一些个POJO,而要把它传至Web客户端,可以通过JSON库提供的一些接口方法,如我们在一个名为Book的POJO类中额外添加一个方法Book.toJSONString()方法:

Java代码
public String toJSONString() throws JSONException {       
  1.   JSONObject jsonObj = new JSONObject();       
  2.   jsonObj.put("bookId"new Integer(this.bookId));       
  3.   jsonObj.put("title"this.title);       
  4.   jsonObj.put("isbn"this.isbn);       
  5.   jsonObj.put("author"this.author);       
  6.   return jsonObj.toString();       
  7. }   
public String toJSONString() throws JSONException {    
  JSONObject jsonObj = new JSONObject();    
  jsonObj.put("bookId", new Integer(this.bookId));    
  jsonObj.put("title", this.title);    
  jsonObj.put("isbn", this.isbn);    
  jsonObj.put("author", this.author);    
  return jsonObj.toString();    
} 

 

例子中的JSONObject类即将Book类的所有属性都提取出来,然后包装成为一个类似于java.util.Map的对象,最后通过toString()方法提供传输给Web端去eval()。同样,我们可以用另外一个JSONArray对象来包装相关信息为一个List,然后传输到Web客户端。

 

在Web客户端的实现,我们可以参考下面的例子:

Js代码
function trMouseOver(bookId) {      
  1.   getBookInfo(bookId);      
  2. }      
  3.      
  4. function trMouseOut(evt) {      
  5.   var bookDiv = document.getElementById("bookInfo");      
  6.   bookDiv.style.display = "none";      
  7. }      
  8.      
  9. function getBookInfo(bookId) {      
  10.   var params = new Array();      
  11.   params['bookId'] = bookId;      
  12.   var bindArgs = {      
  13.     url: "book.jsp",      
  14.     error: function(type, data, evt){      
  15.           alert("error");      
  16.          },      
  17.     mimetype: "text/json",      
  18.     content: params      
  19.   };      
  20.   var req = dojo.io.bind(bindArgs);      
  21.   dojo.event.connect(req, "load"this"populateDiv");      
  22. }      
  23.      
  24. function populateDiv(type, data, evt) {      
  25.   var bookDiv = document.getElementById("bookInfo");      
  26.   if (!data) {      
  27.     bookDiv.style.display = "none";      
  28.   } else {      
  29.     bookDiv.innerHTML = "ISBN: " + data.isbn +      
  30.                 "<br/>Author: " + data.author;      
  31.     bookDiv.style.display = "";      
  32.   }      
  33. }  
 

不同于前一个例,此例中的bingArgs多了一个content属性,用来存储一个键值对,然后作为参数传递给book.jsp页面去响应。在某种意义上来说,它有点类似于Form的fields提交。

 

下一次,再继续写Dojo的高级运用:Widget的制作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值