ajax简介
Ajax的全称是:Asynchronous JavaScript And XML,指的是异步 JavaScript 及 XML(其实主要用的就是javascript技术),它不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术。Ajax的特点是异步,比如可以使用Ajax更新局部网页、使用Ajax在不刷新页面的情况下查询数据、验证用户注册的用户名是否唯一等。
Ajax交互模型:
同步web交互方式
异步web交互方式
XMLHttpRequest对象
JavaScript中XMLHttpRequest对象是整个Ajax技术的核心,它提供了异步发送请求的能力。
对象的创建方式
对于不同的浏览器,对象的创建方式是不同的。
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
常用方法
- open(method,URL,async)
建立与服务器的连接
method参数指定请求的HTTP方法,典型的值是GET或POST
URL参数指请求的地址
async参数指定是否使用异步请求,其值为true或false,默认是true - send(content)
发送请求
content指定请求的参数 - setRequestHeader(header,value)
设置请求的头信息
常用属性
- onreadystatechange
指定回调函数 - readyState
XMLHttpRequest的状态信息
就绪状态码 | 说明 |
---|---|
0 | XMLHttpRequest对象没有完成初始化即:刚刚创建。 |
1 | XMLHttpRequest对象开始发送请求调用了open方法,但还没有调用send方法。请求还没有发出 |
2 | XMLHttpRequest对象的请求发送完-成send方法已经调用,数据已经提交到服务器,但没有任何响应 |
3 | XMLHttpRequest对象开始读取响应,还没有结束收到了所有的响应消息头,但正文还没有完全收到 |
4 | XMLHttpRequest对象读取响应结束一切都收到了 |
使用Ajax校验用户名
通常情况下在一个系统中的用户的登录名是唯一的,为了保证用户名的唯一性,需要在用户注册时添加校验,即根据用户输入的用户名去数据库中查找,这里使用ajax校验用户名可以很好的提升用户体验,用户输入完用户名失去鼠标焦点后通过ajax去数据库中查找是否唯一,然后根据结果给用户相应的提示信息,这样对于用户来说非常方便。
什么是回调函数
回调函数就是你编写好了一个函数,让软件系统来调用这个函数,该函数就是回调函数。说的简单点其实就是让系统调用你的函数就是回调,那你调用系统的函数是直调。
举例来说,你跟马云谈生意,聊天结束后,你跟马云说以后有什么需要帮助的可以联系我的秘书小张。这个秘书小张就可以看做是回调函数,当马云联系你的秘书小张时,叫做调用回调函数。
代码示例:
创建jsp添加一个表单:
1 <body> 2 用户名:<input type="text" name="name" /><span id="msg"></span><br/> 3 </body>
在jsp中添加onblur事件绑定,然后使用ajax完成异步请求
1 <script type="text/javascript"> 2 window.onload=function(){ 3 var nameElement = document.getElementById("name"); 4 //绑定onblur事件 5 nameElement.onblur = function(){ 6 //this等价于nameElement 7 var name = this.value; 8 //创建XMLHttpRequest对象 9 var xhr; 10 if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari 11 xhr = new XMLHttpRequest(); 12 } else {// code for IE6, IE5 13 xhr = new ActiveXObject("Microsoft.XMLHTTP"); 14 } 15 //注册回调函数 16 xhr.onreadystatechange = function(){ 17 if(xhr.readyState==4){//请求一切正常 18 if(xhr.status==200){//服务器响应一切正常 19 var msg = document.getElementById("msg"); 20 if(xhr.responseText=="true"){ 21 msg.innerHTML = "<font color='red'>用户名已存在</font>"; 22 23 }else{ 24 msg.innerHTML = "可以使用"; 25 } 26 } 27 } 28 } 29 30 //创建连接 31 xhr.open("get","${pageContext.request.contextPath }/regist?name="+name); 32 //发送请求 33 xhr.send(null); 34 } 35 36 } 37 </script>
创建用来处理请求的servlet,这里省略JDBC数据库相关的操作,直接将用户名写死在程序中:
1 package com.monkey1024.servlet; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 /** 12 * 注册 13 */ 14 public class RegistServlet extends HttpServlet { 15 private static final long serialVersionUID = 1L; 16 17 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 18 PrintWriter out = response.getWriter(); 19 String name = request.getParameter("name"); 20 if("monkey1024".equals(name)){ 21 out.print(true); 22 }else{ 23 out.print(false); 24 } 25 } 26 27 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 28 doGet(request, response); 29 } 30 31 }
百度下拉提示框
在使用百度搜索时,在输入框中输入部分文字后,下面会将与该文字相关的词组展示出来,该功能就可以使用ajax来实现。
注册输入框的onkeyup事件,该事件触发时,将输入框中填写的内容使用ajax发送到servlet中,在servlet中根据用户的输入去数据库中查询,之后将查询出的数据再发送给jsp中,最后将该数据展示在页面即可。
代码示例:
定义jsp:
1 <!-- 用户输入框 --> 2 <div id="divsearch"> 3 <input type="text" name="name" id="name" /> 4 <input type="submit" value="搜索"> 5 6 </div> 7 <!-- 下拉提示框 --> 8 <div id="tips" 9 style="display: none; border: 1px solid red; 128px; top: 135px;"> 10 11 </div>
在jsp中编写javascript代码:
1 <script type="text/javascript"> 2 window.onload = function(){ 3 4 var searchElement = document.getElementById("name"); 5 var div = document.getElementById("tips"); 6 7 //给文件框注册按键弹起事件 8 searchElement.onkeyup = function(){ 9 //获取文本框的值 10 var name = this.value; 11 //如果文本框没有数据时,将div隐藏。 12 if(name==""){ 13 div.style.display="none"; 14 return; 15 } 16 17 //获得XMLHttpRequest对象 18 var xhr = getXMLHttpRequest(); 19 20 //回调函数 21 xhr.onreadystatechange = function(){ 22 if(xhr.readyState==4){//请求一 切正常 23 if(xhr.status==200){//服务器响应一切正常 24 var str = xhr.responseText;//得到服务器返回的数据 25 if(str == ""){ 26 return; 27 } 28 var result = str.split(","); // 把返回的数据截成数组 29 var childDivs = ""; 30 //循环把数据放入div中 31 for(var i=0;i<result.length;i++){ 32 //把数组中的每个元素放到div中 33 childDivs+="<div onclick='writeText(this)' onmouseover='changeBackground_over(this)' onmouseout='changeBackground_out(this)'>"+result[i]+"</div>"; 34 } 35 36 div.innerHTML= childDivs;//把多个childDivs(div)放入列表div中 37 div.style.display="block";//把列表显示 38 } 39 } 40 } 41 42 xhr.open("get","${pageContext.request.contextPath}/search?name="+name+"&time="+new Date().getTime()); 43 44 xhr.send(null); 45 } 46 } 47 48 function getXMLHttpRequest(){ 49 var xhr; 50 if (window.XMLHttpRequest) {//IE7+, Firefox, Chrome, Opera, Safari 51 xhr = new XMLHttpRequest(); 52 } else {//IE6, IE5 53 xhr = new ActiveXObject("Microsoft.XMLHTTP"); 54 } 55 return xhr; 56 } 57 58 //鼠标悬浮时,改变背景色 59 function changeBackground_over(div){ 60 div.style.backgroundColor = "orange"; 61 } 62 //鼠标离开时,恢复背景色 63 function changeBackground_out(div){ 64 div.style.backgroundColor = ""; 65 } 66 67 //将文本填充到搜索框 68 function writeText(div){ 69 //得到搜索框 70 var searchElement = document.getElementById("name"); 71 searchElement.value = div.innerHTML;//把div中的文本添加到搜索框中 72 div.parentNode.style.display="none";//把context1的div隐藏 73 } 74 </script>
编写servlet用来接收ajax请求并查询数据,这里简化下不去数据库中查询,而是自己构建一个List,将该List作为查询的结果返回给jsp:
1 package com.monkey1024.servlet; 2 3 import java.io.IOException; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 12 /** 13 * 查询 14 */ 15 public class SearchServlet extends HttpServlet { 16 private static final long serialVersionUID = 1L; 17 18 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 19 20 String name = request.getParameter("name"); 21 22 //根据用户输入的数据去查询数据库,这里省略数据库查询操作,手动编写一个List结果集 23 List<String> result = new ArrayList<>(); 24 result.add("m1"); 25 result.add("m2"); 26 result.add("m3"); 27 result.add("m4"); 28 result.add("m5"); 29 30 //把集合中的数据转换为字符串返回到网页 31 String str = ""; 32 //如果用户输入的内容是以m开头的话,则将数据返回 33 if(name.startsWith("m")){ 34 for (int i = 0; i < result.size(); i++) { 35 if(i>0){ 36 str+=","; 37 } 38 str+=result.get(i); 39 } 40 } 41 42 System.out.println(str); 43 //把数据响应到客户端 44 response.getWriter().write(str); 45 } 46 47 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 48 doGet(request, response); 49 } 50 51 }
json简介
json的全称是JavaScript Object Notation,是一种数据交换格式,独立于编程语言,可以用来存储数据,优点是非常利于人类阅读和编写,同时也利于机器的解析和生成,同时还可以提升网络传输效率。
json的数据格式是以名-值对的方式存储的,可以将其看做是一个字符串,下面就是一个json格式的数据:
{name:"monkey1024",age:18,hobby:"java"}
在json中规定的字符编码时utf-8,无需担心乱码问题。几乎所以的编程语言都有解析json数据的第三方库,因此json的应用非常多。在servlet中可以将要返回给jsp的数据封装为json格式,在jsp中可以使用javascript来解析,javascript已经内置了json的解析。
在javascript中创建json对象:
1 <script type="text/javascript"> 2 3 //创建一个json对象 4 var student = {name:"jack",age:18}; 5 alert(student.name); 6 7 //创建一个数组,数组中存放json对象 8 var animal = [{name:"monkey",count:10},{name:"tiger",count:5}]; 9 alert(animal[0].name); 10 </script>
通过上面示例可以看出在javascript中使用json非常方便。
在java中有非常多的第三方库可以解析json格式的数据,常用的有:
fastjson:国人开发的,是目前java语言中最快的json库
gson:google开发
jackson:Tatu Saloranta开发
下面以fastjson为例看下,fastjson相关jar包下载地址:http://pan.baidu.com/s/1jIagJII
fastjson中常用的方法:
- JSON.toJSONString
将JavaBean转成json格式的字符串 - JSON.parseObject
将json格式的字符串转换为JavaBean
代码示例:
创建一个City类,表示城市:
1 package com.monkey1024.bean; 2 3 /** 4 * 城市 5 * 6 */ 7 public class City { 8 9 private int id; 10 11 private String name; 12 13 public int getId() { 14 return id; 15 } 16 17 public void setId(int id) { 18 this.id = id; 19 } 20 21 public String getName() { 22 return name; 23 } 24 25 public void setName(String name) { 26 this.name = name; 27 } 28 29 }
创建一个Province类表示省份:
1 package com.monkey1024.bean; 2 3 import java.util.List; 4 5 /** 6 * 省份 7 * 8 */ 9 public class Province{ 10 11 private String name; 12 13 private List<City> cities; 14 15 public String getName() { 16 return name; 17 } 18 19 public void setName(String name) { 20 this.name = name; 21 } 22 23 public List<City> getCities() { 24 return cities; 25 } 26 27 public void setCities(List<City> cities) { 28 this.cities = cities; 29 } 30 31 }
fastjson测试类:
1 package com.monkey1024.test; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import com.alibaba.fastjson.JSON; 7 import com.monkey1024.bean.City; 8 import com.monkey1024.bean.Province; 9 10 public class JsonTest { 11 12 public static void main(String[] args) { 13 14 City c1 = new City(); 15 c1.setId(1005); 16 c1.setName("石家庄"); 17 18 City c2 = new City(); 19 c2.setId(1006); 20 c2.setName("唐山"); 21 22 City c3 = new City(); 23 c3.setId(1007); 24 c3.setName("保定"); 25 26 List<City> cities = new ArrayList<>(); 27 cities.add(c1); 28 cities.add(c2); 29 cities.add(c3); 30 31 Province hebei = new Province(); 32 hebei.setName("河北"); 33 hebei.setCities(cities); 34 //将Province对象转换为json格式并返回字符串 35 String hebeiString = JSON.toJSONString(hebei); 36 System.out.println(hebeiString); 37 38 //将json格式的字符串转换为Province对象 39 Province hebeiNew = JSON.parseObject(hebeiString, Province.class); 40 System.out.println(hebeiNew.getName()); 41 42 } 43 44 }
使用json进行数据传输
将百度下拉提示框中的代码改成使用json格式进行数据传输。
将SearchServlet类中的doGet方法修改为下面内容:
// 根据用户输入的数据去查询数据库,这里省略数据库查询操作,手动编写一个List结果集
1 List<String> result = new ArrayList<>(); 2 result.add("m1"); 3 result.add("m2"); 4 result.add("m3"); 5 result.add("m4"); 6 result.add("m5");
//将List转换为string类型
1 String str = JSONArray.toJSONString(result);
// 把数据响应到客户端
1 response.getWriter().write(str);
因为servlet中返回了一个JSON字符串,所以需要在javascript中将该字符串转换为JSON类型,因此将search.jsp中的
1 var result = str.split(",");
修改为:
1 var result = JSON.parse(str);
上面代码中将字符串转换为JSON对象。
由此可见使用json进行数据传输时可以减少开发者的操作并且提高系统的运行效率(之前需要遍历list并进行拼接)。