Ajax为我们提供了以异步的方式和服务器进行交换数据的方法。实现Ajax有一个核心的对象:XMLHttpRequest。 该对象提供了open() 和send()两个核心方法用来发起对服务器的连接和数据发送。下面我们用一个Echo程序来演示基本的Ajax使用.
先准备服务端Servlet用于接收Http/Ajax请求(这里假设Ajax使用msg字段携带数据)。服务端Servlet在收到请求后,取出msg的消息,然后加上Echo前缀将消息发回给客户端。
1 package ajax.servlet; 2 3 import java.io.IOException; 4 import java.io.PrintStream; 5 import java.io.PrintWriter; 6 import java.io.UnsupportedEncodingException; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletOutputStream; 10 import javax.servlet.annotation.WebServlet; 11 import javax.servlet.http.HttpServlet; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 15 /** 16 * Servlet implementation class EchoServlet 17 */ 18 19 @WebServlet("/EchoServlet") 20 public class EchoServlet extends HttpServlet 21 { 22 private static final long serialVersionUID = 1L; 23 24 /** 25 * @see HttpServlet#HttpServlet() 26 */ 27 public EchoServlet() 28 { 29 super(); 30 // TODO Auto-generated constructor stub 31 } 32 33 /** 34 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 35 * response) 36 */ 37 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, 38 IOException 39 { 40 this.doPost(request, response); 41 } 42 43 /** 44 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 45 * response) 46 */ 47 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, 48 IOException 49 { 50 this.setEncoding(request, response); 51 52 String msg = request.getParameter("msg"); 53 PrintWriter ps = response.getWriter(); 54 ps.println("ECHO:" + msg); 55 } 56 57 private void setEncoding(HttpServletRequest request, HttpServletResponse response) 58 throws ServletException, IOException 59 { 60 61 request.setCharacterEncoding("UTF-8"); 62 response.setCharacterEncoding("UTF-8"); 63 response.setContentType("text/html;charset=UTF-8"); 64 } 65 66 }
在客户端用JavaScript代码实例化XMLHttpRequest对象的时候要注意IE浏览器和非IE浏览器的区别。IE浏览器用ActiveXObject("Microsoft.XMLHttp")进行实例化,而非IE浏览器直接用XMLHttpRequest()直接实例化(不得不吐槽IE真的很奇葩).
1 var xmlHttpRequest ; 2 if(window.XMLHttpRequest) 3 { 4 xmlHttpRequest = new XMLHttpRequest(); 5 } 6 else 7 { 8 xmlHttpRequest = new ActiveXObject("Microsoft.XMLHttp"); 9 }
在建立好XMLHttpRequest对象后,就可以分一下三步完成Ajax请求了。
1 open()方法设置请求的方式和请求的URL
1 var msg = document.getElementById("msg").value; 2 xmlHttpRequest.open("post", "EchoServlet?msg="+msg);
2 指定请求完成后的回调函数(callback function)
xmlHttpRequest.onreadystatechange = function() { if(xmlHttpRequest.status == 200) { if(xmlHttpRequest.readyState == 2 || xmlHttpRequest.readyState == 3) { alert("请稍后,服务器正在处理请求...."); } if(xmlHttpRequest.readyState == 4) { var backMsg = xmlHttpRequest.responseText; var backMsgDiv = document.getElementById("backMsgDiv"); var newSpan = document.createElement("span"); newSpan.appendChild(document.createTextNode(backMsg)); backMsgDiv.appendChild(newSpan); backMsgDiv.appendChild(document.createElement("br")); } } }
3 send()方法发送请求
xmlHttpRequest.send(null);
在上面的第二部,设置回调函数的时候要注意,http请求状态为200表示正常,所以我们只处理statu为200的结果。同时还有一个readyState状态,它一共有0 1 2 3 4 几种值,每种值分别代表Ajax不同的阶段。
0 代表请求没有发出(调用open()之前)
1 代表请求已经建立,但任然没有发出(调用open()之后)
2 代表请求已经发出,正在等待服务器处理(调用send之后)
3 代表服务器处理完成,正在接收服务器的返回信息
4 代表所有的服务器信息已经接收完成
下面的代码是整个JSP页面的所有代码:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@taglib prefix="c" uri="http://www.mldn.cn/c"%> 3 4 <% 5 String path = request.getContextPath(); 6 String basePath = request.getScheme() + "://" + request.getServerName() + ":" 7 + request.getServerPort() + path + "/"; 8 %> 9 10 <html> 11 <head> 12 <base href="<%=basePath%>"> 13 14 <title>My JSP 'template.jsp' starting page</title> 15 <link type="text/css" rel="stylesheet" href="css/mldn.css"> 16 <script type="text/javascript" src="js/mldn.js"></script> 17 <script type="text/javascript"> 18 19 function sendRequest() 20 { 21 var xmlHttpRequest ; 22 if(window.XMLHttpRequest) 23 { 24 xmlHttpRequest = new XMLHttpRequest(); 25 } 26 else 27 { 28 xmlHttpRequest = new ActiveXObject("Microsoft.XMLHttp"); 29 } 30 31 var msg = document.getElementById("msg").value; 32 xmlHttpRequest.open("post", "EchoServlet?msg="+msg); 33 xmlHttpRequest.onreadystatechange = function() 34 { 35 if(xmlHttpRequest.status == 200) 36 { 37 if(xmlHttpRequest.readyState == 2 || xmlHttpRequest.readyState == 3) 38 { 39 alert("请稍后,服务器正在处理请求...."); 40 } 41 42 if(xmlHttpRequest.readyState == 4) 43 { 44 var backMsg = xmlHttpRequest.responseText; 45 var backMsgDiv = document.getElementById("backMsgDiv"); 46 var newSpan = document.createElement("span"); 47 newSpan.appendChild(document.createTextNode(backMsg)); 48 backMsgDiv.appendChild(newSpan); 49 backMsgDiv.appendChild(document.createElement("br")); 50 } 51 } 52 } 53 xmlHttpRequest.send(null); 54 } 55 </script> 56 57 </head> 58 59 <body> 60 <input type="text" id="msg" name="msg" /><button onclick="sendRequest()">提交</button> 61 <div id="backMsgDiv"> 62 </div> 63 </body> 64 </html>