Top

JAVA AJAX DAY01

  1. 获得Ajax对象
  2. 使用Ajax对象发送GET请求
  3. 使用Ajax对象发送POST请求
  4. 使用Ajax校验用户名
  5. POST请求时的乱码处理
  6. GET请求时的乱码处理
  7. 使用Ajax实现级联的下拉列表

1 获得Ajax对象

1.1 问题

如何获得XmlHttpRequest对象。

1.2 方案

区分浏览器,使用不同的获取方式。

1.3 步骤

步骤一:新建ajax01.html页面

新建一个Web工程,在WebRoot下新建ajax01.html页面。在<script>标记内编写JavaScript代码实现获取Ajax对象。如图-1所示。

图 - 1

步骤二:部署项目访问ajax01.html页面

访问页面如图-2所示。

图– 2

点击链接:

图 - 3

使用IE测试结果如图-4所示。

图– 4

注意:本次测试使用的是IE11,但IE的早期5.5,6.0版本创建的都是ActiveXObject类型的。从IE7开始支持创建XMLHttpRequest的方式来获取Ajax对象。

1.4 完整代码

ajax01.html文件代码如下:

<html>
<head>
<title>ajax01.html</title>	
<meta http-equiv="Content-Type" 
	  content="text/html; charset=UTF-8">
<script type="text/javascript">
	/*获取Ajax对象*/
	function getXhr(){
		var xhr = null;
		//确保IE7,IE8,FireFox下可以运行
		if(window.XMLHttpRequest){
			xhr = new XMLHttpRequest();
		}else{
			//确保IE6可以运行,无视更古老的IE浏览器
			xhr = new ActiveXObject("Microsoft.XMLHttp");
		}
		return xhr;    
		//更简易的写法
		//xhr = window.XMLHttpRequest?
		//new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHttp");	
	}    
</script>
</head>
<body>
<!-- 获取XMLHttpRequest对象 -->
<a href="javascript:;" onclick="alert(getXhr());">
获取Ajax对象
</a>
</body>
</html>

2 使用Ajax对象发送GET请求

2.1 问题

使用Ajax对象发送GET类型的请求,从服务器端获取一小段文本。

2.2 方案

遵循创建Ajax对象,创建请求,设置回调函数,发送请求的步骤来完成一次异步请求。

2.3 步骤

步骤一:新建ajax02.html页面

图 - 5

步骤二:添加getText()方法,并补充超链接对该方法的调用

图 - 6

步骤三:编写ActionServlet类

图 - 7

步骤四:部署、运行,查看结果

图– 8

点击链接:

图 - 9

2.4 完整代码

ajax02.html页面代码:

<html>
<head>
<title>ajax02.html</title>	
<meta http-equiv="Content-Type" 
	  content="text/html; charset=UTF-8">
<script type="text/javascript">
	function getXhr(){
		var xhr = null;
		if(window.XMLHttpRequest){
			xhr = new XMLHttpRequest();
		}else{
			xhr = new ActiveXObject("Microsoft.XMLHttp");
		}
		return xhr;    	
	}
	function getText(){
		//1.获取Ajax对象
		var xhr = getXhr();     
		//2.设置回调函数	
		xhr.onreadystatechange=function(){    			
			if(xhr.readyState==4 && xhr.status==200){
				var txt = xhr.responseText;
				alert(txt);
			}
		};
//3.创建请求
		xhr.open("get","get_text.do",true);  
		//4.发送请求
		xhr.send(null);
	}   
</script>
</head>
<body>
<!-- 获取服务器端一小段文本 -->
<a href="javascript:;" onclick="getText()">获取文本</a>
</body>
</html>

ActionServlet.java页面代码:

package web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ActionServlet extends HttpServlet {

	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		//获取请求资源路径
		String uri = request.getRequestURI();
		String path = uri.substring(
				uri.lastIndexOf("/"),
				uri.lastIndexOf("."));
#cold_bold		if(path.equals("/get_text")){//get请求
#cold_bold			out.println("来自星星的你");
#cold_bold		}
		out.close();
	}

}

