一、 ajax概述
1.1 什么是ajax
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。
1.2 AJAX的应用场景
ajax的应用场景很多,常见的应用场景如下:
检查用户名是否已经被注册
很多站点的注册页面都具备自动检测用户名是否存在的友好提示,该功能整体页面并没有刷新,但仍然可以异步与服务器端进行数据交换,查询用户的输入的用户名是否在数据库中已经存在。
省市二联下拉框联动
很多站点都存在输入用户地址的操作,在完成地址输入时,用户所在的省份是下拉框,当选择不同的省份时会出现不同的市区的选择,这就是最常见的省市联动效果。
1.3 同步方式与异步方式的区别
同步方式发送请求
发送一个请求,需要等待响应返回,然后才能够发送下一个请求,如果该请求没有响应,不能发送下一个请求,客户端会处于一直等待过程中。
异步方式发送请求
发送一个请求,不需要等待响应返回,随时可以再发送下一个请求,即不需要等待。
二、 jQuery框架的ajax(重点)
2.1 jQuery框架的ajax简介
jquery是一个优秀的js框架,自然对js原生的ajax进行了封装,封装后的ajax的操 作方法更简洁,功能更强大,与ajax操作相关的jquery方法有如下几种,但开发中 经常使用的有三种:
请求方式 | 语法 |
---|---|
GET请求 | $.get(url, [data], [callback], [type]) |
POST请求 | $.post(url, [data], [callback], [type]) |
AJAX请求 | $.ajax([settings]) |
2.2 GET请求方式
概述
通过远程 HTTP GET 请求载入信息。这是一个简单的 GET 请求功能,如需复杂的ajax参数设置请使用$.ajax
。
语法
jQuery.get(url, [data], [callback], [type])
其中,参数说明如下:
参数名称 | 解释 |
---|---|
url | 请求的服务器端url地址 |
data | 发送给服务器端的请求参数,格式可以是key=value,也可以是js对象 |
callback | 当请求成功后的回掉函数,可以在函数体中编写我们的逻辑代码 |
type | 预期的返回数据的类型,取值可以是 xml, html, script, json, text, _defaul等 |
示例代码
- js代码
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
function sendRequest(){
$.get(
"/ajaxServlet",
"name=迪丽热巴&age=23",
function(data){
alert(data);
},
"text"
);
}
</script>
</head>
<body>
<input type="button" value="ajax异步访问服务器端" onclick="sendRequest()">
</body>
</html>
- Servlet代码
@WebServlet("/ajaxServlet")
public class AjaxServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获得请求参数
String name = request.getParameter("name");
String age = request.getParameter("age");
response.getWriter().write("ajax response data ..."+ name +"..."+age);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- 注意:js代码中的
$.get()
函数也可以写成如下格式,不同的是$.get()
中要加大括号
$.get({
url:"/ajaxServlet",
data:"name=迪丽热巴&age=23",
success:function(data){
alert(data);
},
dataType:"text"
});
2.3 POST请求方式
概述
通过远程 HTTP POST 请求载入信息。这是一个简单的 POST 请求功能,如需复杂的ajax参数设置请使用$.ajax。
语法
jQuery.post(url, [data], [callback], [type])
其中,参数说明如下:
参数名称 | 解释 |
---|---|
url | 请求的服务器端url地址 |
data | 发送给服务器端的请求参数,格式可以是key=value,也可以是js对象 |
callback | 当请求成功后的回掉函数,可以在函数体中编写我们的逻辑代码 |
type | 预期的返回数据的类型,取值可以是 xml, html, script, json, text, _defaul等 |
代码
- 只要把上面的
get
换成post
就行了
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
function sendRequest(){
$.post(
"/ajaxServlet",
"name=迪丽热巴&age=20",
function(data){
alert(data);
},
"text"
);
}
</script>
</head>
<body>
<input type="button" value="ajax异步访问服务器端" onclick="sendRequest()">
</body>
</html>
- Servlet代码
@WebServlet("/ajaxServlet")
public class AjaxServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获得请求参数
String name = request.getParameter("name");
String age = request.getParameter("age");
response.getWriter().write("ajax response data ..."+ name +"..."+age);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
2.4 AJAX请求方式(了解)
概述
通过 HTTP 请求加载远程数据。jQuery 底层 AJAX 实现。简单易用的高层实现见get和post方法。$.ajax()方法可以更加详细的设置底层的参数。
语法
jQuery.ajax([settings])
其中,settings是一个js字面量形式的对象,格式是{name:value,name:value... ...}
,常用的name属性名如下:
属性名称 | 解释 |
---|---|
url | 请求的服务器端url地址 |
async | (默认: true) 默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false |
data | 发送到服务器的数据,可以是键值对形式,也可以是js对象形式 |
type | (默认: “GET”) 请求方式 (“POST” 或 “GET”), 默认为 “GET” |
dataType | 预期的返回数据的类型,取值可以是 xml, html, script, json, text, _defaul等 |
success | 请求成功后的回调函数 |
error | 请求失败时调用此函数 |
代码
- js代码
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
function sendRequest(){
$.ajax({
url:"/ajaxServlet2",
async:true,
data:"name=迪丽热巴&age=21",
type:"GET",
dataType:"text",
success:function (data) {
alert(data);
},
error:function () {
alert("数据没有成功返回");
}
});
}
</script>
</head>
<body>
<input type="button" value="ajax异步访问服务器端" onclick="sendRequest()">
</body>
</html>
- Servlet代码
@WebServlet("/ajaxServlet2")
public class AjaxServlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获得请求参数
String name = request.getParameter("name");
String age = request.getParameter("age");
response.getWriter().write("ajax response data ..."+ name +"..."+age);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
三、用户名检查案例
3.1 问题描述
在注册时,如果用户名填写了已经被注册的数据,那么浏览器就会提示换个用户名,如下图所示,如果填写的用户名没有被注册过,那么提示用户该用户名可以使用。
3.2 问题分析
- 该功能的实现步骤:当用户输入用户名且鼠标离开输入框时,触发事件,抓取用户输入的用户名并去数据库中查询,如果查到了,证明该用户名已经被注册,提示“换个用户名”,否则提示“用户名可以使用”
3.3 数据库的建立
首先建立一个简单的数据库,代码如下,自行添加数据
CREATE DATABASE ajax;
USE ajax;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) DEFAULT NULL,
`password` VARCHAR(32) DEFAULT NULL,
PRIMARY KEY (`id`)
)
3.4 注册页面
- 写一个非常简单的注册页面,代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户注册</title>
</head>
<body>
<form action="01.html" method="get">
<table align="center" >
<tr>
<td>用户名</td>
<td><input type="text" name="username" id="username"/></td>
<td><span id="usernameMsg"></span></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"/></td>
<td><span id="passwordMsg"></span></td>
</tr>
<tr>
<td>昵称</td>
<td><input type="text" name="nickname"/></td>
<td><span id="nicknameMsg"></span></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="注册"/></td>
<td></td>
</tr>
</table>
</form>
</body>
</html>
界面如下图所示
3.5 给注册界面中的js代码
- 下面要往注册页面中国写控制的js代码,主要添加以下功能:
- 离焦事件,当鼠标离开文本框时触发
checkUserName
函数; checkUserName
函数判断用户输入不为空后向服务器发送用户名数据;- 服务器判断结果出来后,进行接收,不同的查询结果发送不同的信息
代码如下:
- 离焦事件,当鼠标离开文本框时触发
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户注册</title>
<script src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function checkUserName(){
// 获取用户的输入
var username = $("#username").val();
//.trim()去掉两端空格
if (username.trim() == ""){
//没有填写,提示输入用户名
$("#usernameMsg").html("请输入用户名!").css("color","red");
return; // 结束函数
}
// 当填写的数据不为空时,向服务器发送请求
$.get({
url:"/checkUserName",
data:"username="+username,
success:function (data) {
console.log(data)
// 判断服务器的查询结果
if (data == "false"){ //不可以使用
// id为usernameMsg的对象的html改为"用户名已经存在,请重新输入!",并修改其样式
$("#usernameMsg").html("用户名已经存在,请重新输入!").css("color","red");
return;
}else {
$("#usernameMsg").html("恭喜您,用户名可以使用!").css("color","green");
}
},
dataType:"text"
})
}
</script>
</head>
<body>
<form action="01.html" method="get">
<table align="center" >
<tr>
<td>用户名</td>
<!--注册事件,失去焦点-->
<td><input type="text" name="username" id="username" onblur="checkUserName()"/></td>
<td><span id="usernameMsg"></span></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"/></td>
<td><span id="passwordMsg"></span></td>
</tr>
<tr>
<td>昵称</td>
<td><input type="text" name="nickname"/></td>
<td><span id="nicknameMsg"></span></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="注册"/></td>
<td></td>
</tr>
</table>
</form>
</body>
</html>
3.6 服务器端代码
3.6.1 Servlet代码
import pojo.User;
import service.UserService;
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(urlPatterns = "/checkUserName")
public class CheckUserNameServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
// 向service层传递用户名,返回查询结果
UserService service = new UserService();
User user = service.queryByUserName(username);
if (user != null){
// 查询到了结果,证明该用户名不可以用,所以向网页发送false
response.getWriter().write("false");
}else {
response.getWriter().write("true");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
3.6.2 Service层代码
import dao.UserDao;
import pojo.User;
import java.sql.SQLException;
import java.util.List;
public class UserService {
/**
* 接收web传来的用户名
* 调用dao层方法查询数据
*/
public User queryByUserName(String username){
UserDao userDao = new UserDao();
User user = userDao.queryByUserName(username);
return user;
}
}
3.6.3 Dao层代码
package dao;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import pojo.User;
import utils.C3p0Utils;
import java.sql.SQLException;
import java.util.List;
public class UserDao {
/**
* 接收业务层传递的用户名
* 查询数据表,返回User对象
*/
public User queryByUserName(String username){
QueryRunner qr = new QueryRunner(C3p0Utils.getDataSource());
String sql = "select * from user where name = ?";
User user = null;
try {
user = qr.query(sql, new BeanHandler<User>(User.class),username);
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
}
3.6.4 效果
四、 json数据格式
4.1 什么是json
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
4.2 json的语法格式
json对象有三种数据格式,分别如下:
类型 | 语法 | 解释 |
---|---|---|
对象类型 | {name:value,name:value…} | 其中name是字符串类型,而value是任意类型 |
数组/集合类型 | [value,value,value…] | 其中value是任意类型 |
混合类型 | [{},{}… …] 或 {name:[]… …} | 合理包裹嵌套对象类型和数组类型 |
4.3 json格式和json解析练习
练习1 – json表示对象的方式
格式:
{key:value,key:value}
代码演示:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script language="JavaScript">
/**
* 案例一
* var person={key:value,key:value}
*
* class Person{
* String firstname = "张";
* String lastname = "三丰";
* Integer age = 100;
* }
*
* Person p = new Person();
* System.out.println(p.firstname);
*/
//json的定义
var person = {"firstname":"迪丽","lastname":"热巴","age": 20};
//json解析
console.log( person.firstname );
console.log( person.lastname);
console.log( person.age);
</script>
</head>
<body>
</body>
</html>
练习2 - json表示对象集合(对象数组)的方式
格式:
[{key:value,key:value},{key:value,key:value}]
代码演示:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script language="JavaScript">
/**
* 案例二
* [{key:value,key:value},{key:value,key:value}]
*/
//json的定义
var persons = [{"firstname":"迪丽","lastname":"热巴","age": 20},
{"firstname":"古力","lastname":"娜扎","age": 20},
{"firstname":"欧阳","lastname":"娜娜","age": 20}];
//json解析
for(var i=0; i<persons.length; i++){
console.log( persons[i].firstname +"=="+ persons[i].lastname +"=="+ persons[i].age );
}
</script>
</head>
<body>
</body>
</html>
练习3 - 对象中的某个属性的值 是 对象数组
格式:
{
"param":[{key:value,key:value},{key:value,key:value}]
}
代码演示:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script language="JavaScript">
/**
案例
{
"param":[{key:value,key:value},{key:value,key:value}]
}
*/
//json的定义
var persons = {"girls":[{"firstname":"迪丽","lastname":"热巴","age": 20},
{"firstname":"古力","lastname":"娜扎","age": 20},
{"firstname":"欧阳","lastname":"娜娜","age": 20}]};
//json解析
//获取所有
for(var i=0; i<persons.girls.length; i++){
console.log( persons.girls[i].firstname + persons.girls[i].lastname);
}
</script>
</head>
<body>
</body>
</html>
练习4 - 对象中的多个属性的值 是 对象数组
格式:
{
"param1":[{key:value,key:value},{key:value,key:value}],
"param2":[{key:value,key:value},{key:value,key:value}],
"param3":[{key:value,key:value},{key:value,key:value}]
}
代码演示:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script language="JavaScript">
/**
* 案例
* {
"param1":[{key:value,key:value},{key:value,key:value}],
"param2":[{key:value,key:value},{key:value,key:value}],
"param3":[{key:value,key:value},{key:value,key:value}]
}
*/
//json的定义
var persons = {"girls":[
{"firstname":"迪丽","lastname":"热巴","age": 20},
{"firstname":"古力","lastname":"娜扎","age": 20},
{"firstname":"欧阳","lastname":"娜娜","age": 20}
],
"boys":[
{"firstname":"吴","lastname":"京","age": 35},
{"firstname":"古","lastname":"天乐","age": 40}
]};
//json解析
//获取古天乐
console.log( persons.boys[1].firstname +"=="+ persons.boys[1].lastname );
</script>
</head>
<body>
</body>
</html>
4.4 json的转换工具
json转换工具的概述
json的转换工具是通过java封装好的一些jar工具包,直接将java对象或集合转换成json格式的字符串。
json的转换插件是通过java的一些工具,直接将java对象或集合转换成json字符串。
常见的json转换工具
工具名称 | 介绍 |
---|---|
Jsonlib | Java 类库,需要导入的jar包较多 |
Gson | google提供的一个简单的json转换工具 |
Fastjson | alibaba技术团队提供的一个高性能的json转换工具 |
Jackson | 开源免费的json转换工具,springmvc转换默认使用jackson |
Jackson开发步骤
- 导入jar包
- 创建Jackson转换工具对象 ObjectMapper
- 调用方法, 完成 json 与java对象 相互转换
API简述
ObjectMapper类, 是Jackson库的主要类, 它提供一些功能将Java对象转换成JSON结构,反之亦然
TypeReference 类, 对进行泛型的反序列化,使用TypeReference可以明确的指定反序列化的类型
- API : 类ObjectMapper
方法 | 描述 |
---|---|
public String writeValueAsString(Object value) | 将java对象 转换成 json字符串 |
public T readValue(String content, Class valueType) | 将json字符串 转换成 Java对象 |
public T readValue(String content, TypeReference valueTypeRef) | 将json字符串 转换成 Java对象 |
json字符串与java对象相互转换:
- 需求:
1. 对象转json, json转对象
2. map<String,String>转json, json转map<String,String>
3. map<String,User>转json, json转map<String,User>
4. list<String>转json, json转 list<String>
5. list<User>转json, json转list<User>
- 代码实现
public class JsonAndJava {
private static ObjectMapper mapper = new ObjectMapper();
/**
* 1. 对象转json, json转对象
* 打印结果
* json字符串 = {"name":"迪丽热巴","age":22}
* java对象 = User{name='迪丽热巴', age=22}
*/
@Test
public void test1() throws IOException {
//对象转json
User user = new User("迪丽热巴", 22);
String json = mapper.writeValueAsString(user);
System.out.println("json字符串 = "+json);
//json转对象
User u = mapper.readValue(json, User.class);
System.out.println("java对象 = " + u);
}
/**
* 2. map<String,String>转json, json转map<String,String>
* 打印结果
* json字符串 = {"最佳男明星":"古天乐","最佳女明星":"迪丽热巴"}
* java对象 = {最佳男明星=古天乐, 最佳女明星=迪丽热巴}
*/
@Test
public void test2() throws IOException {
//map<String,String>转json
HashMap<String, String> map = new HashMap<>();
map.put("最佳女明星","迪丽热巴");
map.put("最佳男明星","古天乐");
String json = mapper.writeValueAsString(map);
System.out.println("json字符串 = "+json);
//json转map<String,String>
HashMap<String,String> mmap = mapper.readValue(json, HashMap.class);
System.out.println("java对象 = "+mmap);
}
/**
* 3. map<String,User>转json, json转map<String,User>
* 打印结果:
* json字符串 = {"最佳男明星":{"name":"古天乐","age":35},"最佳女明星":{"name":"迪丽热巴","age":22}}
* java对象 = {最佳男明星=User{name='古天乐', age=35}, 最佳女明星=User{name='迪丽热巴', age=22}}
*/
@Test
public void test3() throws IOException {
//map<String,User>转json
HashMap<String, User> map = new HashMap<>();
map.put("最佳女明星",new User("迪丽热巴",22));
map.put("最佳男明星",new User("古天乐", 35));
String json = mapper.writeValueAsString(map);
System.out.println("json字符串 = " + json);
//json转map<String,User>
HashMap<String, User> mmap = mapper.readValue(json, new TypeReference<HashMap<String, User>>() {});
System.out.println("java对象 = " + mmap);
}
/**
* 4. List<String>转json, json转 List<String>
* 打印结果:
* json字符串 = ["迪丽热巴","古力娜扎"]
* java对象 = [迪丽热巴, 古力娜扎]
*/
@Test
public void test4() throws IOException {
//List<String>转json
List<String> list = new ArrayList<>();
list.add("迪丽热巴");
list.add("古力娜扎");
String json = mapper.writeValueAsString(list);
System.out.println("json字符串 = " + json);
//json转 List<String>
List<String> list1 = mapper.readValue(json, List.class);
System.out.println("java对象 = " + list1);
}
/**
* 5. List<User>转json, json转List<User>
* 打印结果:
* json字符串 = [{"name":"迪丽热巴","age":23},{"name":"古力娜扎","age":20}]
* java对象 = [User{name='迪丽热巴', age=23}, User{name='古力娜扎', age=20}]
*/
@Test
public void test5() throws IOException {
//List<User>转json
List<User> list = new ArrayList<>();
list.add(new User("迪丽热巴", 23));
list.add(new User("古力娜扎", 20));
String json = mapper.writeValueAsString(list);
System.out.println("json字符串 = " + json);
//json转List<User>
List<User> list1 = mapper.readValue(json, new TypeReference<List<User>>(){});
System.out.println("java对象 = " + list1);
}
}