1. ajax
-
Ajax (Asynchronous Javascript And XML,异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新,即在不重新加载整个页面的情况下,实现对网页部分更新的效果。
-
应用场景
- 检查用户名是否已被注册
- 省市二联下拉框联动
- 内容自动补全
1.1 同步方式与异步方式的区别
-
同步方式发送请求:
- 每个请求都需要等待响应返回后才能发送下一个请求。如果请求无响应,则不能发送下一个请求,客户端处于抑制等待的过程。
-
异步方式发送请求:
- 每个请求不需要等待响应返回随时可以发送下一个请求。
1.2 ajax原理分析
-
本质是js,通过对网页的js代码进行操作,达到页面更新的效果。
-
原理详述:
- ajax引擎提交异步请求,服务器端处理完返回数据给ajax引擎
2. js原生的ajax
2.1 js原生的ajax的开发步骤
1)创建Ajax引擎对象;
2)为Ajax引擎对象绑定监听(监听服务器已将数据响应给引擎);
3)绑定提交地址;
4)发送请求;
5)接受响应数据。
2.2 原理
-
ajax通过ajax引擎对象与服务器通信状态码xmlHttp.readystate获得连接状态,状态码范围:0-4。
-
状态码的数值每次变化都会调用ajax的回调函数。
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
-
只有ajax引擎通信状态码为4和http通信状态码为200才能保证获得正确的响应数据
2.3 js原生的ajax示例代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css"></style>
<script type="text/javascript">
//同步事件
function sendRequest() {
location.href="Demo01AjaxServlet?name=admin&psw=13579";
}
//异步事件
function sendAjaxRequest() {
//1)创建Ajax引擎对象;
var xmlhttp = new XMLHttpRequest(); //此时readystate=0
//2)为Ajax引擎对象绑定监听(监听服务器已将数据响应给引擎);
xmlhttp.onreadystatechange = function () {
//状态码每次变动都会执行该函数
//这个回调函数共被调用4次,但只有状态码4的时候才代表服务器响应数据完成。
//只有保证ajax引擎通信状态码为4和http通信状态码为200,才能保证数据正确响应
if (xmlhttp.readyState == 4 && xmlhttp.status==200) {
//5)获得响应数据
var resultContent = xmlhttp.responseText;
alert(resultContent);
}
}
//3)绑定提交地址;
//xmlhttp.open(提交方式,请求路径)
xmlhttp.open("get","Demo01AjaxServlet?name=admin&psw=13579");
//4)发送请求;
xmlhttp.send();
}
</script>
</head>
<body>
<input type="button" value="发送同步请求" onclick="sendRequest()">
<input type="button" value="发送异步请求" onclick="sendAjaxRequest()">
</body>
</html>
servlet:已有过滤器过滤乱码
@javax.servlet.annotation.WebServlet(urlPatterns = "/Demo01AjaxServlet")
public class Demo01AjaxServlet extends javax.servlet.http.HttpServlet {
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//获得请求数据
String name = request.getParameter("name");
String psw = request.getParameter("psw");
System.out.println("name=" + name);
System.out.println("psw=" + psw);
//输出数据到页面中
response.getWriter().write("this is ajax");
}
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//*如果post方式的执行内容与get不同,则删掉下面代码重写即可
doGet(request, response);
}
}
3. jQuery框架下的ajax
3.1 jQuery框架的ajax简介
以下为常用的5种方式
请求方式 | 语法 |
---|---|
GET请求 | $.get(url, [data], [callback], [type]) |
POST请求 | $.post(url, [data], [callback], [type]) |
AJAX请求 | $.ajax([settings]) |
GET请求 | $.get([settings]) |
POST请求 | $.post([settings]) |
3.2 GET请求方式
- 通过远程 HTTP GET 请求载入信息
3.2.1 GET请求方式语法
jQuery.get(url, [data], [callback], [type])
参数说明:
参数名称 | 解释 |
---|---|
url(必选) | 请求的服务器端url地址 |
data | 发送给服务器端的请求参数,格式是键值对字符串("key1=value1&key2=value2..." ),或js对象({key1:value1,key2:value2...} ) |
callback | 请求成功后的回调函数,用于处理服务器返回的数据,格式为function(result){} ,其中result是用于接收返回数据的变量 |
type | 设置服务器返回数据的类型,常见类型有 xml, html, script, json, text(默认格式)等 |
注意事项
如果type是json,会要求服务器返回json字符串并将返回的数据转换为js对象(也称为json对象)。json字符串格式:"{\"key1\":value1,\"key2\":value2...}"
。注意,json格式要求每个key必须使用双引号括住。
3.2.3 GET请求示例代码
html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax</title>
<style type="text/css"></style>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function sendAjaxRequest() {
//使用get请求方式
//jQuery.get(url, [data], [callback], [type])
//注意,url、data、type都是字符串形式,callback的格式为function(result){}
$.get("Demo02AjaxServlet","name=admin&psw=13579",function (result) {
alert(result);
},"text");
}
</script>
</head>
<body>
<input type="button" value="发送异步请求" onclick="sendAjaxRequest()">
</body>
</html>
servlet代码
@WebServlet(urlPatterns = "/Demo02AjaxServlet")
public class Demo02AjaxServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得请求数据
String name = request.getParameter("name");
String psw = request.getParameter("psw");
System.out.println("name=" + name);
System.out.println("psw=" + psw);
//输出数据到页面中
response.getWriter().write("this is ajax by get");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得请求数据
String name = request.getParameter("name");
String psw = request.getParameter("psw");
System.out.println("name=" + name);
System.out.println("psw=" + psw);
//输出数据到页面中
response.getWriter().write("this is ajax by post");
}
}
3.3 POST请求方式
- 通过远程 HTTP POST 请求载入信息
3.2.1 POST请求方式语法
jQuery.post(url, [data], [callback], [type])
参数说明同GET请求方式的参数说明
3.2.3 POST请求示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax</title>
<style type="text/css"></style>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function sendAjaxRequest() {
//使用post请求方式
//jQuery.post(url, [data], [callback], [type])
//注意,url、data、type都是字符串形式,callback的格式为function(result){}
$.post("Demo02AjaxServlet","name=admin&psw=13579",function (result) {
alert(result);
},"text");
}
</script>
</head>
<body>
<input type="button" value="发送异步请求" onclick="sendAjaxRequest()">
</body>
</html>
3.3 AJAX请求方式(也称为AJAX签名方式)(推荐)
- 通过 HTTP 请求加载远程数据
3.3.1 AJAX请求方式语法
jQuery.ajax(url[,async][,data][,type][,dataType][,success][,error])
- ajax的属性要以js对象形式或键值对形式
属性名称 | 解释 |
---|---|
url(必选) | 请求的服务器端url地址 |
async | (默认: true) 默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false |
data | 发送到服务器的数据,可以是键值对形式,也可以是js对象形式 |
type | (默认: “GET”) 请求方式 (“POST” 或 “GET”), 默认为 “GET” |
dataType | 预期的返回数据的类型,取值可以是 xml, html, script, json, text, _defaul 等 |
success | 请求成功后的回调函数,一般格式function(result){} |
error | 请求失败时调用此函数 |
注意事项
ajax请求方式的参数type含义与get/post请求方式的type含义不一样,注意区分。
3.3.2 AJAX请求示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax</title>
<style type="text/css"></style>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function sendAjaxRequest() {
//使用ajax请求方式
//jQuery.ajax(url[,async][,data][,type][,dataType][,success][,error])
$.ajax({
url:"Demo02AjaxServlet",
data:{name:"admin",psw:"13579"},
type:"get",//可以是get或者post
dataType:"text",
success:function (result) {
alert(result);
},
error:function () {
alert("服务器忙");
}
});
}
</script>
</head>
<body>
<input type="button" value="发送异步请求" onclick="sendAjaxRequest()">
</body>
</html>
3.4 jQuery3.0 的GET新增签名方式
- jQuery 3 为
jQuery.get()
和jQuery.post()
这两个工具函数增加了新签名,从而使得它们和$.ajax()
的接口风格保持一致
3.4.1 jQuery3.0 的GET新增签名方式语法
jQuery.get([settings])
注:settings与ajax请求方式的settings基本一致,除了不用写type
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax</title>
<style type="text/css"></style>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function sendAjaxRequest() {
//使用get新特性请求方式
//jQuery.get(url[,async][,data][,type][,dataType][,success][,error])
$.get({
url:"Demo02AjaxServlet",
data:{name:"admin",psw:"13579"},
type:"get",
dataType:"text",
success:function (result) {
alert(result);
},
error:function () {
alert("服务器忙");
}
});
}
</script>
</head>
<body>
<input type="button" value="发送异步请求" onclick="sendAjaxRequest()">
</body>
</html>
3.4.2 jQuery3.0 的POST新增签名方式语法
jQuery.post([settings])
注:settings与ajax请求方式的settings基本一致,除了不用写type
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax</title>
<style type="text/css"></style>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function sendAjaxRequest() {
//使用post新特性请求方式
//jQuery.post(url[,async][,data][,type][,dataType][,success][,error])
$.post({
url:"Demo02AjaxServlet",
data:{name:"admin",psw:"13579"},
type:"get",
dataType:"text",
success:function (result) {
alert(result);
},
error:function () {
alert("服务器忙");
}
});
}
</script>
</head>
<body>
<input type="button" value="发送异步请求" onclick="sendAjaxRequest()">
</body>
</html>
3.5 使用jQuery框架下的ajax的注意事项
参数的value是字符串类型、js对象或者函数。如果不是js对象或者函数,基本都要用双引号括住
4. JSON
- JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
- 作用:
- 处理Javascript 和web服务器端的之间数据交换,是一种数据传输格式;
- 常用于ajax,可以转换成js对象;
4.0.1 json字符串基本格式
"{\"key1\":value1,\"key2\":value2...}"
。- 注意,json格式要求每个key必须使用双引号括住。
4.1 三种类型的json的语法格式
类型 | 语法 | 解释 |
---|---|---|
对象类型 | {name:value,name:value...} | 其中name是字符串类型(需要用双引号括住),而value是任意类型 |
数组/集合类型 | [value,value,value...] 或[{},{}...] | 其中value是任意类型 |
混合类型 | {name:[]...} | 合理包裹嵌套对象类型和数组类型 |
4.2 json示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css"></style>
<script type="text/javascript">
//json的定义
var person = {"firstname":"张","lastname":"三丰","age":100};
//json解析
alert("1" + person.firstname);
alert("1" + person.lastname);
alert("1" + person.age);
//[{key:value,key:value},{key:value,key:value}]
var json = [
{"firstname":"张","lastname":"三丰","age":100},
{"firstname":"张","lastname":"翠山","age":58},
{"firstname":"张","lastname":"无忌","age":23}
];
for(var i=0;i<json.length;i++){
alert("2" + json[i].lastname);
}
/*
{
* "param":[{key:value,key:value},{key:value,key:value}]
* }
*/
json = {
"baobao":[
{"name":"小双","age":18,"addr":"扬州"},
{"name":"建宁","age":18,"addr":"北京海淀"},
{"name":"龙儿","age":38,"addr":"岛国"},
{"name":"阿珂","age":17,"addr":"台湾"}
]
};
//全取
for(i=0;i<json.baobao.length;i++){
alert("3" + json.baobao[i].name);
}
/*
{
* "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 = {
"baobao":[
{"name":"小双","age":18,"addr":"扬州"},
{"name":"建宁","age":18,"addr":"北京海淀"},
{"name":"龙儿","age":38,"addr":"岛国"},
{"name":"阿珂","age":17,"addr":"台湾"}
],
"haohao":[
{"name":"楠楠","age":23,"addr":"北京昌平修正"},
{"name":"倩倩","age":18,"addr":"上海"}
]
}
//取倩倩
alert(json.haohao[1].name);
</script>
</head>
<body>
</body>
</html>
4.3 json转换工具
-
json字符串拼接非常麻烦,首先每个key必须使用双引号括住,而且整个字符串要用双引号括住(详见上面json格式),涉及到双引号的转义。如果字符串太长,很容易拼错。
-
json的转换工具是通过java封装好的一些jar工具包,直接将java对象或集合转换成json格式的字符串
4.3.1 常见的json转换工具
Jsonlib: Java 类库,需要导入的jar包较多
Gson: google提供的一个简单的json转换工具
Fastjson :alibaba技术团队提供的一个高性能的json转换工具
Jackson: 开源免费的json转换工具,springmvc转换默认使用jackson
4.3.2 开发步骤
1)导入json相关jar包;
2)创建java对象或集合;
3) 使用jackson的核心对象ObjectMapper
的writeValueAsString()
转换为json字符串
4.3.3 json转换工具的返回值
- 传入java对象,返回值是对象类型的json字符串;
- 传入List集合,返回值是数组类型的json字符串(保存多条数据);
- 传入map集合,返回值是混合类型的json字符串;
4.3.4 json转换示例代码
public class Demo03Json_Jackson {
public static void main(String[] args) {
/*创建java对象或集合;
使用Jackson的核心对象ObjectMapper的writeValueAsString()转换为json字符串*/
try {
//1.将JavaBean转换为json字符串
//创建对象
User user = new User(1,"JoJo","starplatinum");
//使用Jackson核心对象转换为json字符串
String jsonUser = new ObjectMapper().writeValueAsString(user);
System.out.println("java对象转json字符串:" + jsonUser);
//2.将List转换为json字符串
List<User> list = new ArrayList<>();
list.add(new User(1,"JoJo","starplatinum"));
list.add(new User(2,"dio","theworld"));
//使用Jackson核心对象转换为json字符串
String listJson = new ObjectMapper().writeValueAsString(list);
System.out.println("List集合转json字符串:" + listJson);
//3.将Map转换为json字符串
Map<String,User> map = new HashMap<>();
map.put("jj", new User(1,"JoJo","starplatinum"));
map.put("dd", new User(2,"dio","theworld"));
//使用Jackson核心对象转换为json字符串
String mapJson = new ObjectMapper().writeValueAsString(map);
System.out.println("map集合转json字符串:" + mapJson);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5. 经典案例
5.1 检查用户名是否已被注册
需求:在用户注册页面,输入用户名,当用户名输入框失去焦点时,发送异步请求,将输入框的用户名传递给服务器端进行是否存在的校验。
准备工作:导入druid、JDBCUtils工具类、JdbcTemplate、tomcat及Tomcat8的乱码过滤器、实体类
5.1.1 页面代码
- 重点:使用ajax异步请求数据,注意,每个属性的值是字符串或者js对象,success和error属性是回调函数,success的需要用一个变量保存返回的数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>register</title>
<style type="text/css"></style>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
/*
思路:给用户名的input注册一个失去焦点的事件,当触发事件后异步发送请求到服务器中查询
获取返回的信息输出信息(使用json和ajax)
*/
//注册失去焦点事件
$(function () {
$("#username").blur(function () {
//获取用户输入的内容
var content = $(this).val();
//判断输入的内容是否为空,空返回false,非空返回true
if (content){
//使用ajax异步发送请求
$.ajax({
url: "RegisterServlet",
data:{username:content}, //注意是一个js对象或者键值对
type:"post",
dataType:"json",
success:function (result) {
/*如果是用户名存在,则显示红色字体*/
if(result.flag) {
$("#usernameInfo").css("color","red");
} else {
/*如果是用户名不存在,则显示绿色字体*/
$("#usernameInfo").css("color","green");
}
//在输入框后面的span标签添加msg内容
$("#usernameInfo").html(result.msg);
},
error:function () {
alert("服务器忙,请稍后")
}
});
}
});
});
</script>
</head>
<body>
<div>
<font>会员注册</font>USER REGISTER
<form class="form-horizontal" style="margin-top: 5px;">
<table>
<tr>
<td>用户名</td>
<td>
<input type="text" id="username" name="username" placeholder="请输入用户名">
<span id="usernameInfo" style="color:red"></span>
</td>
</tr>
<tr>
<td>密码</td>
<td>
<input type="password" placeholder="请输入密码">
</td>
</tr>
</table>
<input type="submit" value="注册"/>
</form>
</div>
</body>
</html>
5.1.2 web层
重点:拼接json字符串,用于给页面显示提示信息
@WebServlet(urlPatterns = "/RegisterServlet")
public class RegisterServlet extends HttpServlet {
private RegisterService service = new RegisterService();
/*
思路:页面发送请求到这里,调用service层的方法获得数据,然后返回json数据,其中包含两个属性,第一个是布尔类型,
用于指明用户名是否存在,第二个是String类型,用于给予对应的提示
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//获取请求的数据
String username = request.getParameter("username");
//根据username调用方法获取对应的用户
User user = service.getUserByName(username);
String jsonData = null;
//判断user是否为空
if (user != null) {
//拼接json字符串
jsonData = "{\"flag\":true,\"msg\":\"已被注册\"}";//js对象
} else {
jsonData = "{\"flag\":false,\"msg\":\"可以注册\"}";//js对象
}
//返回json到页面
response.getWriter().write(jsonData);
} catch (Exception e) {
e.printStackTrace();
//不需要给前端友好提示,因为前端有错误回调函数,这里只要不返回json字符串,ajax引擎就知道发生错误了。
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//*如果post方式的执行内容与get不同,则删掉下面代码重写即可
doGet(request, response);
}
}
5.1.3 service层
public class RegisterService {
private UserDao userDao = new UserDao();
/**
* 调用dao层获取用户
* @param username
* @return User
* @throws Exception
*/
public User getUserByName(String username) throws Exception{
return userDao.getUserByName(username);
}
}
5.1.4 dao层
public class UserDao {
private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 访问数据库获取用户信息
* @param username
* @return User
* @throws SQLException
*/
public User getUserByName(String username) throws SQLException{
try {
String sql = "select * from user where username = ?;";
return jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(User.class),username);
} catch (DataAccessException e) {
return null;
}
}
}
5.2 内容自动补全
需求:在输入框输入关键字,下拉框中异步显示与该关键字相关的商品的名称
案例代码
- 下面代码已省略实体类、乱码过滤器、工具类等准备工作
5.2.1 jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
.content{
width:643px;
margin:200px 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>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(function () {
//给搜索框注册键盘弹起事件
$("#word").keyup(function () {
//获取搜索框的内容
var content = $(this).val();
//判断有效性,如果不为空则异步发送请求
if (content) {
//使用ajax异步发送请求
$.ajax({
url:"SearchServlet",
data:{word:content}, //传输的数据时输入的内容
dataType:"json",
type:"post",
success:function (result) {
//如果获得数据,则将数据添加到输入框后面,需要拼装字符串
//遍历,获取列表每个数据并拼装
var html = "";
for (var i=0;i<result.length;i++) {
//获取每个user数据
var user=result[i];
//拼接字符串
html+="<div>"+user.name+"</div>"
}
//将拼接的字符串更新到show的标签体中
$(".show").html(html);
//使用动画将更新的内容显示出来
$(".show").show();
},
error:function () {
alert("服务器忙,请稍后再试");
}
});
}
});
});
</script>
</head>
<body>
<div class="content">
<img alt="" src="img/管理三连.jpg"><br/><br/>
<input id="word" type="text" name="word">
<input type="button" value="搜索一下">
<div class="show"></div>
</div>
</body>
</html>
5.2.2 web层
@WebServlet(urlPatterns = "/SearchServlet")
public class SearchServlet extends HttpServlet {
private SearchService searchService = new SearchService();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//获取请求数据
String content = request.getParameter("word");
//调用service层获取符合条件的列表
List<User> userList = searchService.findContent(content);
//转化为json返回到浏览器
String listStr = new ObjectMapper().writeValueAsString(userList);
response.getWriter().write(listStr);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
5.2.3 service层
public class SearchService {
private UserDao userDao = new UserDao();
/**
* 获得user列表
* @param content
* @return List<User>
* @throws Exception
*/
public List<User> findContent(String content) throws Exception{
return userDao.findContent(content);
}
}
5.2.4 dao层
public class UserDao {
private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 获得相关的user列表
* @param content
* @return List<User>
* @throws SQLException
*/
public List<User> findContent(String content) throws SQLException{
String sql = "select * from user where name like ? limit 0,4;"; //限制显示0-4条
return jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(User.class),content+"%"); //模糊搜索,获得已content开头的列表
}
}