Java之Ajax技术

ajax(asynchronouse javascript and xml) 异步的javascript 和 xml(现在常把xml换成json):

ajax是2005年提出的,在2006,2007年迅速的发展,目前很多网站都使用了ajax技术,在招聘软件工程师时,ajax技术是必须要求掌握的。ajax技术包含了几种技术:javascript、xml、css、xstl、dom、xhtml和XMLHttpRequest七种技术,所以ajax就像是粘合剂把七种技术整合到一起,从而发挥各个技术的优势,威力惊人。[新瓶装旧酒,组合拳]ajax是一个与服务端语言无关的技术. 即可以使用在(php/java ee/.net网站/ asp)ajax可以给客户端返回三种格式数据(文本格式 ,xml , json格式)

为什么ajax会如此流行,必然有它的道理。ajax技术解决了很多其它技术解决不了的问题,比如:

(1)页面无刷新的动态数据交换

(2)局部刷新页面【验证用户名唯一】

(3)界面的美观  【增强用户体验】

(4)对数据库的操作

(5)可以返回简单的文本格式,也可以返回 xml文件格式, json数据格式

ajax技术的意义:

互联网的连接是不稳定,谁也不愿意看着自己的电脑从服务器一点一滴的下载数据,那么,ajax是不是解决了这个问题呢,说实话,与其说ajax解决了这个问题,倒不如它只是掩盖了这个问题,它只是在服务器和客户端之间充当了一个缓冲器,让用户误以为服务没有中断。精确的说,ajax并不能提高从服务器端下载数据的速度,而只是使这个等待不那么令人沮丧。但是正是这一点就足以产生巨大的影响和震动,它实际上也对桌面软件产生了巨大的冲击。

ajax在什么地方用的多

1 动态加载数据,按需取得数据。【树形菜单、联动菜单…/省市联动】

2 改善用户体验。【输入内容前提示、带进度条文件上传…】

3 电子商务应用。 【购物车、邮件订阅…】

4 访问第三方服务。 【访问搜索服务、rss阅读器】

ajax 的运行原理分析:

Java之Ajax技术

Java之Ajax技术

PS:最重要的就是要弄透这四道线,其中4号线需要一个回调函数来实现。

Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。XMLHttpRequest是ajax的核心机制,它是在IE5中首先引入的,是一种支持异步请求的技术。简单的说,也就是javascript可以及时向服务器提出请求和处理响应,而不阻塞用户。达到无刷新的效果。

     我们先来看看XMLHttpRequest这个对象的属性。

它的属性有:

onreadystatechange  每次状态改变所触发事件的事件处理程序。

responseText     从服务器进程返回数据的字符串形式。

responseXML    从服务器进程返回的DOM兼容的文档数据对象(document)。

status           从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)

status Text       伴随状态码的字符串信息

 readyState       对象状态值

0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)

1 (初始化) 对象已建立,尚未调用send方法

2 (发送数据) send方法已调用,但是当前的状态及http头未知

3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,

4 (完成) 数据接收完毕,此时可以通过通过responseXml和responseText获取完整的回应数据

  1. 数据的布局刷新

使用ajax与服务器通信的的步骤

创建一个XMLHttpRequest对象(第一道线)