web.xml文件代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="/java.sun.com/xml/ns/javaee" 
	xmlns:xsi="/www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="/java.sun.com/xml/ns/javaee 
	/java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<servlet>
<servlet-name>ActionServlet</servlet-name>
<servlet-class>web.ActionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>	
</web-app>

3 使用Ajax对象发送POST请求

3.1 问题

使用Ajax对象发送POST类型的请求,并向服务器提交一小段文本,显示从服务器端返回的文本。

3.2 方案

遵循GET请求方式的4步基础上,多增加一个设定,设定请求头中的content-type属性的值为application/x-www-form-urlencoded

3.3 步骤

步骤一:新建my.js文件

在WebRoot节点下,新增一个文件夹“js”。在该文件夹中新增一个文件,名为my.js。将获取XMLHttpRequest对象的方法拷贝到该文件中,便于更多页面重用该方法。

图 - 10

步骤二:新建ajax03.html页面

图– 11

步骤三:编写getText()方法

图 - 12

步骤四:修改ActionServlet

图 - 13

步骤五:运行,查看结果

图– 14

图 - 15

3.4 完整代码

ajax03.html文件代码如下:

<html>
<head>
<title>ajax03.html</title>	
<meta  http-equiv="Content-Type" 
	   content="type=text/html;charset=UTF-8">
<script type="text/javascript" src="js/my.js"></script>
<script type="text/javascript">
	function getText(){
		var xhr = getXhr();
		xhr.onreadystatechange=function(){
			if(xhr.readyState==4 && xhr.status==200){
				alert(xhr.responseText);
			}
		};
xhr.open("post","post_text.do",true);
		xhr.setRequestHeader('content-type',
				'application/x-www-form-urlencoded');
		xhr.send("uname=Dr.");
	}
</script>
</head>
<body>
<!-- 使用Ajax对象发送POST类型请求,并获取文本 -->
<input type="button" onclick="getText()" value="POST请求"/>
</body>
</html>

ActionServlet.java文件代码如下:

package web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ActionServlet extends HttpServlet {
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		//获取请求资源路径
		String uri = request.getRequestURI();
		String path = uri.substring(
				uri.lastIndexOf("/"),
				uri.lastIndexOf("."));
		if(path.equals("/get_text")){//get请求
			out.println("来自星星的你");
#cold_bold		}else if(path.equals("/post_text")){//post请求
#cold_bold			String name = request.getParameter("uname");
#cold_bold			System.out.println(name);
#cold_bold			out.println("又来了一次的" + name);
#cold_bold		}		
		out.close();
	}
}

web.xml文件代码参考案例2。

my.js文件代码参考图-10。

4 使用Ajax校验用户名

4.1 问题

实现注册功能中,用户名是否可用的校验。

4.2 方案

填写完用户名后,通过点击后面的按钮进行验证。并显示服务器返回的说明信息。

4.3 步骤

步骤一:新建regist.html文件

如图-16所示创建页面。

图 - 16

步骤二:编写check_name()方法

图– 17

document.getElementById(“name_msg”).innerHTML=“正在检查“;这行代码在服务器还没有返回信息之前,为用户提供良好的交互体验。

步骤三:修改ActionServlet.java文件

图 - 18

步骤四:运行,查看结果

输入不可用的用户名:

图– 19

提示结果如图-20:

图– 20

输入可用的用户名如图-21所示。

图 - 21

完整代码

regist.html文件代码如下:

<html>
<head>
<title>regist.html</title>
<meta http-equiv="content-type" 
	  content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/my.js"></script>
<script type="text/javascript">
	function check_name(){       		
		var xhr = getXhr();    		
		xhr.onreadystatechange=function(){
			if(xhr.readyState==4 && xhr.status==200){
				document.getElementById("name_msg")
						.innerHTML = xhr.responseText;
			}
		};
		xhr.setRequestHeader('content-type',
				'application/x-www-form-urlencoded');
xhr.open("post","check_name.do",true);
		document.getElementById("name_msg")
						.innerHTML="正在检查。。。";
		var uname = document.getElementById("uname");
			xhr.send("uname="+uname.value);
	}   
