ajax介绍和快速入门
1.Ajax概念
AJAX(Asynchronous JavaScript And XML):异步的 JavaScript 和 XML。AJAX 通过浏览器与服务器进行少量数据交换,就可以使网页实现异步更新。也就是在不重新加载整个页 面的情况下,对网页的部分内容进行局部更新。
2.原生js实现ajax
后端代码实现
@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");
//获取请求参数
String username = req.getParameter("username");
//判断
if ("zhangsan".equals(username)){
resp.getWriter().write("<font color='red'>该用户已经注册</font>");
}else {
resp.getWriter().write("<font color='blue'>用户可用</font>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
前端代码实现
<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>
//1.为姓名绑定失去焦点的事件
document.getElementById("username").onblur = function () {
//2.创建XMLHttpRequest核心对象
let xmlHttp = new XMLHttpRequest();
//3.打开链接
let username = document.getElementById("username").value;
xmlHttp.open("GET","userServlet?username="+username,true);
//4.发送请求
xmlHttp.send();
//5.处理响应
xmlHttp.onreadystatechange = function () {
//判断请求和响应是否成功
if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
//将响应的数据显示到span标签
document.getElementById("uSpan").innerHTML = xmlHttp.responseText;
}
}
}
</script>
原生js实现ajax步骤详解
-1 为姓名绑定失去焦点事件
-2 创建XMLHttpRequest核心对象
XMLHttpRequest:用户后台与服务器交换数据,可以在不重新加载整个网页的情况下,对网页的某部分进行更新
-3 打开链接open(method,url,async)
method:请求的类型GET或者POST
url:请求资源的路径
async:true(异步)或false(同步)
-4 发送请求send(String params)
params:请求的参数(POSt专用)
-5 处理响应onreadyStatechange
readyState:0-请求未初始化,1-服务器连接已建立,3-请求处理中,4-请求已完成,且响应已就绪
status:200-响应已全部OK
3.jquery的通用方法实现ajax(重点)
3.1 $.ajax()语法
$.ajax({
url:"",//请求路径
async:,/异步请求,true-是,false-否(默认true)
data:"", //请求参数,写法1:“name=value&name=value...”,写法2:{name:value,name:value}
type:"", //请求方式,常用的是get和post(默认get方式)
dataType:"", //响应的数据格式
success:function(msg){ //响应成功要执行的函数,msg是响应回来的数据
//处理msg数据
},
error:function(){
}
});
3.2 演示-后台UserServlet代码
@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");
//获取请求参数
String username = req.getParameter("username");
//判断
if ("zhangsan".equals(username)){
resp.getWriter().write("<font color='red'>该用户已经注册</font>");
}else {
resp.getWriter().write("<font color='blue'>用户可用</font>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.3 演示-前端页面发送ajax请求
<script src="js/jquery-3.3.1.min.js"></script>
<body>
<form action="#" autocomplete="off">
姓名:<input type="text" id="username">
<span id="uSpan"></span>
<br>
密码:<input type="password" id="password">
<br>
<input type="submit" value="注册">
</form>
<script>
//1.为用户绑定失去焦点事件
$("#username").blur(function () {
//获取表单填写的用户名
let username = $("#username").val();
//2.用jq的方式实现ajax
$.ajax({
//请求路径
url:"userServlet",
//是否异步
async:true,
//请求参数
data:"username="+username,
//请求方式
type:"get",
//数据形式
dataType:"text",
//请求成功后调用回调函数
success:function (data) {
//将响应的数据显示到span标签
$("#uSpan").html(data);
},
error:function () {
alert("操作有误");
}
});
});
</script>
</body>
4.jquery的get方法实现ajax
4.1 $.get()语法
语法:$.get(url, [data], [callback], [type])
参数:
url:请求路径
data:请求参数,写法1:“name=value&name=value...”,写法2:{name:value,name:value}。
callback:响应成功要执行的函数。
type:响应的数据格式,xml, html, script, json, text, _default。
4.2 演示
<script>
//1.为用户绑定失去焦点事件
$("username").blur(function () {
//获取表单填写的用户名
let username = $("#username").val();
//2.用jq的get方式实现ajax
$.get(
//请求的资源路径
"userServlet",
//请求的参数
"username="+username,
//回调函数
function (data) {
//将响应的数据显示到span标签
$("uSpan").html(data);
},
//响应数据形式
"text"
);
})
</script>
5.jquery的post方法实现ajax
5.1 $.post()语法
语法:$.get(url, [data], [callback], [type])
参数:
url:请求路径
data:请求参数,写法1:“name=value&name=value...”,写法2:{name:value,name:value}。
callback:响应成功要执行的函数。
type:响应的数据格式,xml, html, script, json, text, _default。
5.2 演示
<script>
//1.为用户绑定失去焦点事件
$("#username").blur(function () {
//获取表单填写的用户名
let username = $("#username").val();
//2.用jq的方式实现ajax
$.post(
//请求的资源路径
"userServlet",
//请求的参数
"username=" + username,
//回调函数
function (data) {
//将响应的数据显示到span标签
$("#uSpan").html(data);
},
//响应数据形式
"text"
);
});
</script>
json处理(重点)
1 json回顾介绍
-
json是一种前后端数据交换的格式,这种格式的数据传输快,解析方便,所以被广泛使用。
-
json格式分类
格式1:对象格式
{name:value,name:value,...} //value可以是任意数据类型,如果value是对象,那么就是对象嵌套对象
格式2:数组格式
[ele1,ele2,...] // ele1,ele2 可以是任意数据类型
格式3:混合类型,指的是对象嵌套数组,数组嵌套对象
{name:value,name:[],...}、 [{name:value,name:value,..},{},{},...]
- 常用方法
成员方法 | 说明 |
---|---|
stringify(对象) | 将指定对象转换为json格式的字符串 |
parse(字符串) | 将指定json格式字符串解析成对象 |
2 json转换工具介绍
2.1 JSON转换工具
-
可以将java对象或者集合转换成json格式的字符串,也可以将json格式的字符串转换成java对象
-
Jackson:开源的JSON转换工具,SpringMVC转换默认使用Jackson
- 导入jar包
- 创建核心对象
- 调用方法完成转换
2.2 jackson的相关API介绍
作用:可以将Java对象转换成json字符串,也可以将json字符串解析成Java对象,我们的重心“将Java对象转换成json字符串”。
- jackson涉及到的类
- ObectMapper类涉及到的方法
- 补充方法
- 自定义的对象,json转java对象,需要new TypeReference<>(){}
new TypeReference<List<User>>() {}
TypeReference是一个抽象类,没有子类,不能直接new对象,可以使用匿名内部类创建对象。
TypeReference的泛型List<User>表示告诉jackson要将json转换的数据类型是List<User>
- 不是自定义的对象,写他的字节码对象
List list1 = mapper.readValue(json, List.class);
3 json转换练习
- jackson使用步骤
【第一步】:导入jackson相关jar包,有三个
【第二步】:创建ObjectMapper核心对象
【第三步】:调用ObjectMapper的方法进行转换
Java对象----->json字符串:调用writerValueAsString()或者WriterValue()
json字符串----->Java对象:调用readValue();
- 代码演示
public class ObjectMapperTest {
//创建ObjectMapper核心对象
private ObjectMapper mapper = new ObjectMapper();
/*
1.User对象转json, json转User对象
json字符串 = {"name":"张三","age":23}
user对象 = User{name='张三', age=23}
*/
@Test
public void test01() throws Exception{
//User对象转json
User u1 = new User("张三", 23);
String json = mapper.writeValueAsString(u1);
System.out.println("json字符串:"+json);
//json转User对象
User u2 = mapper.readValue(json, User.class);
System.out.println("java对象:"+u2);
}
/*
2.map<String,String>转json, json转map<String,String>
json字符串 = {"姓名":"张三","性别":"男"}
map对象 = {姓名=张三, 性别=男}
*/
@Test
public void test02() throws Exception{
//map<String,String>转json
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("姓名","张三");
hashMap.put("性别","男");
String json = mapper.writeValueAsString(hashMap);
System.out.println("json字符串:"+json);
//json转map<String,String>
HashMap map = mapper.readValue(json, HashMap.class);
System.out.println("java对象:"+map);
}
/*
3.map<String,User>转json, json转map<String,User>
json字符串 = {"黑马一班":{"name":"张三","age":23},"黑马二班":{"name":"李四","age":24}}
map对象 = {黑马一班=User{name='张三', age=23}, 黑马二班=User{name='李四', age=24}}
*/
@Test
public void test03() throws Exception{
//map<String,User>转json
HashMap<String, User> hashMap = new HashMap<>();
hashMap.put("黑马一班",new User("张三",23));
hashMap.put("黑马二班",new User("李四",24));
String json = mapper.writeValueAsString(hashMap);
System.out.println("json字符串:"+json);
//json转map<String,User>
HashMap<String, User> map = mapper.readValue(json, new TypeReference<HashMap<String, User>>(){});
System.out.println("java对象:"+map);
}
/*
4.List<String>转json, json转 List<String>
json字符串 = ["张三","李四"]
list对象 = [张三, 李四]
*/
@Test
public void test04() throws Exception{
//List<String>转json
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
String json = mapper.writeValueAsString(list);
System.out.println("json字符串:"+json);
//json转 List<String>
List list1 = mapper.readValue(json, List.class);
System.out.println("java对象:"+list1);
}
/*
5.List<User>转json, json转List<User>
json字符串 = [{"name":"张三","age":23},{"name":"李四","age":24}]
list对象 = [User{name='张三', age=23}, User{name='李四', age=24}]
*/
@Test
public void test05() throws Exception{
//List<User>转json
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",23));
list.add(new User("李四",24));
String json = mapper.writeValueAsString(list);
System.out.println("json字符串:"+json);
//json转List<User>
ArrayList<User> list1 = mapper.readValue(json, new TypeReference<ArrayList<User>>() {});
System.out.println("java对象:"+list1);
}
}
注意
- 自定义的对象,json转java对象,需要new TypeReference<>(){}
new TypeReference<List<User>>() {}
TypeReference是一个抽象类,没有子类,不能直接new对象,可以使用匿名内部类创建对象。
TypeReference的泛型List<User>表示告诉jackson要将json转换的数据类型是List<User>
- 不是自定义的对象,写他的字节码对象
List list1 = mapper.readValue(json, List.class);
综合案例-搜索提示(重要)
使用异步前后端 交互 流程
1 案例展示
2 功能分析
3 代码实现
3.1 后台代码实现
- UserServlet代码
@WebServlet("/userServlet")
public class UserServlet extends HttpServlet {
private UserService userService = new UserServiceImpl();
//创建ObjectMapper核心对象
private ObjectMapper mapper = new ObjectMapper();
@Override
protected void doPost(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.调用业务层的模糊查询方法得到数据
List<User> users = userService.selectLike(username);
//3.将数据转成json,响应到客户端
String json = mapper.writeValueAsString(users);
resp.getWriter().write(json);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
}
- UserServiceImpl代码
public class UserServiceImpl implements UserService {
@Override
public List<User> findByUsername(String username) {
SqlSession sqlSession = null;
List<User> list = null;
try {
//1 加载资源
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2 获取SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//3 获取Sqlsession对象
sqlSession = factory.openSession(true);
//4 获取代理对象,执行操作
UserDao userDao = sqlSession.getMapper(UserDao.class);
//"select * from user where name like #{username} order by search_count desc limit 0,4"
//list = userDao.findByUsername("%"+username+"%"); //ok
list = userDao.findByUsername(username);
} catch (IOException e) {
e.printStackTrace();
} finally {
//5 返回结果,释放资源
if(sqlSession!=null){
sqlSession.close();
}
}
return list;
}
}
- UserDao代码
public interface UserDao {
@Select("select * from user where name like concat('%',#{username},'%') order by search_count desc limit 0,4")
public List<User> findByUsername(String username);
}
3.2 前台代码实现
<script>
//1.为用户名输入框绑定鼠标点击事件
$("#username").mousedown(function () {
//2.获取输入的用户名数据
let username = $("#username").val();
//3.判断用户名是否为空
if (username==null || username == ""){
//4.如果为空,则将联想提示框隐藏
$("#show").hide();
return;
}
//5.如果不为空,则发送ajax请求,并将响应的数据显示到联想框
$.ajax({
//请求的资源路径
url:"userServlet",
//请求参数
data:{username:username},
//请求方式
type:"POST",
//响应的数据格式
dataType:"json",
//请求成功后的回调函数
success:function (data) {
//将放回的数据显示到show的div中
let names = "";
for (let i = 0; i < data.length; i++) {
names += "<div>"+data[i].name+"</div>";
}
$("#show").html(names).show();
}
});
});
</script>
综合案例-分页查询-了解
1 效果展示
- 分页效果1:下方有加载动画
- 分析效果2:下方带有分页条
- 案例分析
2 后台的分页知识点回顾【重点
【第一步】:导入开发jar包:jsqlparser-3.1.jar,pagehelper-5.1.10.jar
【第二步】:在mybatisConfig.xml核心配置文件中配置分页助手
<!--集成分页助手插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor" />
</plugins>
【第三步】:在执行查询所有之前设置开始查询的页数和每页查询的条数
//5.封装Page对象 start:当前页码 pageSize:每页显示的条数
PageHelper.startPage(start,pageSize);
//6.调用实现类对象的查询全部方法,此时底层执行的就是MySQL的limit分页查询语句
List<News> list=mapper.selectAll();
【第四步】:在查询所有之后,封装分页信息
//6.调用实现类对象的查询全部方法,此时底层执行的就是MySQL的limit分页查询语句
List<News> list=mapper.selectAll();
//7.封装分页数据
info=new PageInfo<>(list);
3 滑动分页前端代码【了解】
//1.定义发送请求标记
let send = true;
//2.定义当前页码和每页显示的条数
let start = 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) {
//9.将请求标记置为false,当前异步操作完成前,不能重新发起请求。
send = false;
//10.根据当前页和每页显示的条数来 请求查询分页数据
queryByPage(start,pageSize);
//11.当前页码+1
start++;
}
}
});
});
//定义查询分页数据的函数
function queryByPage(start,pageSize){
//加载动图显示
$(".loading").show();
//发起AJAX请求
$.ajax({
//请求的资源路径
url:"newsServlet",
//请求的参数
data:{"start":start,"pageSize":pageSize},
//请求的方式
type:"POST",
//响应数据形式
dataType:"json",
//请求成功后的回调函数
success:function (data) {
if(data.length == 0) {
$(".loading").hide();
$("#no").html("我也是有底线的...");
return;
}
//加载动图隐藏
$(".loading").hide();
//将数据显示
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;
}
});
}
4 带分页条前端代码
//pageQuery方法分页查询
function pageQuery(currPage,pageSize){
$.ajax({
url:"newsServlet",
data:{currentPage:currPage,pageSize:pageSize},
type:"get",
dataType:"json",
success:function (info) { //info就是pageInfo
//展示新闻条目(新闻数据)------------
let lis=``;
for (let news of info.list) {
lis+=`<li>
<div class="title-box">
<a href="#" class="link">
${news.title}
<hr>
</a>
</div>
</li>`;
}
$(".news_list").html(lis);
//展示分页条信息--------------------
$(".pagination").pagination({
css: 'css-5',
pageSizeOpt: [
{'value': 5, 'text': '5条/页', 'selected': true},
{'value': 10, 'text': '10条/页'},
{'value': 15, 'text': '15条/页'},
{'value': 20, 'text': '20条/页'}
],
showPageNum: 8, //显示几个页码
firstPage: '首页',
previousPage: '上一页',
nextPage: '下一页',
lastPage: '尾页',
skip: '跳至',
confirm: '确认',
refresh: '刷新',
totalPageText: '共{}页',
isShowFL: true,
isShowPageSizeOpt: true,
isShowSkip: true,
isShowRefresh: true,
isShowTotalPage: true,
isResetPage: false,
totalPage: info.pages,
callBack: function (currPage, pageSize) {
console.log('currPage:' + currPage + ' pageSize:' + pageSize);
//调用pageQuery方法
pageQuery(currPage,pageSize);
}
});
}
});
}
//当页面加载完成之后向服务器发送请求,获取第一页数据
$(function () {
pageQuery(1,5);
})
page数据
[{"id":21,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”21"},{"id":22,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”22"},{"id":23,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”23"},{"id":24,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”24"},{"id":25,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”25"},{"id":26,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”26"},{"id":27,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”27"},{"id":28,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”28"},{"id":29,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”29"},{"id":30,"title":"奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实”30"}]
pageInfo数据
PageInfo{pageNum=4, pageSize=10, size=10, startRow=31, endRow=40, total=100, pages=10, list=Page{count=true, pageNum=4, pageSize=10, startRow=30, endRow=40, total=100, pages=10, reasonable=false, pageSizeZero=false}[com.itheima.bean.News@2ba8b0fe, com.itheima.bean.News@3f653868, com.itheima.bean.News@2632e0a6, com.itheima.bean.News@67a6bec4, com.itheima.bean.News@967cd8e, com.itheima.bean.News@1fd712b2, com.itheima.bean.News@2e51f63e, com.itheima.bean.News@7cd32dae, com.itheima.bean.News@4bef9407, com.itheima.bean.News@6c0a5d4a], prePage=3, nextPage=5, isFirstPage=false, isLastPage=false, hasPreviousPage=true, hasNextPage=true, navigatePages=8, navigateFirstPage=1, navigateLastPage=8, navigatepageNums=[1, 2, 3, 4, 5, 6, 7, 8]}