不同的浏览器创建 XMLHttpRequest 对象的方法是有差异的.我们使用js 的try..catch..

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function getXmlHttp()
 {
      var xmlHttp;  
      try{
    // Firefox, Opera 8.0+, Safari
    xmlHttp=new XMLHttpRequest();}
    catch (e){
    // Internet Explorer
   try{
       xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");}
   catch (e){
      try{
             xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");}
      catch (e){
         alert("您的浏览器不支持AJAX!");
         return false;}}
    }}

创建url,data,通过 send(),发送请求。(第二道线)

服务器端接收 ajax的请求,做相应处理(操作数据库),然后返回结果。(第三道线)

客户端通过xmlHttpRequest的属性 reponseText , responseXML 取的数据,然后就完成局部刷新当前页面任务。(第四道线)

经典案例:

■ ajax经典案例—无刷新验证用户名

在用户注册时:

1 传统的方法是把用户填写的所有信息都提交到服务器,如果用户名重复,就会出异常。

2 如果使用ajax我们可以只提交用户名,确认用户名是否存在,再让用户点击注册。

配置文件(仅使用了servlet):

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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">
  <servlet>
     <servlet-name>ZMC</servlet-name>
     <servlet-class>com.Register</servlet-class>
  </servlet>
  <servlet-mapping>
     <servlet-name>ZMC</servlet-name>
     <url-pattern>/register</url-pattern>
  </servlet-mapping>
</web-app>

服务端:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class Register extends HttpServlet {
 
private static final long serialVersionUID = 1L;
 
    public Register() {
        super();
        // TODO Auto-generated constructor stub
    }
 
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
 
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
    if(!request.getParameter("user").equals("zmc")){
     response.getWriter().println("这个名字可以注册");//三号线
    }
    else{
     response.getWriter().println("这个名字不可以注册");//三号线
    }
}
}

客户端请求页面:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<%@ 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>无刷新验证用户名</title>
<script type="text/javascript">
//创建ajax引擎
//原理图中的一号线
function getXmlHttpObject(){
var xmlHttpRequest;
//不同的浏览器获取对象XmlHttpRequest 对象方法不一样
if(window.ActiveXObject){
xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");
}else{
xmlHttpRequest=new XMLHttpRequest();
}
return xmlHttpRequest;
}
 
var myXmlHttpRequest=null;//设置全局变量
//验证用户名是否存在
function checkName(){
myXmlHttpRequest=getXmlHttpObject();
//判断XMLHttpRequest对象是否创建成功
if(myXmlHttpRequest){
//通过myXmlHttpRequest对象发送请求到服务器的某个页面
//第一个参数表示请求的方式, "get" / "post"
//第二个参数指定url,对哪个页面发出ajax请求(本质仍然是http请求)
//第三个参数表示 true表示使用异步机制,如果false表示不使用异步
var data="user="+$('username').value;
var url="/AjaxDemo/register";
//打开请求.
myXmlHttpRequest.open("post",url,true);
myXmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
myXmlHttpRequest.setRequestHeader("RequestType","ajax");  
//指定回调函数.chuli是函数名
//注意在Ajax中函数是调用,函数()是引用函数地址
//状态改变的事件触发器,共四种状态
myXmlHttpRequest.onreadystatechange=chuli;
//真的发送请求,如果是get请求则填入 null即可
//如果是post请求,则填入实际的数据
//这就是原理图中的二号线
//如果是get方法,参数写null
myXmlHttpRequest.send(data); 
}
}
 
//回调函数
//一次请求回调函数会被调用四次,分为四种状态,我们关心的是第四种状态即:完成
//原理图中的四号线
function chuli(){
//window.alert("处理函数被调回"+myXmlHttpRequest.readyState);
//我要取出从registerPro.php页面返回的数据
if(myXmlHttpRequest.readyState==4){//最好把响应状态码为200也加入判断
//取出值,根据返回信息的格式定.text
//window.alert("服务器返回"+myXmlHttpRequest.responseText);
$('myRes').value=myXmlHttpRequest.responseText;
}
}
 
//这里我们写一个函数,一般根据id取元素函数名都写为$
function $(id){
return document.getElementById(id);
}
 
</script>
</head>
<body>
<!--
onkeyup:键入一个字符便会触发它,在这个例子中便是调用checkName()函数。
-->
<form action="???" method="post">
    用户名字:<input type="text"  onkeyup="checkName();"  name="username1" id="username">
    <input type="button" onclick="checkName();"  value="验证用户名">
    <input style="border-width: 0;color: red" type="text" id="myRes">
    <br/>
    用户密码:<input type="password" name="password"><br>
    电子邮件:<input type="text" name="email"><br/>
    <input type="submit" value="用户注册">
    </form>
     <form action="???" method="post">
    用户名字:<input type="text" name="username2" >
    <br/>
    用户密码:<input type="password" name="password"><br>
    电子邮件:<input type="text" name="email"><br/>
    <input type="submit" value="用户注册">
    </form>
</body>
</html>

响应结果图:

Java之Ajax技术

PS:使用get方式发出请求,如果提交的用户名不变化,浏览器将不会真的发请求,而是缓存取数据., url解决方法 

  1. url 后带一个总是变化的参数,比如当前时间
 
1
var url="/ajax/registerProcess.php?mytime="+new  Date()+"&username="+$("username").value;
  1. 在服务器回送结果时,禁用缓存.

//这里两句话很重要,第一讲话告诉浏览器返回的数据是xml格式

header(“Content-Type: text/xml;charset=utf-8”);

//告诉浏览器不要缓存数据

header(“Cache-Control: no-cache”);

AJAX 可以在php项目,java ee项目,.net项目使用。在服务器端的业务逻辑层使用何种服务器端语言都可以。

从服务器端接收数据的时候,那些数据必须以浏览器能够理解的格式来发送。服务器端的编程语言一般以如下 3 种格式返回数据:Text(又称Html格式)、XML、JSON。

返回Html格式

HTML 由一些普通文本组成。如果服务器通过 XMLHttpRequest 发送 HTML, 文本将存储在 responseText 属性中。

不必从 responseText 属性中读取数据。它已经是希望的格式,可以直接将它插入到页面中。

插入 HTML 代码最简单的方法是更新这个元素的 innerHTML 属性。

innerHTML 并非 DOM 标准。

■ 返回xml格式优点:

XML 是一种通用的数据格式。不必把数据强加到已定义好的格式中,而是要为数据自定义合适的标记。利用 DOM 可以完全掌控文档。

缺点:如果文档来自于服务器,就必须得保证文档含有正确的首部信息。若文档类型不正确,那么 responseXML 的值将是空的。当浏览器接收到长的 XML 文件后, DOM 解析可能会很复杂

PS:不管是返回的何种类型,影响的只是三四号线

上面的那个例子便是返回了text格式,现在还是拿上面那个例子返回xml 格式:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function chuli(){
if(myXmlHttpRequest.readyState==4){
 
//看看如果取出 xml格式数据,返回的是document对象,xml //dom
//获取mes节点
var mes=myXmlHttpRequest.responseXML.getElementsByTagName("mes");
//取出mes节点值
//mes[0]->表示取出第一个mes节点
//mes[0].childNodes[0]->表示第一个mes节点的第一个子节点
var mes_val=mes[0].childNodes[0].nodeValue;
$('myres').value=mes_val;
}
}
//这里两句话很重要,第一讲话告诉浏览器返回的数据是xml格式
header("Content-Type: text/xml;charset=utf-8");
//告诉浏览器不要缓存数据
header("Cache-Control: no-cache");
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
    if(!request.getParameter("user").equals("zmc")){
     response.getWriter().println("<res><mes>用户名不可以用,对不起</mes></res>");//三号线
    }

返回JSON格式:(推荐)

JSON 只是一种文本字符串。它被存储在 responseText 属性中。为了读取存储在 responseText 属性中的 JSON 数据,需要根据 JavaScript 的 eval 语句。函数 eval 会把一个字符串当作它的参数。然后这个字符串会被当作 JavaScript 代码来执行。因为 JSON 的字符串就是由 JavaScript 代码构成的,所以它本身是可执行的

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
String str="{'ceshi':'这个名字可以注册'}";
String str2="{'ceshi':'这个名字不可以注册'}";
    if(!request.getParameter("user").equals("zmc")){
     response.getWriter().println(str);//三号线
    }
    else{
     response.getWriter().println(str2);//三号线
    }
}
}
function chuli(){
if(myXmlHttpRequest.readyState==4){
//取出值,根据返回信息的格式json字符串 //window.alert("服务器返回"+myXmlHttpRequest.responseText);
var str = myXmlHttpRequest.responseText;
var json = eval("("+str+")");
$('myRes').value=json.ceshi;
}

小结:

当一个ajax请求到服务器,服务器可以根据需求返回 三种格式的数据,那么我们应当选择哪一个?

  1. 如果你的项目经理没有特殊的要求,建议使用json
  2. 若应用程序不需要与其他应用程序共享数据的时候, 使用 HTML 片段来返回数据时最简单的
  3. 如果数据需要重用, JSON 文件是个不错的选择, 其在性能和文件大小方面有优势
  4. 当远程应用程序未知时, XML 文档是首选, 因为 XML 是 web 服务领域的 “世界语”

■ ajax经典案例—省市联动

ajax一个最重要的用途就是,动态的从服务器取需要的数据,并在页面无刷新的显示,我们来看一个经典的用法:省市联动菜单:

1 传统的b/s中,显示省市联动菜单是一次性把数据全部取出,并在客户端显示,这样做数据传输量大,不灵活。

2 使用ajax技术,可以根据用户需求从服务器取数据,当用户点击某个按钮时,才从服务器取数据并显示,灵活。让学生从数据库取出数据,县城级别联动做出.

ajax的省市联动案例(如何动态的从服务器取得数据),这里只贴了一部分代码:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
function getCities(){
myXmlHttpRequest=getXmlHttpObject();
if(myXmlHttpRequest){
var url="/ajax/showCitiesPro.php";//post
var data="province="+$('sheng').value;
myXmlHttpRequest.open("post",url,true);//异步方式
myXmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//指定回调函数
myXmlHttpRequest.onreadystatechange=chuli;
//发送
myXmlHttpRequest.send(data);
}
}
function chuli(){
if(myXmlHttpRequest.readyState==4){
if(myXmlHttpRequest.status==200){
//取出服务器回送的数据
var cities=myXmlHttpRequest.responseXML.getElementsByTagName("city");
$('city').length=0;
var myOption=document.createElement("option");
myOption.innerText="--城市--";
//添加到
$('city').appendChild(myOption);
//遍历并取出城市
for(var i=0;i<cities.length;i++){
var city_name=cities[i].childNodes[0].nodeValue;
//创建新的元素option
var myOption=document.createElement("option");
myOption.value=city_name;
myOption.innerText=city_name;
//添加到
$('city').appendChild(myOption);
}
}
}
}
//这里我们写一个函数
function $(id){
return document.getElementById(id);
}
</script>
</head>
<body>
<select id="sheng" onchange="getCities();">
    <option value="">---省---</option>
    <option value="zhejiang">浙江</option>
    <option value="jiangsu" >江苏</option>
    <option value="sichuan" >四川</option>
    </select>
    <select id="city">
    <option value="">--城市--</option>
    </select>
     <select id="county">
    <option value="">--县城--</option>
    </select>
</body>
</html>
**showCitiesProcess.php**
<?php
//服务器端
//这里两句话很重要,第一讲话告诉浏览器返回的数据是xml格式
header("Content-Type: text/xml;charset=utf-8");
//告诉浏览器不要缓存数据
header("Cache-Control: no-cache");
//接收用户的选择的省的名字
$province=$_POST['province'];
file_put_contents("d:/mylog.log",$province."\r\n",FILE_APPEND);
//如何在调试过程中,看到接收到的数据 。
//到数据库去查询省有那些城市(现在先不到数据库)
$info="";
if($province=="zhejiang"){
$info="<province><city>杭州</city><city>温州</city><city>宁波</city></province>";
}else if($province=="jiangsu"){
$info="<province><city>南京</city><city>徐州</city><city>苏州</city></province>";
}
echo $info;
?>

PS:服务器不可能主动给客户端发消息,拿手机收到短信举例,其实是手机上有一个发射器,它会在规定时间内如2秒定时去服务器上的数据库中查找是否有自己未接收的短信,如果有就接收到。

 

上一篇:jQuery插件之路(一)——试着给jQuery的一个Carousel插件添加新的功能


下一篇:ajax 技术和原理分析