ajax 同步_055 JAVA-AJAX

AJAX

出现背景(问题):

目前浏览器向服务器发起请求的方式有 form 标签,超链接,还有脚本语言(jsjquery)中

的window.location.href 方式和表单提交函数。但是不管哪种提交方式,浏览器都会将接收

到的响应内容覆盖在请求网页中显示,但是怎么在保留请求网页内容的基础显示新的内容呢?

解决方法:

使用AJAX(改良用户体验,实现局部刷新)

与传统网页的区别:

传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

----------------------------------------------------------------------------------------------

AJAX简介

AJAX:Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)

AJAX 是一种用于创建快速动态网页的技术。

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以

在不重新加载整个网页的情况下,对网页的某部分进行更新。

----------------------------------------------------------------------------------------------

AJAX访问原理(及步骤)

v2-8e35d4a9e343f9de467edf99e4cf714b_b.jpg

----------------------------------------------------------------------------------------------

AJAX的应用

  • 运用XHTML+CSS来表达资讯;
  • 运用JavaScript操作DOM(Document Object Model)来执行动态效果;
  • 运用XML和XSLT操作资料;
  • 运用XMLHttpRequest或新的Fetch API与网页服务器进行异步资料交换;
  • 注意:AJAX与Flash、Silverlight和Java Applet等RIA技术是有区分的。

************************************************************************************

