AJAX:【异步】的JavaScript和XML,不是新技术,是多个技术的综合,用于快速创建动态网页的技术。
像一般的网页需要更新内容,必须重新加载整个页面,而AJAX通过与浏览器进行少量的数据交换,就可以实现异步更新,对网页部分内容进行【局部更新】
1、原生的JavaScript实现AJAX,了解即可,有点繁琐
1)核心对象:XMLHttpRequest
用于在后台与服务器交换数据,在不重新加载整个网页的情况下,对网页的部分进行更新
2)打开链接:open(method,url,async)
method:请求的类型GET或POST
url:请求资源的路径
asyn:true为异步,false为同步
3)发送请求:send(String params)
params:请求的参数(POST专用)
4)处理响应:onreadystatechange
readyState:0-请求未初始化,1-服务器连接已建立,2-请求已接受,3-请求处理中,4-请求已完成,且响应已就绪
status:200-响应已全部OK
5)获得响应数据形式
responseText:获得字符串形式的响应数据
responseXML:获得XML形式的响应数据
登录页面
<!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>
//1、为姓名绑定失去焦点事件
document.getElementById("username").onblur = function () {
//2、创建XMLHttpRequest核心对象(可以完成AJAX请求和响应的操作)
let xmlHttp = new XMLHttpRequest();
//3、打开链接
let username = document.getElementById("username").value;
xmlHttp.open("GET","userServlet?username="+username,true);//true表示异步
//xmlHttp.open("GET","userServlet?username="+username,false);//false表示同步,不可以在服务器处理请求时做其他事
//4、发送请求
xmlHttp.send();
//5、处理响应
xmlHttp.onreadystatechange = function () {
//判断请求和响应是否成功
if(xmlHttp.readyState == 4 && xmlHttp.status ==200){//请求和响应成功
//将响应的数据显示到span标签中
document.getElementById("uSpan").innerHTML = xmlHttp.responseText;
}
}
}
</script>
</html>
请求资源
package com.lcl01;
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;
@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");
//模拟服务器处理请求需要五秒钟,在此期间,看看异步同步的差别
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//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);
}
}
2、JQuery的GET方式实现AJAX
核心语法:$.get(url,[data],[callback],[type]);
[]:表示可选的参数,可有可无
url:请求的资源路径
data:发送给服务器端的请求参数,格式可以是key=value,也可以是js对象
callback:当请求成功后的回调函数,可以在函数中编写逻辑代码,也就是对页面的处理功能
type:预期的返回数据的类型,取值可以是xml,html,js,text等
请求资源和上面相同,下面只给出注册页面
<!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.3.1.min.js"></script>
<script>
//1、为姓名绑定失去焦点事件
$("#username").blur(function () {
//获取客户输入的用户名
let username = $("#username").val();
//2、JQuery的GET方式实现AJAX
$.get(
//请求的资源路径
"userServlet",
//请求参数
"username="+username,
//回调函数
function (data) {
//data是服务器响应回来的数据
//将响应的数据响应到span标签中
$("#uSpan").html(data);
},
//响应数据形式
"text"
);
});
</script>
</html>
3、JQuery的POST方式实现AJAX
核心语法:$.post(url,[data],[callback],[type]);
其实和上面的GET方法也就语法那个get变成post而言,没啥区别
4、JQuery的通用方式实现AJAX
核心语法:$.ajax({name:value,name:value…})
url:请求的资源路径
asyn:true为异步(默认),false为同步
data:发送给服务器端的请求参数,格式可以是key=value,也可以是js对象
type:请求方式,POST或GET(默认为GET)
dataType:预期的返回数据的类型,取值可以是xml,html,js,text等
success:请求成功时调用的回调函数
error:请求失败时调用的回调函数
请求资源和上面相同,下面只给出注册页面
<!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.3.1.min.js"></script>
<script>
//1、为姓名绑定失去焦点事件
$("#username").blur(function () {
//获取客户输入的用户名
let username = $("#username").val();
//2、JQuery的通用方式实现AJAX
$.ajax({
//请求的资源路径
url:"userServlet",
//是否异步,可省略,默认为异步
async:true,
//请求参数
data:"username="+username,
//请求方式,可省略,默认为GET
type:"GET",
//返回响应数据类型
dataType:"text",
//请求成功后调用的回调函数
success:function (data) {
//将响应的数据显示到span标签上
$("#uSpan").html(data);
},
//请求失败后调用的回调函数
error:function () {
alert("操作失败");
}
});
});
</script>
</html>
JSON的处理
JSON转换工具:Jackson,三个jar包
步骤:导入jar包,创建核心对象,调用方法完成转换
第二个类,是在使用集合时,集合里面有自己定义的类时使用
JSON转换工具的使用
package com.lcl02;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
public class ObjectMapperTest {
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 user1 = new User("张三", 23);
String json = mapper.writeValueAsString(user1);
System.out.println("json字符串:"+json);
//json字符串转user对象
User user2 = mapper.readValue(json, User.class);
System.out.println("java对象:"+user2);
}
/*
2、map<String,String>转json,json转map<String,String>
json字符串:{"姓名":"张三","性别":"男"}
map对象:{姓名=张三,性别=男}
*/
@Test
public void test02() throws Exception {
HashMap<String, String> map = new HashMap<>();
map.put("姓名","张三");
map.put("性别","男");
//map<String,String>转json
String json = mapper.writeValueAsString(map);
System.out.println("json字符串:"+json);
//json转map<String,String>
HashMap<String, String> map1 = mapper.readValue(json, HashMap.class);
System.out.println("java对象:"+map1);
}
/*
3、map<String,User>转json,json转map<String,User>
json字符串:{"黑马二班":{"name":"李四","age":24},"黑马一班":{"name":"张三","age":23}}
map对象:{黑马二班=User{name='李四', age=24}, 黑马一班=User{name='张三', age=23}}
*/
@Test
public void test03() throws Exception {
User user1 = new User("张三", 23);
User user2 = new User("李四", 24);
HashMap<String, User> map = new HashMap<>();
map.put("黑马一班",user1);
map.put("黑马二班",user2);
//map<String,User>转json
String json = mapper.writeValueAsString(map);
System.out.println("json字符串:"+json);
//jjson转map<String,User>
//HashMap中有自己定义的类,需要用TypeReference
HashMap<String, User> map1 = mapper.readValue(json, new TypeReference<HashMap<String,User>>(){});//第二个参数用匿名内部类
System.out.println("java对象:"+map1);
}
/*
4、List<String>转json,json转List<String>
json字符串:["张三","李四"]
map对象:[张三,李四]
*/
@Test
public void test04() throws Exception {
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
//List<String>转json
String json = mapper.writeValueAsString(list);
System.out.println("json字符串:"+json);
//json转List<String>
ArrayList<String> list1 = mapper.readValue(json, ArrayList.class);
System.out.println("java对象:"+list1);
}
/*
5、List<User>转json,json转List<User>
json字符串:[{"name":"张三","age":23},{"name":"李四","age":24}]
map对象:[User{name='张三', age=23}, User{name='李四', age=24}]
*/
@Test
public void test05() throws Exception {
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",23));
list.add(new User("李四",24));
//List<String>转json
String json = mapper.writeValueAsString(list);
System.out.println("json字符串:"+json);
//json转List<String>
ArrayList<User> list1 = mapper.readValue(json, new TypeReference<ArrayList<User>>(){});
System.out.println("java对象:"+list1);
}
}
综合案例:搜索联想
(其中有个错误,一直出不来结果,java.io.IOException: Could not find resource MyBatisConfig.xml,其实就是需要把三个配置文件放到src目录下才行,不然找不到)
具体思路:
查询页面负责给出一个页面,让用户输入需要搜索的内容,此处是姓氏"张",然后用AJAX请求资源,将"张"作为参数数据传递给服务端。服务端中的控制层负责接收请求参数,调用业务层,将参数传递给业务层,业务层负责连接数据库,并调用数据测,将参数数据传给数据层来数据库查询。然后一层层返回查到的数据到控制层,控制层先json化数据,再响应给查询页面,查询页面再将响应的数据显示在页面
实体对象,三个配置文件也不给了
查询页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户搜索</title>
<style type="text/css">
.content{
width: 643px;
margin: 100px auto;
text-align: center;
}
input[type='text']{
width: 530px;
height: 40px;
font-size: 14px;
}
input[type='button']{
width: 100px;
height: 46px;
background: #38f;
border: 0;
color: #fff;
font-size: 15px;
}
.show{
position: absolute;
width: 535px;
height: 100px;
border: 1px solid #999;
border-top: 0;
display: none;
}
</style>
</head>
<body>
<form autocomplete="off">
<div class="content">
<img src="img/logo.jpg">
<br><br>
<input type="text" id="username">
<input type="button" value="搜索一下">
<!--用于显示联想数据-->
<div id="show" class="show"></div>
</div>
</form>
</body>
<script src="js/jquery-3.3.1.min.js"></script>
<script>
$("#username").mousedown(function () {
let username = $("#username").val();
if(username == null || username == ""){
$("#show").hide();//元素隐藏
return;
}
$.ajax({
url:"userServlet",
data:{"username":username},
type:"POST",
dataType:"json",
success:function (data) {
let names = "";
for(let i = 0;i < data.length;i++){
//data[i]是一个个用户,然后取名字,变成一个个div
names += "<div>"+data[i].name+"</div>";
}
$("#show").html(names);
$("#show").show();//元素显示
},
error:function () {
alert("操作错误");
}
});
});
</script>
</html>
控制层:
package com.lcl.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lcl.bean.User;
import com.lcl.service.UserService;
import com.lcl.service.impl.UserServiceImpl;
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.util.List;
@WebServlet("/userServlet")
public class UserServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求和响应编码,以防乱码
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
//获取请求参数
String username = req.getParameter("username");
System.out.println(username);
//调用业务层模糊查询的方法获得数据
UserService userService = new UserServiceImpl();
List<User> users = userService.selectLike(username);
System.out.println(users);
//将数据转为json格式
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(users);
System.out.println(json);
//响应给客户json数据
resp.getWriter().write(json);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
业务逻辑层:接口就不给了
package com.lcl.service.impl;
import com.lcl.bean.User;
import com.lcl.mapper.UserMapper;
import com.lcl.service.UserService;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class UserServiceImpl implements UserService {
@Override
public List<User> selectLike(String username) {
List<User> users = null;
SqlSession sqlSession = null;
InputStream is = null;
try{
//1、加载核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2、获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3、通过SqlSession工厂对象获取SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
//4、获取UserMapper接口的实现类对象,接口代理
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//5、通过实现类对象调用方法,接收结果
users = mapper.selectLike(username);
}catch (Exception e){
e.printStackTrace();
}finally {
//6、释放资源
if(sqlSession!=null){
sqlSession.close();
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return users;
}
}
数据层:
package com.lcl.mapper;
import com.lcl.bean.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
/*模糊查询*/
@Select("SELECT * FROM user WHERE name LIKE CONCAT('%',#{username},'%') ORDER BY search_count DESC LIMIT 0,4")
public abstract List<User> selectLike(String username);
}
综合案例:分页
瀑布流无限加载数据分页
懒得看和做了