数据交换和异步请求 - JSON& Ajax
JSON 介绍
1. JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
2. JSON 是轻量级的文本数据交换格式
3. JSON 独立于语言 [解读:即 java 、php、asp.net , go 等都可以使用 JSON]
4. JSON 具有自我描述性,更易理解, 一句话,非常的好用..
JSON 的定义格式
JSON 规则
1) 映射(元素/属性)用冒号 : 表示,"名称":值 , 注意名称是字符串,因此要用双引号引起来
2) 并列的数据之间用逗号 , 分隔。"名称 1":值,"名称 2":值
3) 映射的集合(对象)用大括号 {} 表示。{"名称 1":值,"名称 2":值}
4) 并列数据的集合(数组)用方括号 [] 表示。 [{"名称 1":值,"名称 2":值}, {"名称 1":值,"名称 2":值}]
5) 元素值类型:string, number, object, array, true, false, null
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>json 快速入门案例</title>
<script type="text/javascript">
window.onload = function () {
/*
1. myJson 就是一个json对象
2. 演示如何获取到json对象的各个属性/key
*/
var myJson = {
"key1": "大家好", // 字符串
"key2": 123, // Number
"key3": [1, "hello", 2.3], // 数组
"key4": {"age": 12, "name": "jack"}, //json对象
"key5": [ //json数组
{"k1": 10, "k2": "milan"},
{"k3": 30, "k4": "smith"},
]
};
//1. 取出key1
console.log("key1= ", myJson.key1);
//2. 取出key3
console.log("key3= ", myJson.key3);
// 可以对key3取出的值(Array), 遍历
for (var i = 0; i < myJson.key3.length; i++) {
console.log("第%i个元素的值= " , i, myJson.key3[i]);
}
//3. 取出key4
console.log("key4= " , myJson.key4 , " name= " , myJson.key4.name);
//4. 取出key5
console.log("key5= " , myJson.key5, " k4= ", myJson.key5[1].k4)
}
</script>
</head>
<body>
<h1>json 快速入门案例</h1>
</body>
</html>
JSON 对象和字符串对象转换
应用案例
1. JSON.stringify(json)功能: 将一个 json 对象转换成为 json 字符串 [简单说名字来源.] Serialize
2. JSON.parse( jsonString )功能: 将一个 json 字符串转换成为 json 对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON对象和字符串对象转换</title>
<script type="text/javascript">
window.onload = function () {
//解读JSON
//1.JSON 是一个js的内置对象(build-in),可以直接使用
// console.log("JSON=", JSON);
//演示如何将以json对象->string
var jsonPerson = {
"name": "jack",
"age": 20
}
console.log("jsonPerson=" , jsonPerson);
var strPerson = JSON.stringify(jsonPerson);
console.log("strPerson= ", strPerson, " strPerson类型= ", typeof strPerson);
//string->json
//注意要转成json对象的string 格式必须满足json格式
var strDog = "{\"name\":\"小黄狗\", \"age\":2}";
var jsonDog = JSON.parse(strDog);
console.log("jsonDog= ", jsonDog);
}
</script>
</head>
<body>
<h1>JSON对象和字符串对象转换</h1>
</body>
</html>
注意事项和细节
1、 JSON.springify( json对象) 会返回对应 string, 并不会影响原来json对象,演示
2、JSON.parse(string)函数会返回对应的 json 对象, 并不会影响原来 string
3、在定义 Json 对象时, 可以使用 ' ' 表示字符串,
比如 var json_person = {"name": "jack", "age": 100};
也可以写成 var json_person = {'name': 'jack', 'age': 100};
4、但是在把原生字符串转成 json 对象时, 必须使用 "", 否则会报错 比如:
var str_dog = "{'name':'小黄狗', 'age': 4}"; 转 json 就会报错
5、JSON.springify(json 对象) 返回的字符串, 都是 "" 表示的字符串, 所以在语法格式正确
的情况下, 是可以重新转成 json
代码演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>json和字符串转换的注意事项和细节</title>
<script type="text/javascript">
window.onload = function () {
var jsonPerson = {
"name": "jack",
"age": 20
}
//1. JSON.springify(json对象) 会返回对应string, 并不会影响原来json对象
// 可以这样理解 java基础 int n = 10; double n2 = (double)n;
var strPerson = JSON.stringify(jsonPerson);
console.log("jsonPerson=", jsonPerson);
//2. JSON.parse(string) 函数会返回对应的json对象, 并不会影响原来string
var strDog = "{\"name\":\"小黄狗\", \"age\":2}";
var jsonDog = JSON.parse(strDog);
console.log("strDog=", strDog, " 类型= ", typeof strDog);
//3. 在定义Json对象时, 可以使用 ' ' 表示字符串
// 前面的key 可以不用" " 或者 ' '
var jsonPerson2 = {
name: 'jack',
age: 20
}
console.log("jsonPerson2=", jsonPerson2);
//4. 但是在把原生字符串转成 json对象时, 必须使用 "", 否则会报错 比如
// 工作时,非常容易错
var strdog3 = "{\"name\":\"小黄狗~\", \"age\": 4}";
JSON.parse(strdog3);
//5. JSON.springify(json对象) 返回的字符串, 都是 "" 表示的字符串
var strPerson2 = JSON.stringify(jsonPerson2);
var parse = JSON.parse(strPerson2);
console.log("parse=", parse);
}
</script>
</head>
<body>
</body>
</html>
JSON 在 java 中使用
说明
1. java 中使用 json,需要引入到第 3 方的包 gson.jar
2. Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。
3. 可以对 JSON 字符串 和 Java 对象相互转换
JSON 在 Java 中应用场景
1. Javabean 对象和 json 字符串 的转换
2. List 对象和 json 字符串 的转换
3. map 对象和 json 字符串
应用场景示意图
应用实例
Book.java
public class Book {
private Integer id;
private String name;
public Book(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
JavaJson.java
TypeToken<List<Book>>() {}如果不知道这个意思请看这个的博客
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaJson {
public static void main(String[] args) {
//创建一个gson对象,做完一个工具对象使用
Gson gson = new Gson();
//演示javabean 和 json字符串的转换
Book book = new Book(100, "Java");
//1. 演示把javebean -> json字符串
String strBook = gson.toJson(book);
System.out.println("strBook=" + strBook);
//2. json字符串->javabean
//(1) strBook 就是 json字符串
//(2) Book.class 指定将 json字符串转成 Book对象
//(3) 底层是反射机制
Book book2 = gson.fromJson(strBook, Book.class);
System.out.println("book2=" + book2);
//3. 演示把list对象 -> json字符串
List<Book> bookList = new ArrayList<>();
bookList.add(new Book(200, "天龙八部"));
bookList.add(new Book(300, "三国演义"));
String strBookList = gson.toJson(bookList);
System.out.println("strBookList= " + strBookList);
//4. 演示把json字符串 -> list对象
Type type = new TypeToken<List<Book>>() {}.getType();
List<Book> bookList2 = gson.fromJson(strBookList, type);
System.out.println("bookList2= " + bookList2);
//5, 把map对象->json字符串
Map<String, Book> bookMap = new HashMap<>();
bookMap.put("k1", new Book(400, "射雕英雄传"));
bookMap.put("k2", new Book(500, "西游记"));
String strBookMap = gson.toJson(bookMap);
System.out.println("strBookMap=" + strBookMap);
//6. 把json字符串 -> map对象
Map<String, Book> bookMap2 = gson.fromJson(strBookMap,
new TypeToken<Map<String, Book>>() {
}.getType());
System.out.println("bookMap2=" + bookMap2);
}
}
Ajax 基本介绍
Ajax 是什么
1. AJAX 即"Asynchronous Javascript And XML"(异步 JavaScript 和 XML)
2. Ajax 是一种浏览器异步发起请求(指定发哪些数据),局部更新页面的技术
3. 传统的方式
Ajax 经典应用场景
1. 搜索引擎根据用户输入关键字,自动提示检索关键字
2. 动态加载数据,按需取得数据【树形菜单、联动菜单...】
3. 改善用户体验。【输入内容前提示、带进度条文件上传...】
4. 电子商务应用。 【购物车、邮件订阅...】
5. 访问第三方服务。【访问搜索服务、rss 阅读器】
6. 页面局部刷新
Ajax 原理示意图
传统的 WEB 应用
Ajax 原理示意图
JavaScript 原生 Ajax 请求
应用实例-验证用户名是否存在
1. 演示 javascript 发送原生 ajax 请求的案例
1) 在输入框输入用户名
2) 点击验证用户名, 使用 ajax 方式, 服务端验证该用户名是否已经占用了, 如果该用户已经占用, 以 json 格式返回该用户信息
3) 假定用户名为 king , 就不可用, 其它用户名可以=》 后面我们接入 DB[Mysql+JDBC]
4) 对页面进行局部刷新, 显示返回信息
程序框架图
数据库的思路分析图
User.java
/**
* User类就是一个javabean/pojo/entity/domain
*/
public class User {
private Integer id;
private String username;
private String pwd;
private String email;
//必须提供一个无参构造器, 是给我们的反射使用
public User() {
}
public User(Integer id, String username, String pwd, String email) {
this.id = id;
this.username = username;
this.pwd = pwd;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
CheckUserServlet.java
import com.google.gson.Gson;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CheckUserServlet extends HttpServlet {
//定义一个UserService属性
private UserService userService = new UserService();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//System.out.println("CheckUserServlet 被调用....");
//接收ajax提交的数据
String uname = request.getParameter("uname");
System.out.println("uname= " + uname);
response.setContentType("text/html;charset=utf-8");
//到DB查询
//如果有就返回user对象,否则,返回的是null
//User user = userService.getUserByName(uname);
//if (user != null) {//说明用户名存在..,返回该user的json格式数据字符串
// Gson gson = new Gson();
// String strUser = gson.toJson(user);
// response.getWriter().write(strUser);
// } else {
//response.getWriter().write("");
// }
//假定用户名为 king , 就不可用, 其它用户名可以
if("king".equals(uname)) {//不能使用king用户名
//后面这个信息,是从DB获取
User king = new User(100, "king", "666", "king@sohu.com");
//把 king 转成 json字符串
String strKing = new Gson().toJson(king);
//返回
response.getWriter().write(strKing);
} else {
//如果用户名可以用,返回""
response.getWriter().write("");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
<script type="text/javascript">
window.onload = function () { //页面加载后执行function
var checkButton = document.getElementById("checkButton");
//给checkButton绑定onclick
checkButton.onclick = function () {
//1. 创建XMLHttpRequest对象(!!!) [ajax引擎对象]
var xhr = new XMLHttpRequest();
// 获取用户填写的用户名
var uname = document.getElementById("uname").value;
//2. 准备发送指定数据 open, send
//解读
//(1)"GET" 请求方式可以 GET/POST
//(2)"/ajax/checkUserServlet?username=" + uname 就是 url
//(3)true , 表示异步发送
xhr.open("GET", "/ajax/checkUserServlet?uname=" + uname, true);
//说明,在send函数调用前,给XMLHttpRequest 绑定一个事件onreadystatechange
//该事件表示,可以去指定一个函数,当数据变化,会触发onreadystatechange
// 每当 xhr对象readyState 改变时,就会触发 onreadystatechange 事件
xhr.onreadystatechange = function () {
//如果请求已完成,且响应已就绪, 并且状态码是200
if (xhr.readyState == 4 && xhr.status == 200) {
//把返回的jon数据,显示在div
document.getElementById("div1").innerHTML = xhr.responseText;
//console.log("xhr=", xhr)
var responseText = xhr.responseText;
//console.log("返回的信息=" + responseText);
if (responseText != "") {
document.getElementById("myres").value = "用户名不可用"
} else {
document.getElementById("myres").value = "用户名可用"
}
}
}
//3. 真正的发送ajax请求[http请求]
// 说明如果你POST 请求,再send("发送的数据")
xhr.send();
}
}
</script>
</head>
<body>
<h1>用户注册~</h1>
<form action="/ajax/checkUserServlet" method="post">
用户名字:<input type="text" name="username" id="uname">
<input type="button" id="checkButton" value="验证用户名">
<input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>
用户密码:<input type="password" name="password"><br/><br/>
电子邮件:<input type="text" name="email"><br/><br/>
<input type="submit" value="用户注册">
</form>
<h1>返回的json数据</h1>
<div id="div1"></div>
</body>
</html>
sql
CREATE DATABASE ajaxdb
USE ajaxdb
-- 创建表
CREATE TABLE `user` (
id INT PRIMARY KEY,
username VARCHAR(32) NOT NULL DEFAULT '',
pwd CHAR(32) NOT NULL DEFAULT '',
email VARCHAR(32) NOT NULL DEFAULT '')CHARSET utf8 ENGINE INNODB
-- 测试数据
INSERT INTO `user` VALUES(100, 'king', MD5('123'), 'king@qq.com');
INSERT INTO `user` VALUES(200, 'wyxedu', MD5('666'), '123@qq.com');
SELECT * FROM `user`
原生 Ajax 请求问题分析
1. 编写原生的 Ajax 要写很多的代码,还要考虑浏览器兼容问题,使用不方便。
2. 在实际工作中,一般使用 JavaScript 的库(比如 Jquery) 发送 Ajax 请求,从而解决这个问题
在线文档:jQuery AJAX get() 和 post() 方法
$.ajax 方法
1. $.ajax 常用参数
● url: 请求的地址
● type : 请求的方式 get 或 post
● data : 发送到服务器的数据。将自动转换为请求字符串格式
● success: 成功的回调函数
● error: 失败后的回调函数
● dataType: 返回的数据类型 常用 json 或 text
$.get 请求和$.post 请求
1. $.get 和 $.post常用参数
url: 请求的 URL 地址
data: 请求发送到服务器的数据
success: 成功时回调函数
type: 返回内容格式,xml, html, script, json, text
2. 说明:$.get 和 $.post 底层还是使用$.ajax()方法来实现异步请求
$.getJSON
1. $.getJSON 常用参数
url: 请求发送的哪个 URL
data: 请求发送到服务器的数据
success: 请求成功时运行的函数
2. 说明:$.getJSON 底层使用$.ajax()方法来实现异步请求
代码实战
1) 在输入框输入用户名
2) 点击验证用户名, 服务端验证该用户名是否已经占用了, 如果该用户已经占用, 以 json格式返回该用户信息
3)链接数据库验证表前面有
4) 对页面进行局部刷新, 显示返回信息
login2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
<!-- 引入jquery-->
<script type="text/javascript" src="./script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
$(function () {
//绑定事件
$("#btn1").click(function () {
//发出ajax
/**
* 解读
* 1. 指定参数时,需要在{}
* 2. 给参数时,前面需要指定参数名
* 3. dataType: "json" 要求服务器返回的数据格式是json
*/
// $.ajax({
// url: "/ajax/checkUserServlet2",
// type: "POST",
// data: { //这里我们直接给json, 为啥我要传日期, 为了浏览器缓存
// username: $("#uname").val(),
// date: new Date()
// },
// error: function () { //失败后的回调函数
// console.log("失败~")
// },
// success: function (data, status, xhr) {
// console.log("成功");
// console.log("data=", data);
// console.log("status=", status);
// console.log("xhr=", xhr);
// //data是json对象-> 显示转成json的字符串
// $("#div1").html(JSON.stringify(data));
// //对返回的结果进行处理
// if ("" == data.username) {
// $("#myres").val("该用户名可用");
// } else {
// $("#myres").val("该用户名不可用");
// }
// },
// dataType: "json"
// })
//说明
//1.$.get() 默认是get请求,不需要指定 请求方式
//2.不需要指定参数名
//3.填写的实参,是顺序 url, data, success回调函数, 返回的数据格式
//讲解.get() 使用
// $.get(
// "/ajax/checkUserServlet2",
// {
// username: $("#uname").val(),
// date: new Date()
// },
// function (data, status, xhr) {
// console.log("$.get() 成功");
// console.log("data=", data);
// console.log("status=", status);
// console.log("xhr=", xhr);
// //data是json对象-> 显示转成json的字符串
// $("#div1").html(JSON.stringify(data));
// //对返回的结果进行处理
// if ("" == data.username) {
// $("#myres").val("该用户名可用");
// } else {
// $("#myres").val("该用户名不可用");
// }
// },
// "json"
// )
//说明$.post() 和 $.get() 的方式一样
//只是这时,是按照post方式发送ajax请求
// $.post(
// "/ajax/checkUserServlet2",
// {
// username: $("#uname").val(),
// date: new Date()
// },
// function (data, status, xhr) {
// console.log("$.post() 成功");
// console.log("data=", data);
// console.log("status=", status);
// console.log("xhr=", xhr);
// //data是json对象-> 显示转成json的字符串
// $("#div1").html(JSON.stringify(data));
// //对返回的结果进行处理
// if ("" == data.username) {
// $("#myres").val("该用户名可用");
// } else {
// $("#myres").val("该用户名不可用");
// }
// },
// "json"
// )
//说明
//1. 如果你通过jquery发出的ajax请求是get 并且 返回的数据格式是json
//2. 可以直接使用getJSON() 函数,就很简洁
$.getJSON(
"/ajax/checkUserServlet2",
{
username: $("#uname").val(),
date: new Date()
},
function (data, status, xhr) {//成功后的回调函数
console.log("$.getJSON 成功");
console.log("data=", data);
console.log("status=", status);
console.log("xhr=", xhr);
//data是json对象-> 显示转成json的字符串
$("#div1").html(JSON.stringify(data));
//对返回的结果进行处理
if ("" == data.username) {
$("#myres").val("该用户名可用");
} else {
$("#myres").val("该用户名不可用");
}
}
)
})
})
</script>
</head>
<body>
<h1>用户注册-Jquery+Ajax</h1>
<form action="/ajax/checkUserServlet2" method="post">
用户名字:<input type="text" name="username" id="uname">
<input type="button" id="btn1" value="验证用户名">
<input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>
用户密码:<input type="password" name="password"><br/><br/>
电子邮件:<input type="text" name="email"><br/><br/>
<input type="submit" id="submit" value="用户注册">
</form>
<h1>返回的json数据</h1>
<div id="div1"></div>
</body>
</html>
CheckUserServlet2
import com.google.gson.Gson;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CheckUserServlet2 extends HttpServlet {
private UserService userService=new UserService();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收jquery发送的ajax数据
String username = request.getParameter("username");
//查询有没有这个人
User userByName = userService.getUserByName(username);
response.setContentType("text/json;charset=utf-8");
Gson gson = new Gson();
if (null!=userByName) {
response.getWriter().write(gson.toJson(userByName));
} else {
//返回一个不存在的User=>是有设计
User user = new User(-1, "", "", "");
response.getWriter().write(gson.toJson(user));
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}