创建AJAX对象(XMLHttpRequest 对象

XMLHttpRequest 是 AJAX 的基础

所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象,但在老版本的浏览器中并不是,所以考虑充分的情况下,创建方法如下:

var ajax;
if (window.XMLHttpRequest)
{
    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
    ajax=new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
    // IE6, IE5 浏览器执行代码
    ajax=new ActiveXObject("Microsoft.XMLHTTP");
    //ajax = new ActiveXObject("Msxml2.XMLHTTP");
}

AJAX - 向服务器发送请求请求

如需将请求发送到服务器,使用 XMLHttpRequest 对象的 open() 和 send() 方法:

v2-4c1113b395fffa105e2c972f9f1d4cf4_b.jpg

-----------------------------------------------------------------------------------------------------

get请求与post请求:

与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。

然而,在以下情况中,请使用 POST 请求:

  • 无法使用缓存文件(更新服务器上的文件或数据库)
  • 向服务器发送大量数据(POST 没有数据量限制)
  • 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

异步 - True 或 False:

通过 AJAX,JavaScript 无需等待服务器的响应,而是:

  • 在等待服务器响应时执行其他脚本
  • 当响应就绪后对响应进行处理

AJAX - 服务器 响应:

v2-4f8cc58522e2187a026d1e744884742d_b.jpg

如果来自服务器的响应并非 XML,可以使用responseText 属性返回字符串形式的响应

如果来自服务器的响应是 XML,而且需要作为 XML 对象进行解析,使用 responseXML 属性进行响应

实例:

get请求的同步、异步:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript">
    	//非ajax方法
		function test1(){
			window.location.href="test";
		};
		
		//ajax方法
		function test2(){
			//创建AJAX对象
			var ajax;
			if(window.XMLHttpRequest){
				//火狐浏览器
				ajax = new XMLHttpRequest();
			}else if(window.ActiveXObject){
				//IE浏览器
				ajax = new ActiveXObject("Msxm12.XMLHTTP");
			}
			//声明监听事件
			ajax.onreadystatechange = function(){
				if(ajax.readyState==4){
					if(ajax.status==200){
						//处理响应
							//获取响应内容
						var data = ajax.responseText;
						//获取div对象
						var div = document.getElementById("showdiv");
						div.innerHTML=data;
						//alert(ajax.readyState);
					}else if(ajax.status==404){
						//获取div对象
						var div = document.getElementById("showdiv");
						div.innerHTML="访问资源不存在!";
					}else if(ajax.status==500){
						//获取div对象
						var div = document.getElementById("showdiv");
						div.innerHTML="内部服务器繁忙!";
					}else{
						//获取div对象
						var div = document.getElementById("showdiv");
						div.innerHTML="未知错误!";
					}
				}
			};
			//创建请求
				//异步(默认)
			//ajax.open("get","/ajax/test",true);
				//同步
			ajax.open("get","/ajax/test?userName=张三&pwd=123",false);
			//发送请求
			ajax.send(null);
			var div = document.getElementById("showdiv");
			alert(div.innerHTML);
		};
	</script>
  </head>
  <body>
  	<h3>ajax学习</h3>
  	<input type="button" value="测试非ajax" onclick="test1()" />
  	<input type="button" value="测试ajax" onclick="test2()" />
  	<hr />
  	<div id="showdiv" style="width: 200px;height: 200px;border: 1px solid red;"></div>
  </body>
</html>

post请求的同步、异步:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript">
    	//非ajax方法
		function test1(){
			window.location.href="test";
		};
		
		//ajax方法
		function test2(){
			//创建AJAX对象
			var ajax;
			if(window.XMLHttpRequest){
				//火狐浏览器
				ajax = new XMLHttpRequest();
			}else if(window.ActiveXObject){
				//IE浏览器
				ajax = new ActiveXObject("Msxml2.XMLHTTP");
			}
			//声明监听事件
			ajax.onreadystatechange = function(){
				if(ajax.readyState==4){
					if(ajax.status==200){
						//处理响应
							//获取响应内容
						var data = ajax.responseText;
						//获取div对象
						var div = document.getElementById("showdiv");
						div.innerHTML=data;
						//使用eval方法将字符串数据转换为js对象
						eval("var obj="+data);//eval("var obj=
                                {userId:2,userName:'王五',pwd:'12345',age:45,sex:'男'}")
 					        //获取div对象
 						var div=document.getElementById("showdiv");
 						div.innerHTML=obj.sex;
						//alert(ajax.readyState);
					}else if(ajax.status==404){
						//获取div对象
						var div = document.getElementById("showdiv");
						div.innerHTML="访问资源不存在!";
					}else if(ajax.status==500){
						//获取div对象
						var div = document.getElementById("showdiv");
						div.innerHTML="内部服务器繁忙!";
					}else{
						//获取div对象
						var div = document.getElementById("showdiv");
						div.innerHTML="未知错误!";
					}
				}
			};
			//创建请求
				//异步(默认)
			//ajax.open("get","/ajax/test",true);
				//同步
			ajax.open("post","/ajax/test",false);
			//设置请求参数为键值对方式
			ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
			//发送请求
			ajax.send("userName=张三&pwd=123");
			var div = document.getElementById("showdiv");
			alert(div.innerHTML);
		};
	</script>
  </head>
  <body>
  	<h3>ajax学习</h3>
  	<input type="button" value="测试非ajax" onclick="test1()" />
  	<input type="button" value="测试ajax" onclick="test2()" />
  	<hr />
  	<div id="showdiv" style="width: 200px;height: 200px;border: 1px solid red;"></div>
  </body>
</html>

-----------------------------------------------------------------------------------------------------

AJAX - onreadystatechange 事件

当请求被发送到服务器时,我们需要执行一些基于响应的任务。

每当 readyState 改变时,就会触发 onreadystatechange 事件。

readyState 属性存有 XMLHttpRequest 的状态信息。

v2-afb6c48633ff637e1046f45d1d190bc2_b.jpg

在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。

并且当 readyState 等于 4 且状态为 200 时,表示响应已就绪:

xmlhttp.onreadystatechange=function()
{
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
        document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
}

///

AJAX实现用户名校验:

----数据库设计:

user表

v2-50096a33583b8a5bd964a86223e7ab83_b.jpg

----实体类(pojo)、Dao层、service层、servlet层、工具类(util)、properties设计

v2-e4511aa1fb71c0863f43cb5719f1604b_b.jpg

pojo实体类(User)

v2-c323ec67230c396e3689835880c0dee7_b.jpg

Dao层(封装方法):

v2-aeaa8c87b35bb58b437b7dfd876f1428_b.jpg

v2-55884abca4d2c8d3d90f774058419d46_b.jpg
package com.sxt.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.sxt.dao.DataDao;
import com.sxt.util.DBUtil;

public class DataDaoImpl implements DataDao {
	
	//查询用户名是否存在
	@Override
	public boolean checkUnameInfoDao(String uname) {
		Connection conn = null;
		PreparedStatement psmt= null;
		ResultSet rs = null;
		String sql = "select * from user where uname=?";
		//声明变量
		boolean flag = false;
		try {
			conn = DBUtil.getConnection();
			psmt = conn.prepareStatement(sql);
			psmt.setString(1,uname);
			rs = psmt.executeQuery();
			if(rs.next()){
				//rs.getString("uname");
				flag = true;
			}
			//System.out.println("rs集合:"+rs.getString("uname"));
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			DBUtil.closeAll(rs, psmt, conn);
		}
		return flag;
	}
}

service层:

v2-c1a5a852858797d04e96646a51b18f63_b.jpg

v2-9d583177687efa8d58df33a8995b3cbc_b.jpg

servlet层(servlet方法):

package com.sxt.servlet;

import java.io.IOException;

import javax.security.auth.message.callback.PrivateKeyCallback.Request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sxt.service.DataService;
import com.sxt.service.impl.DataServiceImpl;

public class DataServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException,IOException{
		//设置请求编码集格式
		req.setCharacterEncoding("utf-8");
		//设置响应编码集格式
		resp.setContentType("text/html;charset=utf-8");
		//获取请求信息
		String uname = req.getParameter("uname");
		//System.out.println("DataServlet.service():"+uname);
		//处理请求信息
			//获取业务层对象
		DataService ds = new DataServiceImpl();
		boolean flag = ds.checkUnameInfoService(uname);
		//响应处理结果
		if(flag){
			//用户已存在
			resp.getWriter().write("true");
		}else{
			//用户不存在
			resp.getWriter().write("false");
		}
	}
}

