1.ajax介绍和ajax的访问原理
概念:
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
问题:
怎么在保留当前页面信息的基础上显示新的信息呢
解决:使用ajax
特点:
实现网页的局部刷新
应用前景:
搜索框提示语
地图
网页的其他功能
使用:
ajax的访问原理
访问原理:
第一个ajax程序:
流程:
创建ajax引擎对象
声明事件监听:监听ajax对象的属性readystate的值,一旦readystate的值发生改变就会触发声明的函数的执行
2.ajax状态码
ajax的状态码之readyState的值:
0:表示ajax引擎对象创建
1:表示请求创建但是未发送 ajax.open("get","my");
2:请求发送 ajax.send(null);
3:请求处理完毕,正在接收响应内容
4:响应内容接收完毕(重要状态)
ajax之响应状态码:ajax.status
200:表示一切正常
404:资源未找到
500:服务器内部错误
ajax之响应数据
服务器响应给浏览器的数据应该是字符串类型
但是如果数据量比较大,我们就需要在服务器端将数据拼接成一个良好格式的字符串数据,响应给浏览器。
浏览器根据格式进行数据的解析和使用。
问题:
什么样的格式算是良好的格式呢?
解决:
使用json格式的字符串
//声明单击事件--非ajax
function test() {
window.location.href="my";
}
//声明单击事件--ajax
function testAjax() {
//创建Ajax引擎对象
var ajax;
if(window.XMLHttpRequest){
ajax=new XMLHttpRequest();
}else if(window.ActiveXObject){
ajax=new ActiveXObject("Msxml2.XMLHttp");
}
MyServlet
public class MyServlet 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");
String pwd = req.getParameter("pwd");
//处理请求信息
System.out.println(uname+":"+pwd);
//int i=5/0;
//让线程睡一会儿
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//创建对象
User u = new User(18,"老黑",18,"看电影");
//json格式的字符串
String str = new Gson().toJson(u);
System.out.println(str);
//响应处理结果
//resp.getWriter().write(u.toString());
resp.getWriter().write(str);
}
}
非ajax
ajax
测试介绍添加事件
3.ajax之异步和同步
同步的好处:
1、同步流程对结果处理通常更为简单,可以就近处理。
2、同步流程对结果的处理始终和前文保持在一个上下文内。
3、同步流程可以很容易捕获、处理异常。
4、同步流程是最天然的控制过程顺序执行的方式。
异步的好处:
1、异步流程可以立即给调用方返回初步的结果。
2、异步流程可以延迟给调用方最终的结果数据,在此期间可以做更多额外的工作,例如结果记录等等。
3、异步流程在执行的过程中,可以释放占用的线程等资源,避免阻塞,等到结果产生再重新获取线程处理,
4、异步流程可以等多次调用的结果出来后,再统一返回一次结果集合,提高响应效率。
4.ajax同步异步总结和ajax的请求(get、post)
向服务器发送请求
创建并发送ajax请求
创建ajax请求(设置异步或者同步)
ajax.open(method,url,ansyc);
method:表示请求方式
get方式:请求数据以?隔开的形式拼接在url的后面。
请求数据不能写在send方法中
post方式:
post方式需要单独的进行请求数据的设置。使用ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
设置请求数据为键值对数据。如果有请求数据则ajax.send("键值对数据&键值对数据..."),如果没有请求数据则ajax.send(null)
url:请求地址
ansyc:设置异步或者同步请求,true表示异步,false,表示同步。默认是异步的。
异步:当前js函数继续执行,无须等待ajax请求的响应以及响应的处理。
同步:
当前js函数会等待ajax请求以及响应,当ajax响应处理完毕后,继续执行函数的剩余代码。
发送ajax请求
//get方式
ajax.send(null);
//post方式
ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
ajax.send("uname=张三&pwd=123");
明确流程:
1、创建ajax引擎对象
2、声明监听函数
//判断ajax状态码
//判断响应状态码
//获取响应信息(普通字符串和json格式的字符串)
//处理响应
3、创建并发送ajax请求
创建请求(设置请求方式,设置请求地址,设置异步或者同步)
发送请求
4、其他处理
服务器响应:
//声明单击事件--非ajax
function test() {
window.location.href="my";
}
//声明单击事件--ajax
function testAjax() {
//创建Ajax引擎对象
var ajax;
if(window.XMLHttpRequest){
ajax=new XMLHttpRequest();
}else if(window.ActiveXObject){
ajax=new ActiveXObject("Msxml2.XMLHttp");
}
//声明事件监听
ajax.onreadystatechange=function(){
//判断ajax的状态码
var div = document.getElementById("showdiv");
if(ajax.readyState==4){
//判断ajax响应状态码
if(ajax.status==200){
//处理响应
//获取响应内容
var data = ajax.responseText;
//使用eval方法将字符串数据转换为js对象
eval("var obj="+data)
//获取div对象
div.innerHTML=obj.fav;
}else if(ajax.status==404){
div.innerHTML="请求资源不存在";
}else if(ajax.status==500){
div.innerHTML="服务器内部繁忙";
}else{
div.innerHTML="未知异常";
}
}
}
//发送请求
//get请求方式
//创建请求
ajax.open("get", "my?uname=张三&pwd=123",false);
//发送请求
ajax.send(null);
//post请求方式
//创建请求
ajax.open("post", "my", false);
//设置请求参数为键值对方式
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//发送请求
ajax.send("uname=李四&pwd=456");
//异步同步
var div = document.getElementById("showdiv");
alert(div.innerHTML);
}
//使用js方式添加监听事件及其监听的函数
function testD(){
var btn = document.getElementById("btn");
btn.onclick=function(){
alert("aaaaa");
}
}
//js中的josn对象
//创建js对象
var obj={};
//声明对象内容
obj.name="王五";
obj.pwd="1234";
//使用json方式创建对象
var obj2={
name:"赵六",
pwd:"789"
}
var str="{name:'赵六',pwd:'789'}";
alert(obj.name+":"+obj2.name);
</script>
</head>
<body onload="testD()">
<h3>ajax学习</h3>
<hr />
<input type="button" value="测试非ajax" onclick="test()"/>
<input type="button" value="测试ajax" onclick="testAjax()"/>
<input type="button" id="btn" value="测试js添加事件" />
<div id="showdiv" style="width: 200px;height: 200px;border: solid 1px;"></div>
</body>
</html>
5.json的使用
json的概念:
JSON : JavaScript对象表示法( JavaScript Object Notation)。JSON是轻量级的文本数据交换格式.JSON是一门独立的语言。
其实json就是js创建对象的一种格式。保证对象中数据的紧密性 和完整性。
JSON的语法,数据在名称/值对中 ,方括号保存数组,花括号保存对象 。
json的格式:
var 对象名={
键名:值,
键名:值,
...
键名:值
}
使用:
在服务器端将要响应的数据拼接成json格式的字符串,这样客户端(浏览器端)在接收到响应数据后
可以使用eval方法将json格式的字符串数据直接转换为对应的js对象,便于数据的操作。
我们可以在服务器端使用类似Gson的工具包完成json格式字符串的拼接。
导入gson工具包
相应的代码:
6.ajax之用户名校验ajax代码
功能:
用户名是否被注册校验
思路:
1、用户书写用户名信息,在失去焦点时进行用户校验
2、失去焦点发送请求到服务器,服务器根据用户名信息去数据库中查询该用户名是否存在
3、将校验结果响应给客户端
4、在当前页面,也就用户名输入框后显示提示语
技术:使用ajax技术
reg.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>My JSP 'reg.jsp' starting page</title>
<!--
功能:
用户名是否被注册校验
思路:
1、用户书写用户名信息,在失去焦点时进行用户校验
2、失去焦点发送请求到服务器,服务器根据用户名信息去数据库中查询该用户名是否存在
3、将校验结果响应给客户端
4、在当前页面,也就用户名输入框后显示提示语
技术:
使用ajax技术
-->
<!--声明js代码域 -->
<script type="text/javascript">
//声明用户名校验函数
function checkUname() {
//获取用户名信息
var uname = document.getElementById("uname").value;
//创建ajax引擎对象
var ajax;
if(window.XMLHttpRequest){
ajax=new XMLHttpRequest();
}else{
ajax=new ActiveXObject("Msxml2.XMLHttp");
}
//声明监听函数
ajax.onreadystatechange=function(){
//判断ajax状态码
if(ajax.readyState==4){
//判断响应状态码
if(ajax.status==200){
//获取响应数据(普通字符串或者json格式的字符串)
var data=ajax.responseText;
//处理响应数据
if(Number(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";
}
}
}
}
//创建并发送请求
//创建请求
ajax.open("get","data?uname="+uname);
//发送请求
ajax.send(null);
}
</script>
</head>
<body>
用户名:<input type="text" name="uname" id="uname" value="" onblur="checkUname()" /><span id="unameSpan"></span>
</body>
</html>
7.ajax之用户名校验后台代码完成
pojo实体类
public class User {
private int uid;
private String uname;
private int age;
private String fav;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFav() {
return fav;
}
public void setFav(String fav) {
this.fav = fav;
}
@Override
public String toString() {
return "User [uid=" + uid + ", uname=" + uname + ", age=" + age
+ ", fav=" + fav + "]";
}
public User(int uid, String uname, int age, String fav) {
super();
this.uid = uid;
this.uname = uname;
this.age = age;
this.fav = fav;
}
public User() {
super();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((fav == null) ? 0 : fav.hashCode());
result = prime * result + uid;
result = prime * result + ((uname == null) ? 0 : uname.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (age != other.age)
return false;
if (fav == null) {
if (other.fav != null)
return false;
} else if (!fav.equals(other.fav))
return false;
if (uid != other.uid)
return false;
if (uname == null) {
if (other.uname != null)
return false;
} else if (!uname.equals(other.uname))
return false;
return true;
}
}
DataDao接口类
package com.sxt.dao;
public interface DataDao {
/**
* 查询用户名是否注册
* @param uname
* @return
*/
boolean checkUnameInfoDao(String uname);
}
DataDaoImpl实现类
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{
//查询用户名是否存在 select * from t_user where uname=?;
public boolean checkUnameInfoDao(String uname) {
//声明jdbc变量
Connection conn = null;
PreparedStatement ps =null;
ResultSet rs = null;
//声明变量
boolean flag = false;
//创建连接
try {
conn=DBUtil.getConnection();
//创建SQL命令
String sql = "select * from t_user where uname=?";
//创建SQL命令对象
ps=conn.prepareStatement(sql);
//给占位符赋值
ps.setString(1, uname);
//执行
rs = ps.executeQuery();
//遍历
if(rs.next()){
flag=true;
}
//关闭资源
} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.closeAll(rs, ps, conn);
}
return flag;
}
}
DataService接口类
package com.sxt.service;
public interface DataService {
/**
* 校验用户名是否被注册
* @param uname
* @return
*/
boolean checkUnameInfoService(String uname);
}
DataServiceImpl实现类
package com.sxt.service.impl;
import com.sxt.dao.DataDao;
import com.sxt.dao.impl.DataDaoImpl;
import com.sxt.service.DataService;
public class DataServiceImpl implements DataService {
//创建Dao层对象
DataDao dd = new DataDaoImpl();
//校验用户名是否被注册
public boolean checkUnameInfoService(String uname) {
return dd.checkUnameInfoDao(uname);
}
}
DataServlet类
import java.io.IOException;
import javax.servlet.ServletException;
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");
//处理请求信息
//获取业务层对象
DataService ds = new DataServiceImpl();
//校验用户信息
boolean flag = ds.checkUnameInfoService(uname);
System.out.println(flag);
//响应处理结果
if(flag){
resp.getWriter().print(1);
}else{
resp.getWriter().print(0);
}
}
}
8.封装自己的ajax
ajax封装:
问题:
我们发现在使用ajax进行业务处理时,ajax的代码其实很多地方是相同的。
这样造成编写代码时出现了重复编写,影响了开发的效率。
解决:
使用封装
实现:相同的保留,不同的传参。
请求方式:method
请求地址:url
请求参数:data 请求参数的格式为键值对格式的字符串,不同的键值对使用&符号隔开.如果没有 请求数据传入null
示例:"a=1&b=2"
异步同步设置:ansyc
响应处理参数:deal200
该参数接收一个js的函数对象,函数对象中声明ajax响应数据的处理逻辑代码。
注意:函数对象需要声明一个形参用来接收要处理的响应数据
<%@ 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>My JSP 'fz.jsp' starting page</title>
<!--引入js文件 -->
<script type="text/javascript" src="js/AjaxUtil.js"></script>
<script type="text/javascript">
//使用ajax进行处理--演示调用
myAjax("get","data","uname=张三",function(a){
alert(a);
})
</script>
</head>
<body>
<h3>ajax封装学习</h3>
<hr/>
</body>
</html>
Ajax.js封装的数据
//声明用户名校验函数
function myAjax(method, url, data, deal200, ansyc) {
//创建ajax引擎对象
var ajax;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
} else {
ajax = new ActiveXObject("Msxml2.XMLHttp");
}
//声明监听函数
ajax.onreadystatechange = function() {
//判断ajax状态码
if (ajax.readyState == 4) {
//判断响应状态码
if (ajax.status == 200) {
//获取响应数据(普通字符串或者json格式的字符串)
var data = ajax.responseText;
//处理响应数据
if (deal200) {
deal200(data);
}
}
}
}
}
//创建并发送请求
if ("get" == method.toLowerCase()) {
//创建请求
ajax.open("get", url + (data == null ? "" : "?" + data), ansyc);
//发送请求
ajax.send(null);
} else if ("post" == method.toLowerCase()) {
//创建请求
ajax.open("post", url, ansyc);
//设置请求参数为键值对方式
ajax.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
//发送请求
ajax.send(data);
}