一、Ajax简介
1. Ajax的应用场景
1.在线视频、直播平台等…评论实时更新、点赞、小礼物、…
2.会员注册时的信息验证,手机号、账号唯一
3.百度关键搜索补全功能
2. Ajax简介
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
Ajax 是一种用于创建快速动态网页的技术。
Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
3. 同步方式与异步方式区别
同步方式发送请求 :
发送一个请求,需要等待响应返回,然后才能够发送下一个请求,如果该请求没有响应,不能发送下一个请求,客户端会处于一直等待过程中。
异步方式发送请求 :
发送一个请求,不需要等待响应返回,随时可以再发送下一个请求,即不需要等待。
以下所有内容整合到一个JavaWeb项目中,用到的所有依赖文件如下图所示
二、JS原生方式实现异步
1. 实现步骤
1. 定义一个XMLHttpRequest核心对象;
2. 通过核心对象.open方法给当前对象提供访问方式、URL等。
3. 发送当前的请求至指定的URL
4. 接收返回值并处理
案例需求
需求:
前台页面通过一个按钮向后台发送一个Ajax请求,后台做完处理后向前台页面响应一段文本信息显示在页面上。
JSP代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Js原生方法实现异步Ajax</title><script type="text/javascript">function testJsAjax(){//1、创建核心对象var xmlhttp = new XMLHttpRequest();//2、通过核心对象方法给当前的对象提供访问路径和URL路径xmlhttp.open("GET","jsAjax?name=Tom",true);//3、发送当前的请求至指定的URLxmlhttp.send();//4、接收返回值并处理xmlhttp.onreadystatechange = function () {//xmlhttp.readyState==4 代表XMLHttpRequest对象读取服务器的响应结束。xmlhttp.status==200代表响应成功if(xmlhttp.readyState==4 && xmlhttp.status==200){var msg = xmlhttp.responseText;document.getElementById("msg").innerHTML=msg;}}}</script>
</head>
<body>
<div id="msg"></div>
<input type="button" name="btn" value="JsOriginalAjax" onclick="testJsAjax()">
</body>
</html>
Servlet控制层代码
package com.jn.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;
@WebServlet("/jsAjax")
public class JsAjaxServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");//获取名称String name = req.getParameter("name");System.out.println(name);//响应resp.getWriter().write("Response Successful");}
}
三、jQuery方式实现异步
JS版的Ajax仅做为了解,我们重点学习jQuery版的Ajax,jQuery是一个优秀的js框架,自然对JS原生的Ajax进行了封装,封装后的Ajax的操作方法更简洁,功能更强大,这也是程序员最普遍使用,语法结构简单,代码可读性好。
与Ajax操作相关的jQuery方法经常使用的有三种:
请求方式 语法
Ajax请求 $.ajax([settings])
GET请求 $.get(url, [data], [callback], [type])
POST请求 $.post(url, [data], [callback], [type])
1. Ajax请求
语法格式:
$.ajax({
url:"",
data:{},
type:"post/get",
async:true,
dataType:"text",
success:function(obj){
},
error:function(){
}
})
属性解析:
参数名称 描述
url 请求的服务器端url地址, 与form表单中的action一样,都是代表请求的路径
data 前台需要向后台传递的数据(键值对形式)
type 和form表单中method对应,代表请求类型 get/post
async 取值是布尔类型true/false,分别表示异步和同步,默认为true(异步),一般不建议写
dataType 回传的数据类型。text、xml、html、json...
success 成功的回调函数,参数obj表示返回值
error 失败的回调函数,一般不写
注意事项:
1、每个属性后都要跟随一个英文逗号,最后一个不用。
2、每一个属性都是键值对的形式存在,中间用英文冒号:隔开
3、data:{} 是一个特殊的写法,值是一个{},里面使用键值对存储
例如:data:{“键1”:值1, “键2”:值2, “键3”:值3}
4、以上属性没有先后顺序要求
Jsp页面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Jquery实现Ajax的请求</title><script src="./js/jquery-3.3.1.js"></script><script>//页面加载时间$(function () {//为按钮绑定点击事件$("#btn").click(function () {$.ajax({url:"ajaxTest",data:{"uname":"Tom","age":18},type:"GET",dataType:"text",async:true,//一般省略不写success:function (obj) {//将控制层操作成功的响应信息通过弹窗展示alert(obj);},error:function () {alert("error")}})})})</script>
</head>
<body>
<input type="button" id="btn" value="Ajax Request">
</body>
</html>
Servlet控制层代码
package com.jn.servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/ajaxTest")//访问地址与ajax里面的访问路径一致
public class AjaxServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取页面传递过来的参数String uname = req.getParameter("uname");String age = req.getParameter("age");System.out.println("Name:" + uname + "\tAge:" + age);//制造一个错误,然后测试ajax的错误回调函数//System.out.println(1 / 0);//响应文本resp.getWriter().write("Response Ok");}
}
效果演示
2. GET请求
语法格式:
$.get(url, [data], [callback], [type]);
属性解析:
参数名称 描述
url 请求的服务器端url地址, 与form表单中的action一样,都是代表请求的路径
data 前台需要向后台传递的数据(键值对形式)
callback 当请求成功后的回掉函数,可以在函数体中编写我们的逻辑代码
type 预期的返回数据的类型,取值可以是 text、xml、html、json...
注意事项:
这种写法功能和$.ajax是一样的,但是严格要求属性顺序。
Jsp页面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>GET请求实现异步</title><script src="./js/jquery-3.3.1.js"></script><script>$(function () {$("#btn").click(function () {$.get("getTest",{"uname":"Tom","age":18},function (obj) {//接收响应的文本信息alert(obj);},"text")})})</script>
</head>
<body>
<input type="button" id="btn" value="Ajax Request">
</body>
</html>
Servlet控制层代码
package com.jn.servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/getTest")
public class GetServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取页面参数String uname = req.getParameter("uname");String age = req.getParameter("age");System.out.println("Name:" + uname + "\tAge:" + age);//响应resp.getWriter().write("Response Ok");}
}
效果演示
3. POST请求
语法格式:
$.post(url, [data], [callback], [type]);
属性解析:
参数名称 描述
url 请求的服务器端url地址, 与form表单中的action一样,都是代表请求的路径
data 前台需要向后台传递的数据(键值对形式)
callback 当请求成功后的回掉函数,可以在函数体中编写我们的逻辑代码
type 预期的返回数据的类型,取值可以是 text、xml、html、json...
注意事项:
这种写法功能和$.ajax是一样的,但是严格要求属性顺序。
4. $.ajax与$.get|$.post异同
相同点:都是jQuery封装的方法实现异步交互。
不同点:
$.ajax()是jQuery的第一次封装,使用时稍显麻烦,但是功能强大,覆盖了get和post请求,有错误调试能力,写法顺序可以改变。
$.post()和$.get()是jQuery Ajax的第二次封装,由于$.Ajax()写法过于臃肿,简化为$.post()和$.get(),功能是相同的没有区别。但是写法要求更高,顺序不能改变。
Jsp页面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Post请求实现异步</title><script src="./js/jquery-3.3.1.js"></script><script>$(function () {$("#bt").click(function () {$.post("postTest",{"uname":"Bob","age":18},function (obj) {alert(obj);},"text")})})</script></head>
<body>
<input type="button" id="bt" value="Post请求实现异步">
</body>
</html>
Servlet控制层代码
package com.jn.servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/postTest")
public class PostServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取页面参数String uname = req.getParameter("uname");String age = req.getParameter("age");System.out.println("Post Name:" + uname + "\tPost Age:" + age);//响应resp.getWriter().write("Response Successful");}
}
效果演示
四、Ajax校验用户是否唯一案例
案例需求
在用户注册页面,输入用户名,当用户名输入框失去焦点时,发送异步请求,将输入框的用户名传递给服务器端进行是否存在的校验。
实现步骤
1、输入框焦点事件
2、发送post请求
3、指定字符串判断
4、前端页面响应
Jsp页面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>用户唯一检验案例</title><script src="./js/jquery-3.3.1.js"></script><script>$(function () {$("#uname").blur(function () {var uname = $("#uname").val();// 判断用户名不为空var req = /^\s*$/;if (req.test(uname)) {$("#msg").html("用户名不能为空").css("color", "red");return;}// 发送 ajax 请求$.post("regist",{"uname": uname},function (obj) {// 修改这里的判断逻辑if (obj === "false") {$("#msg").html("用户名已被占用").css("color", "red");} else {$("#msg").html("可用的用户名").css("color", "green");}},"text")})})</script>
</head>
<body>
<p>用户名: <input type="text" id="uname" name="uname"><span id="msg"></span>
</p>
<p><input type="button" value="注册">
</p>
</body>
</html>
Servlet控制层代码
package com.jn.servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;@WebServlet("/regist")
public class RegisterServlet extends HttpServlet {@Overridepublic void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//解决中文乱码问题request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");String uname = request.getParameter("uname");Boolean flag;//判断if("liuyan".equals(uname)){flag = true;}else{flag = false;}// 响应PrintWriter writer = response.getWriter();writer.print(!flag);}
}
效果演示
五、Json
(一)、Ajax的返回值类型
Ajax支持多种返回值类型:
XML:太麻烦,解析太费劲,已经不使用
HTML:网页,其实质和返回文本一样,没区别,一般使用文本代替
Script: 直接返回脚本
Text(文本):(默认返回类型)字符串类型,返回直接接收字符串
Json:返回是一个js对象,脚本中可以直接操作这个对象,非常方便
Jsonp:和Json一样,只不过这个支持跨域访问。
(二)、JSON
1、JSON数据格式
(1). JSON介绍
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
(2). JSON语法格式
JSON对象的语法有三种:对象、数组、混合模式
类型 语法 解释
对象类型 {name:value,name:value...} 其中name是字符串类型,而value是任意类型
数组类型 [value,value,value...] 其中value是任意类型
混合类型 [{},{}... ...] 或 {name:[]... ...} 合理包裹嵌套对象类型和数组类型
(3). JSON格式书写规范
1.使用{}和[]书写,{}表示对象类型,[]表示数组类型
2.对象类型中每组数据之间用逗号隔开,每组中的关键字与值之间用冒号隔开
3.数组类型中每个值之间用逗号隔开,最后一个值后面不要加逗号
2、JSON工具使用
JSON在线解析工具:http://www.bejson.com/
作用:
1.校验JSON数据的语法是否正确
2.将不规范的JSON格式数据进行格式化
3、JSON数据的应用
json的转换工具是通过java封装好的一些jar工具包,直接将java对象或集合转换成json格式的字符串。
4、常见的json转换工具
工具名称 介绍 Jsonlib Java 类库,需要导入的jar包较多 Gson google提供的一个简单的json转换工具 Fastjson alibaba技术团队提供的一个高性能的json转换工具 Jackson 开源免费的json转换工具,springmvc转换默认使用jackson
1) 导入json相关jar包
2) 创建java对象或集合
3) 使用jackson的ObjectMapper对象的writeValueAsString方法进行转换
5. 转换代码实现
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<script>//对象类型的json创建var jsonObj = {"name":"tom","age":18};console.log("获取对象类型的json数据:"+jsonObj.name)//数组类型的json创建var jsonArr = ["name","tom","age",18,true];for (var i = 0; i < jsonArr.length; i++) {console.log("Json数组中第"+(i+1)+"个值是:"+jsonArr[i])}var jsonMix = {"name":"Tom","age":18,"hobby":["唱","跳","Rap"]}console.log(jsonMix.name+jsonMix.age+jsonMix.hobby.toString())
</script></body>
</html>
六、JackSon
1、jackSon简介
Java中万事万物皆对象,Jackson库就是是一个基于Java语言的开源JSON格式解析工具。它的主要功能是提供JSON解析和生成,简单来说,Jackson就是用于将Java对象与JSON数据进行互相转换。
2、jack的jar包导入
3、代码演示
实体类
package com.jn.bean;public class User {private String uid;private String uname;private String password;private int age;public User() {}public String getUid() {return uid;}public void setUid(String uid) {this.uid = uid;}public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"uid='" + uid + '\'' +", uname='" + uname + '\'' +", password='" + password + '\'' +", age=" + age +'}';}
}
测试类
package com.jn.Test;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jn.bean.User;import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;public class UseJsonTool {public static void main(String[] args) throws JsonProcessingException {User user = new User();user.setUid("123456");user.setUname("陈奕迅");user.setPassword("888888");user.setAge(33);//创建list集合ArrayList<String> list = new ArrayList<>();list.add("周星驰");list.add("黄依圣");list.add("包租婆");//创建map集合Map map = new HashMap<>();map.put("KongFu Name1:","九阳神功");map.put("KongFu Name2:","辟邪剑谱");map.put("KongFu Name3:","吸星大法");//转化为json数据ObjectMapper mapper = new ObjectMapper();String userJson = mapper.writeValueAsString(user);String listJson = mapper.writeValueAsString(list);String mapJson = mapper.writeValueAsString(map);System.out.println(userJson);System.out.println(listJson);System.out.println(mapJson);}
}
七、搜索框自动补全功能实现
实现步骤
1、实体类创建
package com.jn.bean;public class Student {private int jid;private String jname;private int jage;private String jgongfu;private String jxingge;public Student() {}public int getJid() {return jid;}public void setJid(int jid) {this.jid = jid;}public String getJname() {return jname;}public void setJname(String jname) {this.jname = jname;}public int getJage() {return jage;}public void setJage(int jage) {this.jage = jage;}public String getJgongfu() {return jgongfu;}public void setJgongfu(String jgongfu) {this.jgongfu = jgongfu;}public String getJxingge() {return jxingge;}public void setJxingge(String jxingge) {this.jxingge = jxingge;}@Overridepublic String toString() {return "Student{" +"jid=" + jid +", jname='" + jname + '\'' +", jage=" + jage +", jgongfu='" + jgongfu + '\'' +", jxingge='" + jxingge + '\'' +'}';}
}
2、查询数据库函数封装
package com.jn.dao;import com.jn.utils.JDBCUtil;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;public class Dao<T> {private QueryRunner queryRunner=new QueryRunner();//通用增删改public int update(String sql,Object...objects) {Connection connection = JDBCUtil.getConnection();int update=0;try {update = queryRunner.update(connection, sql, objects);} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtil.closeConn(connection);}return update;}//查询单条数据public T getBean(String sql,Class<T> cls,Object...objects) {Connection connection = JDBCUtil.getConnection();BeanHandler<T> bh=new BeanHandler<T>(cls);T t=null;try {t = queryRunner.query(connection, sql, bh, objects);} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtil.closeConn(connection);}return t;}//查询多条数据public List<T> getBeanList(String sql, Class<T> cls, Object...objects) {Connection connection = JDBCUtil.getConnection();BeanListHandler<T> bh=new BeanListHandler<T>(cls);List<T> list=null;try {list = queryRunner.query(connection, sql, bh, objects);} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtil.closeConn(connection);}return list;}//查询聚合数据public Object getScaleValue(String sql,Object...objects) {Connection connection = JDBCUtil.getConnection();ScalarHandler scalarHandler = new ScalarHandler();Object obj=null;try {obj = queryRunner.query(connection, sql, scalarHandler, objects);} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtil.closeConn(connection);}return obj;}
}
package com.jn.dao;import com.jn.bean.Student;
import org.junit.Test;import java.util.List;public class StudentDao {Dao dao = new Dao();public List<Student> searchWord(String word) {String sql = "select * from student where jname like ?";List<Student> beanList = dao.getBeanList(sql, Student.class, "%" + word + "%");return beanList;}
/*@Testpublic void addMethod(){String sql="select * from student";List<Student> list = dao.getBeanList(sql, Student.class,null);for (Student student : list) {System.out.println(student);}}*/}
3、数据库添加数据
4、查询数据库函数验证
package com.jn.service;import com.jn.bean.Student;
import com.jn.dao.StudentDao;import java.util.List;public class SearchService {public List<Student> searchWord(String word) {StudentDao sd = new StudentDao();return sd.searchWord(word);}
}
5、数据库连接工具
package com.jn.utils;import com.mchange.v2.c3p0.ComboPooledDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;public class JDBCUtil {private static DataSource dataSource=null;static{dataSource=new ComboPooledDataSource("mysql");}/*** 获取数据库连接* @return*/public static Connection getConnection(){Connection conn=null;try {conn=dataSource.getConnection();} catch (SQLException e) {e.printStackTrace();}return conn;}/*** 关闭数据库连接* @param conn*/public static void closeConn(Connection conn){try {if(conn!=null && conn.isClosed()){conn.close();}} catch (SQLException e) {e.printStackTrace();}}
}
6、Jsp页面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title><style type="text/css">* {margin: 0px;padding: 0px;}#box {display: inline-block;}#search {width: 545px;height: 42px;border-color: #4E6EF2;border-top-left-radius: 10px;border-bottom-left-radius: 10px;float: left;}#btn {width: 108px;height: 42px;background-color: #4e6ef2;color: #fff;border: none;font-size: 17px;font-weight: 400;border-top-right-radius: 10px;border-bottom-right-radius: 10px;float: left;}#show {width: 545px;border: 1px solid #4e6ef2;position: relative;left: -55px;text-align: left;}</style><script src="./js/jquery-3.3.1.js"></script><script>$(function(){//绑定键盘弹起事件$("#search").bind('input porpertychange',function(){//获取输入框的值var word = $(this).val();//判断不为空if(word != ""){console.log(word)//发送ajax请求$.ajax({url:"searchWord",data:{"word":word},type:"post",dataType:"json",success:function(obj){var htmlStr = "";for(var i = 0; i < obj.length; i++){console.log(obj[i].jname)htmlStr += "<div>"+obj[i].jname+"</div>";}$("#show").html(htmlStr).show();}})}else{$("#show").hide();}})})</script>
</head>
<body>
<center><img alt="" width="310" height="150" src="${pageContext.request.contextPath }/img/baidu.png"><br/><div id="box"><input id="search" type="text" name="search"/><button id="btn">百度一下</button></div><div id="show"></div>
</center>
</body>
</html>
7、Servlet控制层实现
package com.jn.servlet;import com.fasterxml.jackson.databind.ObjectMapper;
import com.jn.bean.Student;
import com.jn.service.SearchService;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;
import java.util.List;@WebServlet("/searchWord")
public class SearchServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//解决中文乱码req.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");//获取关键字String word = req.getParameter("word");//业务处理(查询数据库)SearchService ss = new SearchService();List<Student> sList = ss.searchWord(word);//System.out.println(sList);//将list集合转发为json集合if (sList !=null && sList.size()>0){ObjectMapper mapper = new ObjectMapper();String sListJson = mapper.writeValueAsString(sList);System.out.println(sListJson);//响应给页面resp.getWriter().print(sListJson);}}
}
效果演示