AJAX学习
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。AJAX代码运行在客户端,其和服务器进行交互完全依靠浏览器的XMLHttpRequest对象来完成。下面来看第一个AJAX程序。
AJAX是与服务器交互的,在无刷新的情况下完成数据校验或提交。所以第一个例子我们来完成这样一个功能:用户输入用户名,当失去焦点的时候页面提示该用户名是否已经存在(输入框所在的页面不刷新)。
创建数据库和插入数据的过程,这里就不再进行阐述,下面主要介绍一下servlet和JSP页面怎么写。
servlet代码如下:
1 package com.mxf.web.action; 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 import com.mxf.service.UserService; 12 import com.mxf.service.impl.UserServiceImpl; 13 14 public class CheckUserNameServlet extends HttpServlet { 15 private static final long serialVersionUID = 1L; 16 17 protected void service(HttpServletRequest request, HttpServletResponse response) 18 throws ServletException, IOException { 19 /** 20 * 获得输出流,向页面输出数据 21 */ 22 PrintWriter pw = response.getWriter(); 23 String userName = request.getParameter("userName"); 24 UserService us = new UserServiceImpl(); 25 boolean flag = us.checkUserName(userName); 26 if(flag){ 27 pw.write("username is exits"); 28 }else{ 29 pw.write("username is not exits"); 30 } 31 } 32 }
像用户客户端的页面标签数据是由容器通过流写出的这种知识点在这里不再进行阐述。这个servlet就是一个简单的用户名校验,可以注意到:它没有转发或者重定向的语句。
这一点很重要,如果有转发或重定向的语句,那么就不叫异步数据交互了。而是将数据通过流的方式响应到客户端。下面来看JSP页面:
<%@ 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>Insert title here</title> <script type="text/javascript"> /* 定义一个全局变量,用来存储XMLHttpRequest的值 */ var xhr ; /* 创建XMLHttpRequest对象 */ function createXMLHttpRequest(){ xhr = new XMLHttpRequest(); } function checkUserName(){ createXMLHttpRequest(); /* 获得用户输入的用户名 */ var userName = document.getElementById("userName").value; /* url是XMLHttpRequest对象open函数内的一个参数,意思是:要往哪个服务器servlet发送请求。 它的内容和用表单提交数据时action内的值一样。 */ var url = "CheckUserNameServlet.do?userName="+userName; /* XMLHttpRequest对象的open函数介绍: open(String method, String url, any async, any username, any password) method:使用哪种方式向服务器发送数据,有两个值:GET、POST;注意都是大写 url:上面已经介绍 async:是否使用异步操作,默认为:true,可以改为false username和password:这两个参数不经常用到,目前不需要详细了解,他们的意思是向其他客户端发送数据。 一般open内填两个参数足矣:method、url */ xhr.open("GET", url); /* XMLHttpRequest的onreadystatechange,从字面意思可以知道:当状态发生变化时,它记录了客户端的各个状态 该对象有5个状态,分别是:0,1,2,3,4 0:准备 1:获取 2:发送数据 3:等待 4:接收到客户端响应 xhr.onreadystatechange = callback;callback是回调函数,后面不要加括号(), 加了括号表示把该函数的返回值给xhr.onreadystatechange,不加括号就是执行该函数。 */ xhr.onreadystatechange = callback; xhr.send(null); xhr.o } function callback(){ /** xhr.readyState:获取xhr的状态,上面有介绍(有5个状态) xhr.status:获取从服务器返回的状态,200位正常 xhr.responseText:获取浏览器返回的信息 document.getElementById("msg").innerHTML=msg:将浏览器返回的数据加到页面 */ if(xhr.readyState == 4){ if(xhr.status == 200){ var msg = xhr.responseText; document.getElementById("msg").innerHTML=msg; } } } </script> </head> <body> <span id="msg"></span> <input type="text" name="userName"id="userName"/> <input type="button" value="check" onclick="checkUserName()" /> </body> </html>
这样就完成了异步交互的第一步,里面还有很多问题。
下面来解决一下ajax get提交的中文乱码问题。
ajax的中文乱码解决方式和表单提交数据时乱码原理基本一致,具体解决办法:
第一种:利用URLEncoder和URLDecoder来解决,都知道:tomcat在接收页面传输来的数据的时候采用的是"ISO-8859-1"的编码格式,如果传输的数据含有中文,解析的时候必定会产生乱码,所以我们可以将接收到的数据采用"ISO-8859-1"的编码方式再进行一次编码,然后再将其转化为"UTF-8"的编码方式,这样就不会再出现乱码,具体实现:
String userName = request.getParameter("userName"); userName = URLEncoder.encoder(userName,"ISO-8859-1"); userName = URLDecoder.decoder(userName,"UTF-8");
这样得到的userName就不会再乱码了。
第二种:userName = new String(userName.getBytes("ISO-8859-1"),"utf-8");
利用String的编码转换也可以解决乱码问题。
第三种:改动tomcat的默认编码格式,修改tomcat conf目录下的server.xml文件里的Connector节点中的编码,修改为:
<Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8"/>
加入URLEncoding="utf-8",就可以了。
ajax以post方式提交数据,JSP页面如下:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 <script type="text/javascript"> 9 var xhr ; 10 function createXMLHttpRequest(){ 11 xhr = new XMLHttpRequest(); 12 } 13 function checkUserName(){ 14 createXMLHttpRequest(); 15 var userName = document.getElementById("userName").value; 16 var url = "CheckUserNameServlet.do"; 17 xhr.open("POST", url); 18 xhr.onreadystatechange = callback; 19 xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 20 xhr.send("userName="+userName); 21 } 22 23 function callback(){ 24 if(xhr.readyState == 4){ 25 if(xhr.status == 200){ 26 var msg = xhr.responseText; 27 document.getElementById("msg").innerHTML=msg; 28 } 29 } 30 } 31 </script> 32 </head> 33 <body> 34 <!-- <form action="CheckUserNameServlet.do" method="post"> --> 35 <span id="msg"></span> 36 <input type="text" name="userName"id="userName"/> 37 <input type="button" value="check2" onclick="checkUserName()" /> 38 <!-- <input type="submit" name="check"/> --> 39 <!-- </form> --> 40 </body> 41 </html>
对比一下get和post方式提交的JSP文件可以发现:
get提交:
xhr.open("GET", url);
xhr.send(null);
post提交:
xhr.open("POST", url);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send("userName="+userName);
post提交中的:xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');是必须的,如果使用post方式提交,则该行代码不可少。
post提交数据时的乱码和用表单post提交数据的处理方式一样:
request.setCharacterEncoding("utf-8");
该文中处理中文乱码的方式在不用ajax时同样适用。