Jsp文件:

<%@ page language="java" import="java.util.*"  contentType="text/html"  pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript">
  		//声明用户名校验函数
  		function checkUname(){
  			var uname = document.getElementById("uname").value;
  			//创建ajax引擎对象
  			var ajax;
  			if(window.XMLHttpRequest){
  				ajax = new XMLHttpRequest;
  			}else if(window.ActiveXObject){
  				ajax = new ActiveXObject;
  			}
  			//声明监听函数
  			ajax.onreadystatechange = function(){
  				//判断ajax状态码
  				if(ajax.readyState==4){
  					//判断状态
  					if(ajax.status==200){
  						//获取响应数据(普通字符串或者json格式的字符串)
  						var data = ajax.responseText;
  						//处理请求数据
  						if(eval(data)){
  							//获取span对象
  							var span = document.getElementById("unameSpan");
  							//设置span随想颜色
  							span.style.color="red";
  							//将数据填充到span中
  							span.innerHTML="用户名已被占用!";
  						}else{
  							//获取span对象
  							var span = document.getElementById("unameSpan");
  							//设置span随想颜色
  							span.style.color="green";
  							//将数据填充到span中
  							span.innerHTML="用户名OK";
  						}
  					}else{
  						//获取span对象
						var span = document.getElementById("unameSpan");
						//设置span随想颜色
						span.style.color="red";
						//将数据填充到span中
						span.innerHTML="未知错误!";
  					}
  				}
  			};
  			//创建并发送请求	
	 			//创建请求
  			ajax.open("get","data?uname="+uname);
  				//发送请求
  			ajax.send(null);
  		};
    </script>
  </head>
  <body>
    用户名:<input name="uname" id="uname" value="" type="text" onblur="checkUname()" /><span id="unameSpan"></span>
  </body>
</html>

工具类(DButil):

