AJAX 介绍
- AJAX(Asynchronous JavaScript And XML): 异步的JavaScript和XML
- 本身不是新技术, 而是多个技术的综合. 用于快速创建动态网页的技术.
- 一般的负面如果需要更新内容, 必需重新加载整个页面
- 而AJAX通过浏览器与服务器进行少量数据交换, 不可以使网页异步更新. 不重新加载整个页面, 对网页部分内容局部更新
原生JavaScript 实现AJAX
- 核心对象:xMLHttpRequest
- 用于在后台与服务器交换数据。可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
- 打开链接:open(method,url,async)
- method :请求的类型 GET 或 POST.
- url:请求资源的路径,
- async:true(异步) 或false(同步)。
- 发送请求:send(String params)
- params:请求的参数(POST 专用)。
- 处理响应:onreadystatechange
- readyState :0-请求末初始化,1-服务器连接已建立,2-请求已接收 ,3-请求处理中,4-请求已完成,且响应已就绪。
- status:200-响应已全部OK。
- 获得响应数据形式
- response Text :获得字符串形式的响应数据。
- responseXML:获得XML形式的响应
jQuery的Get方式实现AJAX
- 核心语法:$.get(url,[data],[callback],[type]);
- url:请求的资源路径
- data:发送给服务器端的请求参数,格式可以是key=value,也可以是js对象
- callback :当请求成功后的回调函数,可以在函数中编写我们的逻辑代码
- type : 预期的返回数据的类型, 取值可以是xml, html, js, ison, text等
@WebServlet("/userServlet")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
// 1. 获取请求参数
String username = req.getParameter("username");
// 2. 判断姓名是否注册
if("zhangsan".equals(username)){
resp.getWriter().write(("<font color='red'>用户名已注册</font>"));
}else{
resp.getWriter().write(("<font color='green'>用户名可用</font>"));
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
</head>
<body>
<form autocomplete="off" >
姓名: <input type="text" id="username">
<span id="uSpan"></span>
<br>
密码: <input type="password" id="password">
<br>
<input type="submit" value="注册">
</form>
</body>
<script src="js/jquery-3.6.0.min.js"></script>
<script>
// 1. 为姓名绑定推动焦点事件
$("#username").blur(function(){
let username = $("#username").val();
// 2. jQuery的get方式实现AJAX
$.get(
"userServlet",
"username="+username,
// 3. 回调函数
function(data){
// 将响应的数据显示到span标签
$("#uSpan").html(data)
},
"text"
);
})
</script>
</html>
jQuery的POST方式实现AJAX
- 核心语法:$.post(url,[data],[callback],[type])
- url:请求的资源路径
- data:发送给服务器端的请求参数,格式可以是key=value,也可以是js对象
- callback :当请求成功后的回调函数,可以在函数中编写我们的逻辑代码
- type : 预期的返回数据的类型, 取值可以是xml, html, js, ison, text等
<script src="js/jquery-3.6.0.min.js"></script>
<script>
// 1. 为姓名绑定推动焦点事件
$("#username").blur(function(){
let username = $("#username").val();
// 2. jQuery的POST方式实现AJAX
$.post(
"userServlet",
"username="+username,
// 3. 回调函数
function(data){
// 将响应的数据显示到span标签
$("#uSpan").html(data)
},
"text"
);
})
</script>
jQuery的通用方式实现AJAX
- 核心语法: $.ajax({name:value,name:value,…});
- url :请求的资源路径.
- async :是否异步请求,true-是,false-否(默认是true)。
- data:发送到服务器的数据,可以是键值对形式,也可以是js对象形式。
- type:请求方式,POST或GET (默认是GET)。
- dataType:预期的返回数据的券型,取值可以是xml,html,js, json, text等。
- success :请求成功时调用的回调函数。
- error :请求失败时调用的回调函数。
<script src="js/jquery-3.6.0.min.js"></script>
<script>
// 1. 为姓名绑定推动焦点事件
$("#username").blur(function(){
let username = $("#username").val();
$.ajax({
url: "userServlet",
async: true,
data: "username=" + username,
type: "GET",
success: function (data) {
$("#uSpan").html(data)
},
dataType: "text",
error: function () {
$("#uSpan").html("<font color='red'>出错了, 请稍后重试</font>")
}
});
})
</script>
JSON 格式
类型 | 语法 | 说明 |
---|---|---|
对象类型 | {name:value,name:value,…} | name是字符串类型, value可以是任意类型 |
数组/集合类型 | [{name:value,…},{name:value,…}] | name是字符串类型, value可以是任意类型 |
混合类型 | {name: [{name:value,…},{name:value,…}] } |
name是字符串类型, value可以是任意类型 |
- 常用方法
成员方法 说明
stringify(对象) 将指定对象转换为json格式字符串
parse(字符串) 将指定json格式字符串解析成对象
- JSON Java 转换工具 jackson
类名 说明
ObjectMapper Jackson工具包的核心类,它提供一些方法来实现JSON字符串和对象之间的转换
TypeReference 对集合泛型的反序列化,使用TypeReference可以明确的指定反序列化的对象类型
- ObjectMappper 常用方法
方法名 说明
String.writeValueAsString(Object.obj) 将Java对象转换成JSON字符串
<T>T.readValue(String.json,Class<T>.valueType) 将JSON字符串转换成Java对象
<T>T.readValue(String.json,TypeReference.valueTypeRef) 将JSON字符串转换成Java对象
public class User {
private String name;
private Integer age;
public User(){}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
package com.example.ajax2;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import com.example.ajax2.User;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ObjectMapperTest {
private ObjectMapper mapper = new ObjectMapper();
// 1. User对象转换json, json转User对象
@Test
public void test01() throws JsonProcessingException {
User user1 = new User("张三", 23);
String json = mapper.writeValueAsString(user1);
System.out.println("json字符串"+json);
User user2 = mapper.readValue(json, User.class);
System.out.println("Java对象"+user2);
}
// 2.map<String,String>转json json转map<String,String>
@Test
public void test02() throws IOException {
Map<String,String> map = new HashMap<>();
map.put("姓名","张三");
map.put("性别","男");
String json = mapper.writeValueAsString(map);
System.out.println("json字符串"+json);
HashMap map2 = mapper.readValue(json, HashMap.class);
System.out.println("Map对象"+map2);
}
// 3. map<String,User>转json json转map<String,User>
@Test
public void test03() throws Exception{
Map<String, User> map1 = new HashMap<>();
map1.put("1", new User("张三",23));
map1.put("2", new User("李四",24));
String json = mapper.writeValueAsString(map1);
System.out.println("json字符串"+json);
HashMap map2 = mapper.readValue(json, new TypeReference<HashMap<String, User>>() {} );
System.out.println("Map对象"+map2);
}
// 4.List<String>转json, json转List<String>
@Test
public void test04() throws Exception{
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
String json = mapper.writeValueAsString(list);
System.out.println("json字符串"+json);
// ArrayList<String> list2 = mapper.readVal ue(json, new TypeReference<ArrayList<String>>() { });
ArrayList<String> list2 = mapper.readValue(json, ArrayList.class);
System.out.println("List<string>集合"+list2);
}
// 5. List<User>转json, json转List<User>
@Test
public void test05() throws Exception {
ArrayList<User> list1 = new ArrayList<>();
list1.add(new User("张三",23));
list1.add(new User("李四",24));
String json = mapper.writeValueAsString(list1);
System.out.println("json字符串"+json);
ArrayList<User> list2 = mapper.readValue(json, new TypeReference<ArrayList<User>>() {
});
System.out.println("List对象"+list2);
}
}
搜索联想
package com.lizicai.bean;
public class Student {
private Integer id;
private String name;
private Integer age;
private Integer score;
public Student(){}
public Student(Integer id, String name, Integer age, Integer score) {
this.id = id;
this.name = name;
this.age = age;
this.score = score;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>搜索</title>
</head>
<body>
<form autocomplete="off" >
姓名: <input type="text" id="username" list="userlist" placeholder="输入名称搜索">
<datalist id="userlist">
</datalist>
</form>
</body>
<script src="js/jquery-3.6.0.min.js"></script>
<script>
// 1. 为用户名输入框绑定鼠标点击事件
$("#username").mousedown(function(){
// 2. 获取用户名是否为空
let username = $("#username").val();
if( username == null || username == ""){
return;
}else{
$.ajax({
url: "userServlet",
async: true,
data: {"username":username},
type: "POST",
success: function (data) {
let names = "";
console.log(data)
for(let i=0;i<data.length;i++){
names +="<option>"+data[i].name+"</option>";
console.log(data[i])
}
$("#userlist").html(names)
},
dataType: "json"
});
}
})
</script>
</html>
package com.lizicai.sql;
import org.apache.ibatis.jdbc.SQL;
public class ReturnSql {
public String getSelectLikeName(){
return new SQL(){
{
SELECT("*");
FROM("student");
WHERE("name like CONCAT('%',#{name},'%')");
ORDER_BY("score DESC");
LIMIT("0,4");
}
}.toString();
}
}
package com.lizicai.mapper;
import com.lizicai.bean.Student;
import com.lizicai.sql.ReturnSql;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface StudentMapper {
@SelectProvider(type = ReturnSql.class, method = "getSelectAll")
public abstract List<Student> selectAll();
@SelectProvider(type = ReturnSql.class, method = "getSelectLikeName")
public abstract List<Student> selectLikeName(String name);
}
package com.lizicai.service;
import com.lizicai.bean.Student;
import com.lizicai.mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Test001 {
@Test
public List<Student> selectLikeName(String name) throws IOException {
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectLikeName(name);
for (Student stu : students) {
System.out.println(stu);
}
sqlSession.close();
is.close();
return students;
}
}
package com.lizicai.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lizicai.bean.Student;
import com.lizicai.service.Test001;
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 java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
@WebServlet("/userServlet")
public class UserServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String username = req.getParameter("username");
ObjectMapper mapper = new ObjectMapper();
Test001 t = new Test001();
List<Student> list = t.selectLikeName(username);
String json = mapper.writeValueAsString(list);
resp.setContentType("application/json; charset=utf-8");
PrintWriter pw = resp.getWriter();
pw.write(json);
pw.close();
}
}
瀑布流分页
create database db11;
use db11;
CREATE TABLE news(
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(999)
);
DELIMITER $$
CREATE PROCEDURE create_date()
BEGIN
DECLARE i INT;
SET i=1;
WHILE i<=100 do
INSERT INTO news VALUES (NULL,CONCAT('今天吃瓜啦,瓜',i));
SET i=i+1;
end WHILE;
end $$
CALL create_date();
- 如何确定当前显示的数据已经浏览完毕
- 公式: 滚动条距询问的距离+滚去条上下滚动的距离+当前窗口的高度>=100
- 当前文档高度: 存储10条数据,100px
- 滚去条距询问的距离: 1px
- 当前窗口的高度: 80px
- 滚去条上下滚去的距离: >=19px
- 前置知识
功能 说明
$(function(){}) 页面加载事件
$(window) 获取当前窗口对象
scroll() 鼠标滚去事件
$(window).height() 当前窗口的高度
$(window).scrollTop() 滚去条上下滚去的距离
$(document).height() 当前文档的高度
package com.lizicai.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.lizicai.bean.News;
import com.lizicai.service.NewsService;
import com.lizicai.service.impl.NewsServiceImpl;
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 java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
@WebServlet("/newsList")
public class NewsServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String pageNum = req.getParameter("pageNum");
String pageSize = req.getParameter("pageSize");
System.out.println(pageNum+" "+pageSize+"----");
Integer intPageNum = Integer.parseInt(pageNum) ;
Integer intPageSize = Integer.parseInt(pageSize) ;
ObjectMapper mapper = new ObjectMapper();
NewsService newsService = new NewsServiceImpl();
Page<News> page = newsService.pageQuery(intPageNum,intPageSize);
String json = mapper.writeValueAsString(page);
resp.setContentType("application/json; charset=utf-8");
PrintWriter pw = resp.getWriter();
pw.write(json);
pw.close();
}
}
package com.lizicai.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.lizicai.bean.News;
import com.lizicai.service.NewsService;
import com.lizicai.service.impl.NewsServiceImpl;
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 java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
@WebServlet("/newsList2")
public class NewsServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String pageNum = req.getParameter("pageNum");
String pageSize = req.getParameter("pageSize");
System.out.println(pageNum+" "+pageSize+"----");
Integer intPageNum = Integer.parseInt(pageNum) ;
Integer intPageSize = Integer.parseInt(pageSize) ;
ObjectMapper mapper = new ObjectMapper();
NewsService newsService = new NewsServiceImpl();
Page page = newsService.pageQuery(intPageNum,intPageSize);
PageInfo<List<News>> pageInfo = new PageInfo<>(page);
String json = mapper.writeValueAsString(pageInfo);
resp.setContentType("application/json; charset=utf-8");
PrintWriter pw = resp.getWriter();
pw.write(json);
pw.close();
}
}
<script>
//1.定义发送请求标记
let send = true;
//2.定义当前页码和每页显示的条数
let pageNum = 1;
let pageSize = 10;
//3.定义滚动条距底部的距离
let bottom = 1
//4.设置页面加载事件
$(function (){
//5.为当前窗口绑定滚动条滚动事件
$(window).scroll(function (){
//6.获取必要信息,用于计算当前展示数据是否浏览完毕
//当前窗口的高度
let windowHeight = $(window).height() ;
//当前滚动条从上往下滚动的距离
let scrollTop = $(window).scrollTop();
//当前文档的高度
let docHeight = $(document).height() ;
//7.计算当前展示数据什么时候浏览完毕
//当 滚动条距底部的距离 + 当前滚动条滚动的距离 + 当前窗口的高度 >= 当前文档的高度
if((bottom + scrollTop + windowHeight) >= docHeight) {
//8.判断请求标记是否为true
if(send == true){
// 如果当前页大于10,则将加载动图隐藏并结束方法
//9.将请求标记置为false,当前异步操作完成前,不能重新发起请求
send = false;
//10.根据当前页和每页显示的条数来 请求查询分页数据
queryByPage(pageNum, pageSize);
//11.当前页码+1
pageNum++;
}
}
});
})
//请求查询分页数据的函数
function queryByPage(pageNum, pageSize){
//将加载动图显示
$(".loading").show();
//发起AJAX异步请求
$.ajax({
url:"newsList",
data:{"pageNum":pageNum,"pageSize":pageSize},
type:"POST",
dataType:"json",
success:function (data){
if(data.length == 0){
// 加载动图隐藏
$(".loading").hide();
$("#no").html("我也是有底线的")
return;
}
// 将数据进行显示
let titles = "";
for(let i=0;i<data.length;i++){
titles += "<li>\n" +
" <div class=\"title-box\">\n" +
" <a href=\"#\" class=\"link\">\n" +
data[i].title+
" <hr>\n" +
" </a>\n" +
" </div>\n" +
" </li>";
}
//追加到页面
$(".news_list").append(titles);
//将请求标记置为true
send = true;
}
})
}
</script>
<script>
// 1. 定义当前页码和每页显示的条数
let pageNum = 1;
let pageSize = 10;
// 2. 调用查询数据的方法
queryByPage(pageNum, pageSize)
// 3. 定义请求查询分布数据的函数, 发起AJAX异步请求, 将数据显示到页面
function queryByPage(pageNum, pageSize){
$.ajax({
url:"newsList2",
data:{"pageNum":pageNum,"pageSize":pageSize},
type:"POST",
dataType:"json",
success:function (pageInfo){
let titles = "";
for( let i=0;i<pageInfo.list.length;i++){
titles += "<li>\n" +
" <div class=\"title-box\">\n" +
" <a href=\"#\" class=\"link\">\n" +
pageInfo.list[i].title+
" <hr>\n" +
" </a>\n" +
" </div>\n" +
" </li>";
}
// 将数据显示到页面上
$(".news_list").html(titles);
// 4. 为分布按钮区域设置页数参数(总页数和当前页)
$("#light-pagination").pagination({
pages:pageInfo.pages,
currentPage: pageInfo.pageNum
});
// 5. 为分布按钮绑定单击事件, 完成上一页下一页
$(".page-link").click(function(){
// 获取点击按钮的文本内容
let page = $(this).html()
console.log(page)
// 如果点击的是Prev, 调用查询方法, 查询当前页的上一页数据
if( page == "Prev"){
queryByPage(pageInfo.pageNum-1, pageSize)
} else if(page == "Next"){
queryByPage(pageInfo.pageNum+1, pageSize)
} else{
queryByPage(page, pageSize)
}
})
}
})
}
</script>