</script>
</head>
<body>
<!-- 验证注册信息中的用户名是否可用 -->
<form action="" method="post">
	<fieldset>
		<legend>注册信息</legend>
		用户名:<input name="uname" id="uname"/>
		<input type="button" value="检查一下吧" 
			   onclick="check_name()"/>
		<span id="name_msg" style="color:red;"></span>
		<br/><br/>
		<input type="submit" value="注册"/>
	</fieldset>
</form>
</body>
</html>

ActionServlet.java文件代码如下:

package web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ActionServlet extends HttpServlet {

	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		//获取请求资源路径
		String uri = request.getRequestURI();
		String path = uri.substring(
				uri.lastIndexOf("/"),
				uri.lastIndexOf("."));
		if(path.equals("/get_text")){//get请求
			out.println("来自星星的你");
		}else if(path.equals("/post_text")){//post请求
			String name = request.getParameter("uname");
			System.out.println(name);
			out.println("又来了一次的" + name);
#cold_bold		}else if(path.equals("/check_name")){//检查用户名
#cold_bold			String name = request.getParameter("uname");
#cold_bold			//模拟网络延迟的操作
#cold_bold			if(1==1){
#cold_bold				try {
#cold_bold					Thread.sleep(6000);
#cold_bold				} catch (InterruptedException e) {
#cold_bold					e.printStackTrace();
#cold_bold				}
#cold_bold			}			
#cold_bold			System.out.println(name);
#cold_bold			if("Luffy".equals(name)){				
#cold_bold				out.println("该用户名不可用");
#cold_bold			}else{
#cold_bold				out.println("可以使用!");
#cold_bold			}
#cold_bold		}
		out.close();
	}

}

5 POST请求时的乱码处理

5.1 问题

在上例中,如果填写的用户名为中文信息时,就会出现如图-22所示的结果。在控制台中打印服务器端获取的数据为乱码。但火狐浏览器提交的中文可以被服务器端正确识别。原因是火狐会告诉服务器端以什么方式解码。而IE浏览器和Chrome浏览器提交的数据,到了服务器端都是以默认解码方式ISO-8859-1来解析的,而提交时浏览器依据meta标记指定的UTF-8的方式进行的编码,编码解码不一致就会导致乱码出现。如何解决?

图 - 22

5.2 方案

在获取表单提交的数据之前,设置服务器端的解码方式为UTF-8即可。

5.3 步骤

步骤一:修改ActionServlet类

在service方法中增加一行代码即可:

图 - 23

步骤二:重新运行regist.html页面

重新运行程序,分别使用Chrome、IE、FireFox浏览器来访问regist.html页面,测试中文情况,结果如图-24所示,可以正确得到表单以POST方式提交的中文字符了。

图 - 24

5.4 完整代码

regist.html文件代码同上一案例。

ActionServlet.java文件代码如下:

