一、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. 绝对路径和相对路径
- 绝对路径
<!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>
- 相对路径(相对于资源所在的目录)
<!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>
- 相对路径(相对于项目目录)
<!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}
二、AJAX
1. 目前浏览器和服务器交互的请求发送方式
浏览器和服务器进行数据交互的基本流程为:
-
浏览器发起http请求
-
服务器收到请求,对请求进行解析,创建请求和响应对象
-
服务器根据请求解析结果调用对应的资源处理请求
-
服务器将处理结果响应给浏览器
-
浏览器收到响应结果,对结果数据进行解析
-
浏览器将解析后的数据展示在页面
目前我们了解的可以让浏览器发送请求的方式有哪些?
- 在浏览器地址栏输入url地址后回车
- 使用超链接
- 使用form表单
- 在js代码中使用window.location.href(当前页面打开)
- 在js代码中使用window.open(新页面打开)
2. 目前的浏览器发送请求访问服务器方式存在的问题
问题:
浏览器发送请求访问服务器后,服务器收到请求调用对应的Servlet进行处理,然后使用resp.getWriter().print()方法的响应结果数据给浏览器,浏览器解析数据,将浏览器页面的内容覆盖掉后,展示解析出的数据!
但是在实际应用中,有时候我们希望新的响应结果是在原有界面内容的基础上继续进行显示,而不是新的响应结果直接覆盖了之前的内容!
解决:
解决上述问题,我们需要让浏览器使用一种新方式去发送请求访问服务器,然后这种用这种发送方式得到的响应结果不要覆盖原有内容,在之前内容基础上可以继续显示。
实现:
Ajax技术
3. Ajax的介绍和使用
3.1 介绍
概念:
Ajax(Asynchronous Javascript And XML)是由浏览器解析运行的基于JavaScript实现的网页局部刷新的技术。
作用:
实现了在当前网页中显示新的响应内容。(不会覆盖掉原有内容)
特点:
-
使用ajax发起的请求,响应结果不会自动的覆盖原有内容,而是可以在原有页面内容上继续显示
-
Ajax是一门基于JavaScript的技术,由浏览器解析运行,所以是一种前端(客户端)技术
-
简单易用
3.2 环境搭建
- 页面
<html>
<head>
<title>尚学堂散文</title>
<script type="text/javascript" src="jquery.js"></script>
<style>
h3 {
text-align: center;
}
div {
width: 600px;
margin: 0 auto;
border: 1px solid lightblue;
text-align: center;
background-color: lightcyan;
}
a {
color: green;
}
</style>
</head>
<body>
<h3>信任</h3>
<hr>
<div>
<p>
都说网络是虚拟的,这一点无可非议,但通过网络相互认识彼此成为知己的也大有人在,
因为网络给人们搭建了一个相互沟通、彼此了解的桥梁。不经意的邂逅,
就有可能让素昧平生的两个人彼此之间擦出爱的火花,那便是爱情里所说的心与心的相知中最美的交集。
</p>
<p>
人的一生何其短暂,如果有一个人肯花时间陪你,那是对你最深的在意。情与情的相牵,
是生命最美的遇见!“女人的幸福莫过于,他真的爱她;男人的幸福莫过于,她值得他爱。”
</p>
<p>
在现实生活中,没有一个人愿意,把时间浪费在他或她不喜欢的人身上。每个人的生命里,都有一个很特殊的日子,
这个日子和一个人有关,与一段故事有关。当时光驾驭的车辙在我们的心田碾过,那些刻骨铭心的印痕,
便被永远地珍藏在记忆的年轮里。
</p>
<p>
一个懂你的人,或许不是十全十美,却义无反顾地用他的生命来爱护你的生命。爱是大度无私的,是无怨无悔的,
更是发自内心的理智的欣赏。
</p>
<a id=”a“ href="javascript:void(0)">继续阅读↓</a>
<p id="pp">
</p>
</div>
</body>
</html>
- 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.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>
1. Ajax的就绪状态(readystate)
在ajax对象中提供了一个监听机制 “onreadystatechange”,用来监听ajax的属性readyState的改变情况,一旦该值改变,就会触发监听中的函数的执行。
readyState的值表示的含义:
0:请求没有开启(在调用open()之前)
1:请求已经建立但是还没有发出(调用send()之前)
2:请求已经发出,服务器正在处理
3:请求已经处理,响应中有数据可用,但是服务器还没有完全响应完
4:响应已经完成,浏览器已经接收到全部的响应内容
对我们来说,我们应该关注的是readyState是4时候的情况。
2. Ajax请求的响应状态
通过对ajax的就绪状态做判断,我们在就绪状态是4的情况下编写我们的对响应结果的处理逻辑代码,但是不是任何响应结果我们都要处理,因为服务器的响应也有状态码,比如:200、404、500等等。
所有我们在ajax中编写响应结果处理时,也必须考虑响应状态码。
3. 实现
<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请求对象
- 建立连接
- 发送连接
- 监听状态变化及结果处理
设置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");
}
}
- a标签通过href发送请求(同步请求)
<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请求和post请求及请求参数
使用Ajax可以发送请求,请求的常用方式是get和post。
6.1 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>
6.2 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>
7. Ajax请求的响应数据格式及处理(重点)
问题:
目前已经可以使用Ajax技术在浏览器发送请求以及对响应结果的简单处理。
通过上面的案例,我们知道,使用Ajax发送请求给服务器,服务器处理完请求后,不需要转发或者重定向,直接将结果打给浏览器即可,浏览器会触发回调函数完成响应结果的处理,服务器的响应结果只是一个简单的字符串数据。
解决:
可以使用json数据格式(特殊格式的字符串, 和js对象格式一致),它比较方便简单,而且也有好用的json工具包。所以,服务器响应Java对象数据给浏览器时,可以使用json字符串的格式,响应一个Java对象。
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工具包。
public class User {
private Integer id;
private String name;
private Integer age;
private String address;
public User() {
}
public User(Integer id, String name, Integer age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
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;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
@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格式的字符串响应给浏览器
-
浏览器收到响应数据后,触发回调函数的执行,将响应结果展示在当前的页面
在上述流程中,可以发现我们真正关注的是:
-
ajax的请求方式
-
ajax的请求地址
-
ajax的请求参数
-
ajax的回调函数
之前我们写的所有Ajax相关的代码案例,都是使用原生的js语言来编写的,比较繁琐。
我们知道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文件。