package com.sxt.util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DBUtil {
	// 声明全局变量记录jdbc参数
	private static String driver;
	private static String url;
	private static String username;
	private static String password;
	// 使用静态代码块,在类加载时即完成对属性文件的读取
	static {
		// 动态获取属性配置文件的流对象
		InputStream in = DBUtil.class.getResourceAsStream("/db.properties");
		// 创建Properties对象
		Properties p = new Properties();
		// 加载
		try {
			p.load(in);// 会将属性配置文件的所有数据存储到Properties对象中
			// 将读取的jdbc参数赋值给全局变量
			driver = p.getProperty("driver");
			url = p.getProperty("url");
			username = p.getProperty("username");
			password = p.getProperty("password");
			// 加载驱动
			Class.forName(driver);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 创建连接对象并返回
	public static Connection getConnection() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return conn;
	}

	// 关闭资源
	public static void closeAll(ResultSet rs, Statement stmt, Connection conn) {
		try {
			if (rs != null) {
				rs.close();
			}
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		try {
			stmt.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	// 封装增加删除修改的通用工具方法
	/**
	 * @param sql
	 *            SQL语句
	 * @param objs
	 *            SQL语句占位符实参,如果没有参数则传入null
	 * @return 返回增删改的结果,类型为int
	 */
	public static int executeDML(String sql, Object... objs) {
		// 声明jdbc变量
		Connection conn = null;
		PreparedStatement ps = null;
		int i = -1;
		try {
			// 获取连接对象
			conn = DBUtil.getConnection();
			// 开启事务管理
			conn.setAutoCommit(false);
			// 创建SQL命令对象
			ps = conn.prepareStatement(sql);
			// 给占位符赋值
			if (objs != null) {
				for (int j = 0; j < objs.length; j++) {
					ps.setObject(j + 1, objs[j]);
				}
			}
			// 执行SQL
			i = ps.executeUpdate();
			conn.commit();
		} catch (Exception e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			DBUtil.closeAll(null, ps, conn);
		}
		return i;
	}

}

----web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <servlet>
    <servlet-name>DataServlet</servlet-name>
    <servlet-class>com.sxt.servlet.DataServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>DataServlet</servlet-name>
    <url-pattern>/data</url-pattern>
  </servlet-mapping>

</web-app>

----db.properties配置

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/project?useUnicode=true&characterEncoding=UTF-8
username=root
password=0100

效果:

v2-d5c4724fa362a347ee67dbb935a14e76_b.jpg

v2-161c2c445efb2eb0662f3c2bdee00e88_b.jpg

JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。

它基于JavaScript Programming Language,Standard ECMA-262 3rd Edition - December 1999的一个子集。

JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。

JSON构建格式:

“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。

JSON具有以下这些形式:

1. 对象是一个无序的“‘名称/值’对”集合。一个对象以{左括号开始,以}右括号结束。每个“名称”后跟一个:冒号;“‘名称/值’ 对”之间使用,逗号分隔

v2-07890c157a036fcdae49ab4a10ef7b0b_b.jpg

2. 数组是值(value)的有序集合。一个数组以[左中括号开始,]右中括号结束。值之间使用,逗号分隔

v2-06446ed6b35dfb8eaeb7e805e79db8ab_b.jpg

3. 值(value)可以是双引号括起来的字符串(string)、数值(number)、truefalsenull、对象(object)或者数组(array)。这些结构可以嵌套

v2-a64524a0cbc5bbaf414aa7405b309303_b.jpg

实例:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript">
    	function test1(){
    		var student = {'id':12,'name':'张三','age':23,'sex':'男'};
    		alert(student.id+"--"+student.name+"--"+student.age+"--"+student.sex);
    	};
    	function test2(){
    		var week = ['星期一','星期二','星期三','星期四','星期五','星期六','星期日'];
    		for(var i=0;i<week.length;i++){
    			alert(week[i]);
    		}
    	};
    	function test3() {
			var stu  =[{'id':1,'name':'张三','age':23,'sex':'男'},{'id':2,'name':'李四','age':24,'sex':'男'}];
			for(var i=0;i<stu.length;i++){
				var student = stu[i];
				alert(student.id+"--"+student.name+"--"+student.age+"--"+student.sex);
			}
		};
    </script>
  </head>
  
  <body>
  	<input type="button" value="测试json格式的对象" onclick="test1()" />
  	<input type="button" value="测试json格式的数组" onclick="test2()" />
  	<input type="button" value="测试json格式的数组对象" onclick="test3()" />
  </body>
</html

-------------------------------------------------------------------------------------------------------------------

JQuery中的AJAX

jquery是js的一个轻量型框架,已经将js创建的操作进行了封装,而ajax也是js的一部分,所以jQuery也已经将ajax进行了封装。

JQuery中封装的方法:

v2-aa6d8a3352108069ec2b1679965340ad_b.jpg

常用的三种:

A. $.get(url,[data],[function])

$.get() 方法通过 HTTP GET 请求从服务器上请求数据

url:请求地址

data:请求参数,参数格式为json对象

function:发送成功时回调函数,注意函数要声明一个形参,用来接收响应数据。

$.get() 方法实现用户名校验(Jquery1-get.jsp):

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript" src="js/jquery-1.9.1.js"></script>
    <script type="text/javascript">
    	$(function(){
    		$("#userName").blur(function(){
    			var userName = $(this).val();
    			//使用JQuery中的$.get(url,[data],[callback])向服务器端发送get的ajax请求
    			$.get("check",{"userName":userName},function(data){
    				if(data=='true'){
    			    	document.getElementById("userNameSpan").innerHTML="<font color=red>用户名已存在!</font>";
    			    }else if(data=='false'){
    			    	document.getElementById("userNameSpan").innerHTML="<font color=green>用户名可用</font>";
    			    }
    			});
    		});
    	});
    </script>
  </head>
  <body>
  	用户名:<input type="text" name="userName" id="userName" /><span id="userNameSpan"></span>
  </body>
</html>

v2-abab238335a8c9a5f981dbc380d86cba_b.jpg

v2-f46f8f5a835567ba9130c5f16241b30c_b.jpg

B. $.post(url,[data],[function])

$.post() 方法通过 HTTP POST 请求向服务器提交数据

url:请求地址

data:请求参数,参数格式为json对象

function:发送成功时回调函数,注意函数要声明一个形参,用来接收响应数据。

$.post() 方法实现用户名校验(Jquery2-post.jsp):

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
	<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
	<script type="text/javascript">
		$(function(){
			$("#userName").blur(function(){
				var userName = $(this).val();
				//使用JQuery中的$.post(url,[data],[callback])向服务器端发送post的ajax请求
				$.post("check",{'userName':userName},function(data){
					if(data=='true'){
    			    	document.getElementById("userNameSpan").innerHTML="<font color=red>用户名已存在!</font>";
    			    }else if(data=='false'){
    			    	document.getElementById("userNameSpan").innerHTML="<font color=green>用户名可用</font>";
    			    }
				});
			});
		});
	</script>
  </head> 
  <body>
  	用户名:<input type="text" name="userName" id="userName" /><span id="userNameSpan"></span>
  </body>
</html>

v2-f787da35e5edbc822141f71d4caec9b5_b.jpg

v2-89b7ee7d8a8ddb1911559d9fa2f9a163_b.jpg

*******************************************************************************************************

注意:

$.post与$.get其实就是对$.ajax进行了更进一步的封装,减少了参数,简化了操作,但是运用的范围更小了

简化了数据提交方式,只能采用POST方式提交。

只能是异步访问服务器,不能同步访问,不能进行错误处理

它的主要几个参数,像method,async等进行了默认设置,我们不可以改变的

C. $.ajax({json格式参数}):参数说明参照api

$.ajax({
  method //数据的提交方式:get和post
  url //数据的提交路径
  async //是否支持异步刷新,默认是true
  data //需要提交的数据
  dataType //服务器返回数据的类型,例如xml,String,Json等
  success //请求成功后的回调函数
  error //请求失败后的回调函数
 });

通过使用这个函数可以完成异步通讯的所有功能

$.ajax中其余参数的设置:

v2-c04915c41f9535be13144e65764bc79d_b.jpg

v2-1dbe26808cb483fcadda2e64b150dba9_b.jpg

v2-3a8f941e53a0418a765f0096ed7f24a2_b.jpg

v2-1666373038d8d2745f59aa05298d3c67_b.jpg

v2-f4308f93b7b659a95a063a5874b79c51_b.jpg

v2-68c0e30e4301fa731bce8b686ba8fe5f_b.jpg

v2-f19e62157c82b0d9e5351bb6a453e238_b.jpg

注意:

v2-da2596d9186ad1341c635b23c814a8b1_b.jpg

$.ajax()方法实现用户名校验(Jquery3-ajax.jsp):

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript" src="js/jquery-1.9.1.js"></script>
    <script>
    	$(function(){
    		$("#userName").blur(function(){
    			var userName = $(this).val();
    			$.ajax({
    				type:'get',
    				url:'check',
    				data:{'userName':userName},
    				//data:'userName='+userName
    				success:function(data){
    					if(data=='true'){
        			    	document.getElementById("userNameSpan").innerHTML="<font color=red>用户名已存在!</font>";
        			    }else if(data=='false'){
        			    	document.getElementById("userNameSpan").innerHTML="<font color=green>用户名可用</font>";
        			    }
    				}
    			});
    		});
    	});
    </script>
  </head>
  <body>
  	用户名:<input type="text" name="userName" id="userName" /><span id="userNameSpan"></span>
  </body>
</html>

v2-9ecbeef93bf31f9e435894d477e76c4f_b.jpg

v2-6fa457584e9c4e5898be3226caf05f73_b.jpg

校验的内容(未连接数据库):

package com.sxt.servlet;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/check")
public class CheckServlet extends HttpServlet{
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		//获取客户端提交的用户名
		String userName = request.getParameter("userName");
		try {
			Thread.sleep(450);//休眠3秒
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//根据用户名查询数据库是否存在
		if("admin".equals(userName)){
			//用户已存在
			out.print("true");
		}else{
			//用户名可用
			out.print("false");
		}
	}
}

v2-0134cbaf21154c5a720eb5648a8de0de_b.jpg

普通方法实现用户名校验(index.jsp):

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>校验用户名是否存在</title>
    <script type="text/javascript">
    	var xmlHttpRequest;
    	//针对不同的浏览器,创建XMLHttpRequest对象
    	function createXMLHttpRequest(){
    		//根据不同的浏览器创建XMLHttpRequest对象
    		if(window.ActiveXObject){//IE浏览器(IE5 IE6)
    			xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
    		}else{
    			xmlHttpRequest = new XMLHttpRequest(); 
    		}
    	}
    	//校验用户名是否存在
    	function checkUserName(){
    		//1.获取输入的用户名
    		var userName = document.getElementById("userName").value;
    		//2.创建XMLHttpRequest对象
    		createXMLHttpRequest();
    		//3.打开连接:xmlHttpRequest.open(method,url,true|false)
    		xmlHttpRequest.open('GET','check?userName='+userName,true);
    		//4.发送请求:send([data]);
    		xmlHttpRequest.send(null);
    		//5.注册回调函数
    		xmlHttpRequest.onreadystatechange=callBack;
    	}
    	//回调函数:处理服务器端返回的结果
    	function callBack(){
    		if (xmlHttpRequest.readyState==4 && xmlHttpRequest.status==200){
			    var content = xmlHttpRequest.responseText;
			    if(content=='true'){
			    	document.getElementById("userNameSpan").innerHTML="<font color=red>用户名已存在!</font>";
			    }else{
			    	document.getElementById("userNameSpan").innerHTML="<font color=green>用户名可用</font>";
			    }
		    }
    	}
    </script>
	</head>
  <body>
  	用户名:<input type="text" name="userName" id="userName" onblur="checkUserName()" /><span id="userNameSpan" ></span>
  </body>
</html>

v2-fc9de450878e866b365885169ec25a65_b.jpg

v2-20ae48b63a7c6ff70096a1fba80b168a_b.jpg

-------------------------------------------------------------------------------------------------------------------------

实例1(省、市、区县的三级联动):

功能需求:

页面中有三个下拉框选项,分别为省下拉框,市下拉框,区/县下拉框

选择省,则市下拉框中出现对应的该省下的市信息,选择市,则区/县下拉框中

出现对应的该市下面的区/县信息

技术分析:

ajax技术+jsp+servlet+jdbc

需求分析(思路):

1、创建页面:页面中有三个下拉框,分别为省、市、区/县

2、页面加载成功发起ajax请求,请求省的信息,并将响应结果

填充到省下拉框中

3、选择省触发一个新的js函数 的执行,该函数中发起新的ajax请求

请求该省下的市信息,并将响应数据填充到市下拉框

4、选择市信息触发一个新的js函数的执行,该函数中发起新的ajax请求

请求该市下的区/县信息,并将数据填充到区/县下拉框中

数据库设计:

创建表(area):存储了省、市、区/县信息

设计表实现一:

地区id:areaid

地区名:areaname

不足:只存储了数据,但是数据之间的层级关系(混乱)没有存储

设计表实现二:

地区id:areaid

地区名:areaname

地区上级id:parentid

sql语句设计:

查询所有的省信息:

select * from area where parentid=0;

查询选择的省的市信息(假如:选择的山东省的areaid为110000,)

select * from area where parentid=110000;

查询选择的市的区/县信息(假如:选择的山东省的济南市areaid为110001)

select * from area where parentid =110001;

提取共性,代码整合

	    	   select * from area where parentid=?;

数据库实现:将资料中提供的area.sql文件导入到数据库中即可

代码缺陷:

发现请求省,市,县的代码中基本上是一致的。代码的冗余量有点大

解决:

考虑使用封装

实现思想:形同的保留,不同的传参

v2-9d1c73df43cc30795956b335b46b5c7e_b.jpg

实现方式一(三种JQuery方式进行操作,但是未实现三级联动):

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript" src="js/jquery-1.9.1.js"></script>
    <script>
    	//省下拉框
    	function loadingProvince() {
    		//使用jquery中的$.get(url,[data],[callback]);
			$.get("select?parentid=0",function(data){
				//使用eval()函数将json字符串转换为json对象
				var json = eval(data);
				for(var i=0;i<json.length;i++){
					var province = json[i];
					//alert(province.areaname);
					$("#province").append("<option value='"+province.areaid+"'>"+province.areaname+"</option>");
				}
			});
		}
    	//市下拉框
    	function loadingCity(value) {
    		//获取当前选中省份的areaid
    		var areaid = value;
    		//使用jquery中的$.post(url,[data],[callback]);
    		$.post("select?parentid="+areaid,function(data){
    			//使用eval()函数将json字符串转换为json对象
				var json = eval(data);
				//清空选项(之前运行保留的信息)
				$("#city").empty();
				for(var i=0;i<json.length;i++){
					var city = json[i];
					$("#city").append("<option value='"+city.areaid+"'>"+city.areaname+"</option>");
				}
    		});
		}
    	//区县下拉框
    	function loadingTown(value) {
			//获取选中市的areaid
			var areaid = value;
			$.ajax({
				type:"get",
				url:"select?parentid="+areaid,
				success:function(data){
					var json = eval(data);
					//清空选项(之前运行保留的信息)
					$("#town").empty();
					for(var i=0;i<json.length;i++){
						var town = json[i];
						$("#town").append("<option value='"+town.areaid+"'>"+town.areaname+"</option>");
					}
				}
			});
		}
    </script>
  </head>
  <body onload="loadingProvince()">
  	省<select name="province" id="province" onchange="loadingCity(this.value)" ></select>
  	市<select name="city" id="city" onchange="loadingTown(this.value)" ></select>
  	区县<select	name="town" id="town" ></select>
  </body>
</html>

v2-16d8ad0aca1bee4b9298b58498846bfc_b.png

实现方式二:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript" src="js/jquery-1.9.1.js"></script>
    <script>
    	$(function(){
    		//省下拉框
        	$.get("select",{parentid:0},function(data){
        		//alert(data);
        		var data = eval(data);
        		//清空原有内容
        		$("#province").empty();
        		for(var i=0;i<data.length;i++){
        			$("#province").append("<option value='"+data[i].areaid+"'>"+data[i].areaname+"</option>");
        		}
        		$("#province").trigger("change");
        	});
        	//市下拉框
        	$("#province").change(function(){
        		var areaid = $("#province").val();
        		$.get("select",{parentid:+areaid},function(data){
        			eval("var data ="+data);
        			//清空原有内容
            		$("#city").empty();
            		for(var i=0;i<data.length;i++){
            			$("#city").append("<option value='"+data[i].areaid+"'>"+data[i].areaname+"</option>");
            		}
            		$("#city").trigger("change");
        		});
        	});
        	//区县下拉框
        	$("#city").change(function(){
        		var areaid = $("#city").val();
        		$.get("select",{parentid:+areaid},function(data){
        			eval("var data ="+data);
        			//清空原有内容
            		$("#town").empty();
            		for(var i=0;i<data.length;i++){
            			$("#town").append("<option value='"+data[i].areaid+"'>"+data[i].areaname+"</option>");
            		}
        		});
        	});
    	});
    </script>
  </head>
  <body>
  	省<select name="province" id="province" ></select>
  	市<select name="city" id="city" ></select>
  	区县<select	name="town" id="town" ></select>
  </body>
</html>

v2-c922b05964f59dd5b8a9c307fbfa4360_b.jpg

效果:

v2-84dfb7235979126cc403fb56342f2956_b.jpg

v2-2966dbcb2d0cf03d5c231e03925ff0f1_b.png

实现方式三(提取共有的代码,将形同的保留,不同的传参):

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript" src="js/jquery-1.9.1.js"></script>
    <script>
    	$(function(){
    		//省下拉框
        		getData(0,"province");
        	//市下拉框
        	$("#province").change(function(){
        		var areaid = $("#province").val();
        		getData(areaid,"city");
        	});
        	//区县下拉框
        	$("#city").change(function(){
        		var areaid = $("#city").val();
        		getData(areaid,"town");
        	});
    	});
    	
    	//提取公共方法
    	function getData(areaid,sid){
    		$.get("select",{parentid:+areaid},function(data){
    			eval("var data ="+data);
    			//清空原有内容
        		$("#"+sid).empty();
        		for(var i=0;i<data.length;i++){
        			$("#"+sid).append("<option value='"+data[i].areaid+"'>"+data[i].areaname+"</option>");
        		}
        		$("#"+sid).trigger("change");
    		});
    	}
    </script>
  </head>
  <body>
  	省<select name="province" id="province" ></select>
  	市<select name="city" id="city" ></select>
  	区县<select	name="town" id="town" ></select>
  </body>
</html>

实例2(搜索框提示功能)

功能需求:

用户在搜索框中输入关键字,然后搜索框下出现下拉选项,提示关键字的提示语。

用户可以使用鼠标进行提示语的选择,也可以使用键盘的上下键来进行选择。

技术分析:

ajax技术+servlet+jsp+jdbc

功能分析(思路):

1、创建搜索界面(搜索框和提示语div和搜索按钮)

2、给搜索框添加onkeyup事件,键盘弹起时发送ajax请求

请求当前用户输入的信息对应的提示语数据

3、将提示语数据填充到搜索框下的div中

问题:

现在用户在搜索框上单击键盘的任意一个键都会发起ajax请求,请求提示语数据。

解决:

判断用户单击的键盘的按键符合要求再发请求。

解决:

获取用户按了键盘的哪个键。使用event对象进行按键的键盘码值获取

4、实现使用鼠标选择提示语

5、实现使用键盘的上和下键选择提示语

6、实现鼠标和键盘的联动操作

7、将显示提示语的div进行隐藏,当有提示语的时候显示隐藏的div

完善:

问题1:只要用户在搜索框中出现键盘点击动作,都会触发键盘事件的执行。

而只要数据符合要求,都会发送ajax请求,请求提示语信息。点击一次都发一次。

但是其实只需要最后一次进行请求发生即可。

解决1:

使用延迟发送请求。

使用1:

window.setTimeout

问题2:

event对象在火狐浏览器中使用window.event获取不到。

解决2:

在获取浏览器中使用传参的方式给event进行赋值。

使用:参照源码即可

数据库设计:

创建表:(data) 存储了常用的关键字数据

关键字编号:id(主键、自增)

关键字数据:title(not null)

说明:remark

添加测试数据:要求前期测试数据为英文单词

SQL语句设计:查询以用户当前搜索框数据开头的关键字

select * from t_data where title like 'a%'
select * from t_data where title like concat(?,'%');

注意:测试数据不要太多。

数据库实现:在数据库中创建表即可,并添加测试数据。

v2-f629439179a2c88478400b5c42ecc665_b.jpg

jsp书写:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
 	<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
 	<script type="text/javascript">
	 	//创建计数器
	 	var count = -1;
	 	//声明变量记录定时执行的编码
	 	var id;
	 	//页面加载成功完成页面资源的初始化
 		$(function(){
 			$("#search").keyup(function(event){
 				//获取event事件(火狐浏览器某些版本使用event直接获取)
 				var even = window.event || event;
 				var code = even.keyCode;
 				//声明正则表达式判断空格
	 			var reg=/^s+$/g;
 				//26个字母   回退键   空格
				if(code>=65&code<=90||code==8||code==32){
					//获取当前搜索框中输入的信息
	 				var message = $("#search").val();
					if(message==""||reg.test(message)){
						return;
					}
					//清空将要发送的请求数据
					window.clearTimeout(id);
					//延迟发送请求
					id = window.setTimeout(function(){
						//$.post("search",{sdata:message},function(data){
						$.get("search",{sdata:message},function(data){
		 					//var sd = eval(data);
		 					eval("var sd ="+data);
		 					//alert(sd)
		 					var dataDiv = $("#dataDiv");
		 					//显示隐藏的div
		 					if(sd.length>0){
			 					dataDiv.css("display","");
		 					}
		 					dataDiv.empty();
		 					for(var i=0;i<sd.length;i++){
		 						//dataDiv.append("<div>'"+sd[i].title+"'</div>");
		 						dataDiv.append("<div>"+sd[i].title+"</div>");
		 					}
		 					//给提示语添加鼠标选择效果
		 					$("#dataDiv div").mouseover(function(){
		 						//清空所有提示语的div的背景颜色
		 			 			$("#dataDiv div").css("background-color","");
		 			 			//将当前选择的div北京颜色变成灰色
		 			 			$(this).css("background-color","gray");
		 			 			//添加鼠标、上下键的联动效果----将当前鼠标选择的div的角标赋值给计数器
		 			 			count=$(this).index();
		 					});
		 					//给提示语div添加单击事件,用来选择提示语
		 			 		$("#dataDiv div").click(function(){
		 			 			//将当前选择的div中的提示语数据改变到搜索框中
		 			 			$("#search").val($(this).html());
		 			 			//隐藏当前填充所有提示语的div
		 			 			$("#dataDiv").css("display","none");	
		 			 		});
		 				});
					},1000);
				}
				//添加向下按键的事件----判断用户点击的是否是键盘的下键
				if(code==40){
					//判断是否有提示语
	 				if($("#dataDiv div").length>0){
	 					//判断向下是否超过界限
	 					count=count<$("#dataDiv div").length-1?++count:0;
	 					//清空所有提示语的div的背景颜色
 			 			$("#dataDiv div").css("background-color","");
	 					//让提示语div中第一个提示语的背景色变成灰色
		 				$("#dataDiv div:eq("+count+")").css("background-color","gray");
		 				//将选择的提示语改变到搜索框中
		 				$("#search").val($("#dataDiv div:eq("+count+")").html());
	 				}
				}
				//添加向上按键的事件----判断用户点击的是否是键盘的上键
				if(code==38){
					//判断是否有提示语
	 				if($("#dataDiv div").length>0){
	 					//判断向上是否超过界限
	 					count=count>0?--count:$("#dataDiv div").length-1;
	 					//清空所有提示语的div的背景颜色
 			 			$("#dataDiv div").css("background-color","");
	 					//让提示语div中第一个提示语的背景色变成灰色
		 				$("#dataDiv div:eq("+count+")").css("background-color","gray");
		 				//将选择的提示语改变到搜索框中
		 				$("#search").val($("#dataDiv div:eq("+count+")").html());
	 				}
				}
 			});
 		});
 	</script>
  </head>
  <body>
  	<!-- 创建div容器将提示语div和搜索框div显示到一起  -->
  	<div id="container" style="width: 550px;margin: auto;">
	  	<!-- 创建div进行搜索框的布局  -->
	  	<div id="sdiv" style="width: 550px;margin: auto;margin-top: 200px;">
	  		<input type="text" name="search"  id="search" value="" style="width:400px;height: 30px;font-size: 18px;" />
	   		<input type="button" value="搜索" style="height: 30px;width: 100px;"/>
	  	</div>
	  	<!-- 提示语div -->
	  	<div id="dataDiv" style="width: 398px;height: 300px;border: solid 1px black;border-top: none;display: none"></div>
  	</div>
  </body>
</html>

v2-9a7bbeeba1e7c26332a31e1206327c17_b.jpg
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值