package web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ActionServlet extends HttpServlet {

	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=UTF-8");
#cold_bold		request.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		//获取请求资源路径
		String uri = request.getRequestURI();
		String path = uri.substring(
				uri.lastIndexOf("/"),
				uri.lastIndexOf("."));
		if(path.equals("/get_text")){//get请求
			out.println("来自星星的你");
		}else if(path.equals("/post_text")){//post请求
			String name = request.getParameter("uname");
			System.out.println(name);
			out.println("又来了一次的" + name);
		}
		else if(path.equals("/check_name")){//检查用户名
			String name = request.getParameter("uname");
			//模拟一个耗时的操作
			if(1==1){
				try {
					Thread.sleep(6000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}			
			System.out.println(name);
			if("Luffy".equals(name)){				
				out.println("该用户名不可用");
			}else{
				out.println("可以使用!");
			}
		}
		out.close();
	}

}

6 GET请求时的乱码处理

6.1 问题

在regist.html页面中,如果将表单的提交方式更换为get,并且服务器端依然保留UTF-8的解码代码,运行程序时,依然会有如图-25所示的乱码问题。如何解决?

图 - 25

6.2 方案

产生乱码的原因是,以GET方式提交的数据存在于提交的消息头中URL中,HTTP协议对于URI的编码方式为UTF-8,但是URI后面的查询字符串的编码方式却是ISO-8859-1。到了服务器端,容器针对URI的解码方式是ISO-8859-1,依然解析不了中文,所以,会出现乱码。为了能够支持地址中查询字符串的中文格式,需要在浏览器端和服务器端同时进行支持UTF-8格式编码、解码的设置。

6.3 步骤

步骤一:修改tomcat的默认解码设置

修改tomcat安装路径下conf/server.xml文件。找到Connector节点后,增加URIEncoding=“UTF-8“这个属性即可。如图-26所示。

图 - 26

步骤二:新建regist01.html页面

新建regist01.html文件,表单内容参考regist.html,Ajax的请求修改为GET方式,为了让URL整体都使用UTF-8的方式进行编码,需要使用JavaScript语言中的encodeURI()方法,所以在open方法创建请求时,第二个URI参数要使用encodeURI方法进行编码。如图-27所示。

图 - 27

步骤三:ActionServlet保持不变

步骤四:运行,查看结果

图 - 28

6.4 完整代码

regist01.html文件代码如下:

<html>
<head>
<title>regist01.html</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/my.js"></script>
<script type="text/javascript">
	function check_name(){    		
		var uname = document.getElementById("uname");
#cold_bold		var uri = "check_name.do?uname="+uname.value;    		
		var xhr = getXhr();    		
xhr.onreadystatechange=function(){
			if(xhr.readyState==4 && xhr.status==200){    				
				document.getElementById("name_msg").innerHTML 
				= xhr.responseText;
			}
		};
#cold_bold		xhr.open("get",encodeURI(uri),true);    				
		document.getElementById("name_msg").innerHTML="正在检查。。。";
#cold_bold			xhr.send(null);
	}   
</script>
</head>
<body>
<!-- GET方式提交中文用户名进行验证 -->
<form action="" method="post">
	<fieldset>
		<legend>注册信息</legend>
		用户名:<input name="uname" id="uname"/>
		<input type="button" value="检查一下吧" onclick="check_name()"/>
		<span id="name_msg" style="color:red;"></span>
		<br/><br/>
		<input type="submit" value="注册"/>
	</fieldset>
</form>
</body>
</html>

ActionServlet.java文件代码如下:

package web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ActionServlet extends HttpServlet {

	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		//获取请求资源路径
		String uri = request.getRequestURI();
		String path = uri.substring(
				uri.lastIndexOf("/"),
				uri.lastIndexOf("."));
		if(path.equals("/get_text")){//get请求
			out.println("来自星星的你");
		}else if(path.equals("/post_text")){//post请求
			String name = request.getParameter("uname");
			System.out.println(name);
			out.println("又来了一次的" + name);
		}else if(path.equals("/check_name")){//检查用户名
			String name = request.getParameter("uname");
			//模拟一个耗时的操作
			if(1==1){
				try {
					Thread.sleep(6000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}			
			System.out.println(name);
			if("Luffy".equals(name)){				
				out.println("该用户名不可用");
			}else{
				out.println("可以使用!");
			}
		}
		out.close();
	}

}

7 使用Ajax实现级联的下拉列表

7.1 问题

实现市区的级联下拉列表。即,选择城市后,动态加载该城市包含的区域信息。

7.2 方案

下拉列表发生onchange事件时,将选中的城市对应的value发送给服务器端,服务器端收到这个城市拼音缩写后,进行比对,返回区域的组合信息。客户端收到信息后分别按照“;“和”,“进行分割,然后构建option对象,添加到区域对应的下拉列表中。

7.3 步骤

步骤一:修改my.js文件

修改my.js文件,增加两个便于定位html页面中元素的方法,以及便于读取元素value属性的方法。如图– 29。

图 - 29

步骤二:新建select.html文件

编写页面中的下拉列表。并且在onchange事件时,将选中项的value属性作为参数传给getCity方法。如图-30所示。

图 - 30

步骤三:编写Ajax代码

图 - 31

步骤四:修改ActionServlet

添加对getCity.do的请求处理

图 - 32

步骤五:访问,查看运行结果

图- 33

图- 34

7.4 完整代码

js/my.js文件代码如下:

/*获取Ajax对象*/
function getXhr(){
	var xhr = null;
    if(window.XMLHttpRequest){
	xhr = new XMLHttpRequest();
    }else{
	xhr = new ActiveXObject("Microsoft.XMLHttp");
    }
	return xhr;    	
}
#cold_boldfunction $(id){
#cold_bold	return document.getElementById(id);
#cold_bold}
#cold_bold
#cold_boldfunction $F(id){
#cold_bold	return $(id).value;
#cold_bold}

select.html文件代码如下:

<html>
<head>
<title>select.html</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/my.js"></script>
<script type="text/javascript">
	function getCity(v1) {
		var xhr = getXhr();		
		xhr.onreadystatechange = function() {
			if (xhr.readyState == 4 && xhr.status==200) {
				var txt = xhr.responseText;
				//静安,ja;黄浦,hp;浦东新,pdx
				var strs = txt.split(';');
				//先清空s2
				$('s2').innerHTML = '';
				for (i = 0; i < strs.length; i++) {
					var str1s = strs[i].split(',');
					/*构造一个Option对象 */
					var op = new Option(str1s[0], str1s[1]);
					/* options是select的一个属性,
					其值是一个数组。数组中的元素是Option对象。
					*/
					$('s2').options[i] = op;
				}
			}
		};
xhr.open('get', 'getCity.do?name=' + v1, true);
		xhr.send(null);
	}
</script>
</head>
<body>
	<!-- Ajax实现级联下拉列表 -->
	<select id="s1" style="width:120px;" 
			onchange="getCity(this.value);">
		<option value="bj">北京</option>
		<option value="sh">上海</option>
		<option value="gz">广州</option>
	</select>
	<select id="s2" style="width:120px;">
	</select>
</body>
</html>

ActionServlet.java文件代码如下:

package web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ActionServlet extends HttpServlet {

	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		//获取请求资源路径
		String uri = request.getRequestURI();
		String path = uri.substring(
				uri.lastIndexOf("/"),
				uri.lastIndexOf("."));
		if(path.equals("/get_text")){//get请求
			out.println("来自星星的你");
		}else if(path.equals("/post_text")){//post请求
			String name = request.getParameter("uname");
			System.out.println(name);
			out.println("又来了一次的" + name);
		}
		else if(path.equals("/check_name")){//检查用户名
			String name = request.getParameter("uname");
			//模拟一个耗时的操作
			if(1==1){
				try {
					Thread.sleep(6000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}			
			System.out.println(name);
			if("Luffy".equals(name)){				
				out.println("该用户名不可用");
			}else{
				out.println("可以使用!");
			}
#cold_bold		}else if(path.equals("/getCity")){//城市列表联动
#cold_bold			String name = request.getParameter("name");
#cold_bold			if("bj".equals(name)){
#cold_bold				out.println("朝阳,cy;东城,dc");
#cold_bold			}else if("sh".equals(name)){
#cold_bold				out.println("静安,ja;黄浦,hp;浦东新,pdx");
#cold_bold			}else{
#cold_bold				out.println("白云,by;番禺,py");
#cold_bold			}
#cold_bold		}
		out.close();
	}

}

web.xml文件代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="/java.sun.com/xml/ns/javaee" 
	xmlns:xsi="/www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="/java.sun.com/xml/ns/javaee 
	/java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<servlet>
<servlet-name>ActionServlet</servlet-name>
<servlet-class>web.ActionServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>	

</web-app>