一、Ajax
1.介绍
概念:
Ajax(Asynchronous Javascript And XML)是由浏览器解析运行的基于JavaScript实现的网页局部刷新的技术。
作用:
实现了在当前网页中显示新的响应内容。(不会覆盖掉原有内容)
特点:
一种新的让浏览器发起http请求的技术
使用ajax发起的请求,响应结果不会自动的覆盖原有内容,而是可以在原有页面内容上继续显示
Ajax是一门基于JavaScript的技术,由浏览器解析运行,所以是一种前端(客户端)技术
简单易用
理解案例
1.页面
<script>
$(function () {
$("#a").click(function () {
//1.创建ajax请求对象,该对象可以向服务端发起请求
var xhr = new XMLHttpRequest();
//2.开启连接
xhr.open("get", "testServlet");
//3.发起请求
xhr.send();
//4.监听就绪状态的变化,就绪状态发生变化会被监听,自动调用指定的function
xhr.onreadystatechange = function (ev) {
if(xhr.readyState==4 && xhr.status==200){
//console.log(xhr);
//获取响应的数据
var responseText = xhr.responseText;
console.log(responseText);
//完成页面的局部刷新
$("#pp").html(responseText);
$("#a").remove();
}
};
});
})
</script>
2. servlet
@WebServlet("/testServlet")
public class TestServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.print(" 爱不是每天相偎相依的温暖,而是彼此走入灵魂深处的,那份无声的惦念,无言的爱恋。一份感情,能够随着时间沉淀下来,潜藏在心里的,那一定是最深的情感。真正爱你的人,不仅使你的脸上充满了微笑,更使你的心灵荡漾了无拘无束的笑声。爱一个人容易,一生只爱一个人实在不容易。所以在爱的世界里,需要信任、包容和理解。信任是理解和包容的基础,包容是信任和理解的目的,理解是信任和包容重要联系的纽带...");
}
}
3.Ajax的基本使用
<script>
$(function () {
$("#a").click(function () {
//1.创建ajax请求对象,该对象可以向服务端发起请求
var xhr = new XMLHttpRequest();
console.log(xhr);
//2.开启连接
xhr.open("get", "testServlet");
console.log(xhr);
//3.发起请求
xhr.send();
//4.监听就绪状态的变化,就绪状态发生变化会被监听,自动调用指定的function
xhr.onreadystatechange = function (ev) {
console.log(xhr);
};
});
})
</script>
2.Ajax的就绪状态
在ajax对象中提供了一个监听机制 “onreadystatechange”,用来监听ajax的属性readyState的改变情况,一旦该值改变,就会触发监听中的函数的执行。
readyState的值表示的含义:
0:请求没有开启(在调用open()之前)
1:请求已经建立但是还没有发出(调用send()之前)
2:请求已经发出,服务器正在处理
3:请求已经处理,响应中有数据可用,但是服务器还没有完全响应完
4:响应已经完成,浏览器已经接收到全部的响应内容
对我们来说,我们应该关注的是readyState是4时候的情况。
3.Ajax的响应状态
通过对ajax的就绪状态做判断,我们在就绪状态是4的情况下编写我们的对响应结果的处理逻辑代码,但是不是任何响应结果我们都要处理,因为服务器的响应也有状态码,比如:200、404、500等等。
所有我们在ajax中编写响应结果处理时,也必须考虑响应状态码。
<script>
$(function () {
$("#a").click(function () {
//1.创建ajax请求对象,该对象可以向服务端发起请求
var xhr = new XMLHttpRequest();
//2.开启连接
xhr.open("get", "testServlet");
//3.发起请求
xhr.send();
//4.监听就绪状态的变化,就绪状态发生变化会被监听,自动调用指定的function
xhr.onreadystatechange = function (ev) {
if(xhr.readyState==4 && xhr.status==200){
//console.log(xhr);
//获取响应的数据
var responseText = xhr.responseText;
console.log(responseText);
//完成页面的局部刷新
$("#pp").html(responseText);
$("#a").remove();
}
};
});
})
</script>
4.同步请求和异步请求
同步请求
发送请求后,一直等待服务端的响应,获取到服务端响应,再执行其他的逻辑代码。
浏览器直接发起
在浏览器地址栏输入url,发起请求
使用超链接,发起请求
使用form表单,发起请求
在js代码中使用window.location.href,发起请求
ajax发起同步请求,有xhr对象发起请求
ajax与其他方式发送同步请求的区别: ajax可以局部刷新(由xhr对象发送请求),其他的请求方式会刷新整张页面
异步请求
发送请求后,不需要等待服务端的响应,继续按照顺序执行其他逻辑代码,监听到响应,自动调用指定的方法。
ajax发起异步请求
5.Ajax的同步和异步设置
设置ajax的同步异步:
通过设置Ajax请求对象open方法的async参数的值:
true:表示异步,默认值
false:表示同步
示例
servlet
@WebServlet("/testSyn")
public class TestSyn extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
resp.getWriter().print("success");
}
}
html
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="testSyn">发送请求</a>
</body>
</html>
Ajax发送同步请求
<html>
<head>
<title>Title</title>
<script>
function f() {
var xhr = new XMLHttpRequest();
/* false:同步请求 */
xhr.open("get", "testSyn", false);
xhr.send();
alert(xhr.responseText);
}
</script>
</head>
<body>
<a href="javascript:void(0)" onclick="f()">发送请求</a>
</body>
</html>
Ajax发送异步请求
<html>
<head>
<title>Title</title>
<script>
function f() {
var xhr = new XMLHttpRequest();
/* true(默认):异步请求 */
xhr.open("get", "testSyn", true);
xhr.send();
xhr.onreadystatechange = function (ev) {
if(xhr.readyState==4 && xhr.status==200){
alert(xhr.responseText);
}
};
}
</script>
</head>
<body>
<a href="javascript:void(0)" onclick="f()">发送请求</a>
</body>
</html>
6.Ajax设置get请求方式及携带请求参数:
Ajax的get请求的请求参数是直接写在请求路径后面
<script>
function f() {
var xhr = new XMLHttpRequest();
xhr.open("get","HelloServlet?name=lucy&age=18");
xhr.send();
xhr.onreadystatechange = function (ev) {
if(xhr.readyState==4 && xhr.status==200){}
};
}
</script>
7.Ajax设置post请求方式及携带请求参数:
Ajax的post请求传递参数是需要单独写在send方法中,而且需要设置请求头,该请求头表示此次请求是以表单的方式提交
<script>
function f() {
var xhr = new XMLHttpRequest();
xhr.open("get","HelloServlet");
//请求方式是post请求,则需要设置请求头,这个请求头就表示是以表单方式提交数据
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("name=lily&age=15");
xhr.onreadystatechange = function (ev) {
if(xhr.readyState==4 && xhr.status==200){}
};
}
</script>
8.Ajax请求的响应数据格式及处理(重点)
使用json数据格式(特殊格式的字符串, 和js对象格式一致),它比较方便简单,而且也有好用的json工具包。所以,服务器响应Java对象数据给浏览器时,可以使用json字符串的格式!
Java对象的json字符串格式:
普通Java对象的json字符串格式:
User user = new User(1, "张三丰", 18, "北京");
{"id":1, "name":"张三丰", "age": 18, "address":"北京"}
Map集合对应的json字符串格式:
Map<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
{"key1":"value1", "key2":"value2"}
List集合对应的json字符串格式:
List<User> list = new ArrayList<>();
list.add(new User(1, "赵敏", 18, "北京"));
list.add(new User(2, "周芷若", 28, "上海"));
[
{"id":1, "name":"赵敏", "age":18, "address":"北京"},
{"id":2, "name":"周芷若", "age":28, "address":"上海"}
]
Ajax获取响应数据的方式:var 变量名 = xhr.responseText;
获取到的是普通字符串数据:直接使用
获取到的是json格式的字符串:使用js的eval()函数,将json格式的字符串转换为js对象
案例
服务器响应的是json格式的字符串,注意使用Gson工具包。
@WebServlet("/WorldServlet")
public class WorldServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
List<User> list = new ArrayList<>();
list.add(new User(1, "段誉", 18, "大理"));
list.add(new User(2, "小龙女", 28, "燕国"));
Gson gson = new Gson();
String jsonStr = gson.toJson(list);
resp.getWriter().write(jsonStr);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script>
$(function(){
$('button').click(function () {
//创建ajax对象
var ajax = new XMLHttpRequest();
//编写回调函数
ajax.onreadystatechange = function () {
//ajax的就绪状态是4,服务器响应的状态是200
if(ajax.readyState == 4 && ajax.status == 200){
//获取响应数据
var data = ajax.responseText;
alert("服务器响应的json格式的字符串数据:" + data);
//使用eval函数将json格式的字符串转为js对象,后端传递的是list集合转为js对象后就是js中的数组了
eval("var arr = " + data);
//遍历js对象,该对象是一个数组
for(var i = 0; i < arr.length; i++){
alert(arr[i].id + "--" + arr[i].name + "--" + arr[i].age + "--" + arr[i].address);
}
}
}
//设置请求方式, 请求路径, 异步方式
ajax.open("get", "WorldServlet", true);
//发送请求
ajax.send();
});
})
</script>
</head>
<body>
<button>点我查看数据</button>
</body>
</html>
二、jQuery封装的Ajax使用
编写的Ajax代码访问服务器及对响应结果的处理流程
在页面编写Ajax相关代码
创建xhr对象
开启连接
发起请求
监听准备状态的变化
用户通过浏览器访问页面
用户在浏览器中触发事件,发起ajax请求
服务器收到请求进行处理,处理完后按照json格式的字符串响应给浏览器
浏览器收到响应数据后,触发回调函数的执行,将响应结果展示在当前的页面
jQuery是js的一个库,其实jQuery中已经对Ajax完成了封装
第一种:
$.ajax({
type:“请求方式”,
url:“请求地址”,
data:“请求参数”,
dataType:"服务器返回的数据类型"
success:fundction(data){ //成功且完整响应自动调用的函数
},
error: function(){ //出现错误自动调用的函数
}
})
dataType:用来指定服务器返回来的数据类型,可选值有如下:
xml:表示服务器返回的是xml内容
html:表示服务器返回的是html文本内容
script:表示服务器返回的是script文本内容
json:表示服务器返回的是json内容(重点)
jsonp:表示使用jsonp形式调用函数,早期我们用它来解决跨域问题
text:表示服务器返回的是纯文本字符串
第二种:
- $.get(“请求地址”,“请求参数”,回调函数, 返回的数据类型)
- $.post(“请求地址”,“请求参数”,回调函数, 返回的数据类型)
回调函数主要是用来处理服务器对我们的响应结果。
返回的数据类型这个参数用来设置服务器返回来的数据类型,可以是xml, html, script, json, text。
第三种:
- $.getJSON("请求地址", "请求参数", "回调函数")
这种方式要求服务器返回的数据类型得是json格式的。
第四种:
$.getScript("请求地址", "回调函数")
这种方式是发送ajax请求获取一个js文件。
案例
servlet
@WebServlet("/ThankServlet")
public class ThankServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("username:" + username);
System.out.println("password:" + password);
resp.getWriter().write("成功了!!!");
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script>
$(function(){
$('#btn1').click(function () {
$.get(
"ThankServlet",
{username:"admin", password:"123"},
function (data) {
$('div').text(data);
});
});
$('#btn2').click(function(){
$.post(
"ThankServlet",
{username:"tom", password:"789"},
function (data) {
$('div').text(data);
}
);
});
$('#btn3').click(function(){
$.ajax({
type: "post",
url: "ThankServlet",
data: "username=cat&password=369",
success: function (data) {
$('div').text(data);
},
dataType: "json"
});
});
$('#btn4').click(function () {
$.getJSON("ThankServlet",{username:"admin", password:"123"},function(data){
$('div').text(data);
});
});
$('#btn5').click(function () {
//在web目录下直接创建一个test.js文件,内容是alert(123)
$.getScript("test.js", function(){
alert("Script加载并执行成功!");
});
});
})
</script>
</head>
<body>
<button id="btn1">$.get()请求</button>
<button id="btn2">$.post()请求</button>
<button id="btn3">$.ajax()请求</button>
<button id="btn4">$.getJSON()请求</button>
<button id="btn5">$.getScript()请求</button>
<div></div>
</body>
</html>
三、Javaweb中路径的说明
1.JavaWeb中的路径
在JavaWeb中,路径分为相对路径和绝对路径两种:
相对路径:
./ 表示当前目录(可省略)
../ 表示当前文件所在目录的上一级目录
绝对路径:
http://ip:port/工程名/资源路径
2.在JavaWeb中/的不同含义
-
/ 斜杠 如果被浏览器解析,得到的地址是:http://ip:port/
-
<a href="/">斜杠</a>
-
<form action="/">
-
-
/ 斜杠 如果被服务器解析,得到的地址是:http://ip:port/工程路径/
-
<url-pattern>/Servlet1</url-pattern>
-
request.getRequestDispatcher(“/”)
-
-
特殊情况:response.sendRedirect(“”);把斜杆发给浏览器去解析,得到http://ip:port/
3.绝对路径和相对路径
1.绝对路径
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>b.html</h2>
<h3>绝对路径</h3>
<a href="http://localhost:8080/Ajax_war_exploded//a.html">a.html</a>
<br>
<a href="http://localhost:8080/Ajax_war_exploded/path/subPath/c.html">c.html</a>
<br>
<a href="http://localhost:8080/Ajax_war_exploded/testServlet">testServlet</a>
</body>
</html>
2.相对路径(相对于资源所在的目录)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>b.html</h2>
<h3>相对路径</h3>
<a href="../a.html">a.html</a>
<br>
<a href="./subPath/c.html">c.html</a>
<br>
<a href="../testServlet">testServlet</a>
</body>
</html>
3.相对路径(相对于项目目录)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>相对路径</h3>
<a href="/Ajax_war_exploded/a.html">a.html</a>
<br>
<a href="/Ajax_war_exploded/path/subPath/c.html">c.html</a>
<br>
<a href="/Ajax_war_exploded/testServlet">testServlet</a>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 使用base提取项目名 -->
<base href="/Ajax_war_exploded/">
</head>
<body>
<h2>b.html</h2>
<h3>相对路径</h3>
<a href="a.html">a.html</a>
<br>
<a href="path/subPath/c.html">c.html</a>
<br>
<a href="testServlet">testServlet</a>
</body>
</html>
4.jsp中获取项目路径
<!-- http://localhost:8080/项目名/ -->
${pageContext.request.contextPath}