目录
前言
概述
什么是Ajax?
同步交互与异步交互的区别是什么呢?
应用场景
场景1 在搜索框搜索 资源
场景2 登录业务的对用户名处理
AJAX的优缺点
优点:
缺点:
使用jQury 实现ajax
使用步骤
1 引入jQury 文件
2 使用Ajax 函数
$.ajax()
3 后端服务器,获得请求参数(重点)
那我们下一步学习如何将请求参数传递给后端服务器?
采用键值对的数据格式
采用json 数据格式
那么我们应该在后端servlet怎么获得 请求参数呢?
如果你采用键值对的方式,并且key 是不加双引号的
采用json 数据格式的方式
实例
前言
之前,我们进行前后端交互使用Servlet 中的重定向 和 请求转发 ,实现 前端界面的跳转( 刷新)。但是我们知道,无论是重定向还是请求转发,都是对整个界面的刷新。
这样有个坏处:
- 请求时间太长
- 我们希望只是局部进行交互,其他不变
因此本篇博客的核心:1 学习为什么要使用Ajax技术 2 怎么使用Ajax 技术做的局部刷新
概述
什么是Ajax?
Ajax是 使用js语言和服务器交互的一门技术。用于前端界面的局部刷新。如做登录业务时,用到的验证码;做搜索业务时,只有搜索框,是通过我们输入的关键词,通过模糊查询查找,整个界面的其他部分不动。
注意:这里的局部刷新,我们引申一个新的词 “ 异步”
同步交互与异步交互的区别是什么呢?
同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
应用场景
场景1 在搜索框搜索 资源
当我们在百度中输入一个“白”字后,会马上出现一个下拉列表!列表中显示的是包含“白”字的关键字。
其实这里就使用了AJAX技术!当文件框发生了输入变化时,浏览器会使用AJAX技术向服务器发送一个请求,查询包含“白”字的关键字,然后服务器会把查询到的结果响应给浏览器,最后浏览器把关键字显示在下拉列表中。
整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
场景2 登录业务的对用户名处理
当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为zhangSan的用户是否存在,最终服务器返回true表示名为zhangSan的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。
整个过程中页面没有刷新,只是局部刷新了;
在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;
AJAX的优缺点
优点:
AJAX使用Javascript技术向服务器发送异步请求;
AJAX无须刷新整个页面;
因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高;
缺点:
AJAX并不适合所有场景,很多时候还是要使用同步交互;
AJAX虽然提高了用户体验,但无形中向服务器发送的请求次数增多了,导致服务器压力增大;
因为AJAX是在浏览器中使用Javascript技术完成的,所以还需要处理浏览器兼容性问题;
使用jQury 实现ajax
为什么使用使用jQury 实现ajax?
原因: jQury 是JavaScript 的一个框架,并且这个框架封装好ajax ,当我们要使用Ajax 时,只需要调用专门的方法,就行了。
使用步骤
1 引入jQury 文件
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
注意:
引入的jQury 文件 最好是国内的,原因是如果从国外的服务器获得,使用这个jQury 文件速度比较慢
放的位置
script标签在 <head> </head> 中
2 使用Ajax 函数
$.ajax()
注意
- $.ajax()可以通过发送HTTP请求加载远程数据,是jQuery最底层的AJAX的实现,具有较高灵活性
- 在 AJAX 请求中,$ 符号通常指的是 jQuery 库的别名。jQuery 是一个非常流行的 JavaScript 库,它简化了 HTML 文档的遍历和操作、事件处理、动画和 Ajax 交互等任务
语法:
$.ajax([设置参数]);
常用设置参数如下:
参 数 说 明 String url 发送请求的地址,默认为当前页地址 String type 请求方式(POST或者GET,默认为GET) Number timeout 设置请求超时时间 Object data 或 String data 发送到服务器的数据 String dataType 预期服务器返回的数据类型,可用类型有:XML,HTML,Script,JSON,JSONP,Text function beforeSend(XMLHttpRequest xhr) 发送请求前调用的函数参数xhr,可选, XMLHttpRequest对象 function complete(XMLHttpRequest xhr,String ts) 请求完成后调用的函数(请求成功或失败时均调用)参数: xhr,可选, XMLHttpRequest对象, ts可选,描述请求类型的字符串 function success(Object result,String ts) 请求成功后调用的函数参数result:可选,由服务器返回的数据参数ts可选,描述请求类型的字符串 function error(XMLHttpRequest xhr,String em,Exception e) 请求失败时调用的函数参数: xhr,可选, XMLHttpRequest对象, 参数em可选,错误信息参数e:可选 ,捕获的异常对象 boolean global 默认为true,表示是否触发全局的AJAX事件 常用的参数:
- url:请求路径
- type:请求方式
contentType:指定请求体类型,一般和post 请求方式搭配使用- data:请求参数
- dataType :预计响应类型
- function success(Object result,String ts):请求成功调用success 方法,
- function error(XMLHttpRequest xhr,String em,Exception e):请求失败调用 error方法
这里大家可以回忆之前学习servlet 时,我们处理前端发来的请求,是不是需要知道,请求参数,请求方式,请求路径。
样例
<script> function test(){ let people ='{"name":"dj","password","123"}'; $.ajax({ url:"/login", //请求路径 type:"", //请求方式 :post /get 默认是get data: people, //请求参数 dataType:"json", // 预计的响应数据类型 success:function (data) { alert(data) } })} </script>
这里没有添加contenType 参数,原因是在本博客中的使用样例,都是比较简单的。如果你没有选择 会采用默认的请求体类型: application/x-www-form-urlencoded; charset=UTF-8
contentType:"application/json", 的应用场景是 请求体的请求参数是json 格式 的并且比较复杂,就使用。如果比较简单,就不写,使用默认也不会报错
3 后端服务器,获得请求参数(重点)
那我们下一步学习如何将请求参数传递给后端服务器?
重点
- 请求参数传递服务器Servlet 有两种数据格式
- 键值对的格式表示
- json 格式表示【重点掌握】
在之后的学习发现,因为使用键值对,存在局限性,因此对于请求参数,应该使用json 格式的
采用键值对的数据格式
键值对的格式表示,表示请求参数。我们知道键值对是 key-value 的方式
同时我们也要知道采用键值对的方式,其实就是 表示JavaScript中 对象字面量【对象】
因此写法:{ key :value} 或 {"key" value}
大家发现,采用键值对的方式,书写 请求参数,有两种:一个要加双引号,一个不用加双引号。
不使用双引号的键值对虽然也能正确表述 请求请求参数,
但这是有局限性的:
1 key 中存在特殊字符 如 -,*,...等
- 如 user-name等
2 key 表示具有特殊含义的字符,
- 如键名如果是class、for等JavaScript的保留字
这两种情况,如果不使用加双引号的是会报错的。
总结
- 键名未加双引号:在大多数情况下是有效的,但为了避免潜在的语法错误,建议加双引号。
- 键名加双引号:提高代码的可读性和一致性,特别是在键名包含特殊字符或与JavaScript保留字冲突的情况下
- 使用键值对的方式,一般只能适用于简单的请求参数,如果是复杂建议使用后面讲的json 数据格式
采用json 数据格式
这里我们要理解 两个词 json 格式的字符串, json 格式对象
格式
json 格式的对象
{" key" :value ,"key1" :value }
json 格式的字符串
'{" key" :value ,"key1" :value }'
注意:value 值可以是 字符串,数组,js对象,基本数据类型表示都可以
发现1
这两者的区别在于, 加了单引号,表示的是字符串。其实在JavaScript中 表示 字符串 除了使用 单引号表示,双引号也可以。但使用双引号 表示时,如果内部同样也使用双引号,那么就会提前结束。因此为了防止出现这个问题,就需要使用转义字符。但很显然使用转义字符会加重我们的负担。
发现2
我们看见json 格式的对象,其实就是我们之前说的采用键值对表示的JavaScript的对象字面量。我们这里直接就说js 对象。
了解
JavaScript 对象字面量与 JSON 格式的区别?【这个大家了解一下就好】
尽管JavaScript对象字面量和JSON格式在外观上非常相似,但它们之间存在一些重要的区别。以下是它们的主要区别:
1. 键名的引用方式
JavaScript 对象字面量:
键名可以不加双引号,只要它们是有效的JavaScript标识符。
例如:{ name: "张三" }
JSON:
键名必须用双引号括起来。
例如:{ "name": "张三" }
2. 值的类型
JavaScript 对象字面量:
值可以是任何有效的JavaScript数据类型,包括函数、日期、正则表达式等。
例如:{ name: "张三", sayHello: function() { console.log("你好"); } }
JSON:
值只能是字符串、数字、对象、数组、布尔值或 null。
例如:{ "name": "张三", "age": 25 }
3. 函数和日期
JavaScript 对象字面量:
可以包含函数和日期。
例如:{ name: "张三", birthDate: new Date("1990-01-01") }
JSON:
不允许包含函数和日期。
例如:{ "name": "张三", "birthDate": "1990-01-01" }上面的JavaScript对象字面量,我后面直接就说js 对象。如下图 则是这两种的关系
因此,我后面会将 使用双引号表示的key ,归类为 json 数据格式的,遵循json格式的一些规则。使用键值对格式只将会是不带双引号的key 。帮助理解!!
学习 js 对象和 json 格式的字符串的转换【重点】
JSON.stringify(js对象)
注意:这个方式是将js对象【JavaScript的字面量/json格式的对象,很大程度上 是同一个意思】 转成json 格式的字符串
JSON.parse(json 格式的字符串)
注意:这个方式是将 json 格式的字符串 【我们也可以看作 js 字符串。是一个意思】 转成 js对象
现在我们学会,要想把数据传递给后端服务器,要求数据格式是 键值对/ json 格式
那么我们应该在后端servlet怎么获得 请求参数呢?
如果你采用键值对的方式,并且key 是不加双引号的
后端servlet
通过调用HttpServletRequest 类型的对象 调用 getParameter( )
一般步骤
//设置请求编码 req.setCharacterEncoding("UTF-8"); //获取请求参数 String name = req.getParameter(" key"); // 设置响应编码 resp.setContentType("text/html; charset=UTF-8"); //输出 响应内容 resp.getWriter().println();
使用这种方式传递的请求参数,就像之前所说的局限性很大。即使不是含有特殊字符或是特殊含义的字符,也有可能出现问题,因此使用这种方式,只能是简单的请求参数传递。
因此我们一般采用第二种传递方式 使用json 数据格式的方式
采用json 数据格式的方式
我们传递都是json格式的字符串 ,
注意:如果是js对象的话,要通过调用stringify() 参数为js 对象 。转成js 字符串。
步骤
1 通过HttpServletRequest类型调用 getReader() 去读取的传递的请求参数
2 使用集合,还是StringBuffer 或StringBuilder 存储读到Json格式的字符串
3 解析json 格式的字符串
3.1 需要使用jar包
如果没有的,可以去maven中央仓库下载,在这里可以找到你需要的jar包
网址:https://mvnrepository.com/
3.2 调用parseObject (json格式字符串) 或 toJSONString(java 对象)
调用parseObject (json格式字符串)
static <T> T parseObject(String text, Class<T> clazz)
将json格式的字符串转成 对应的实体类对象
举例
有一个Person 实体类
使用 FastJSON jar 包的 parseObject 方法将 JSON 字符串转换为 Person 对象
Person person = JSON.parseObject(jsonString, Person.class);
调用toJSONString(java 对象)
static String toJSONString(Object object)
将对应的实体类对象,转成json 格式的字符串
举例
有一个Person 实体类
使用该方法将Person 实体类对象转成字符串
String jsonString = JSON.toJSONString(new Person());
实例
使用Ajax 技术写一个 用户框,当点击用户输入框 时,发送一个局部请求,把用户输入的用户名,传递给后端会向前端响应一个 “ 你好!”+你输入的用户名的弹框
注意:本实例中使用了 json 格式的字符串,当传递到Servlet 时,需要Json 解析器。
前端代码
<%-- Created by IntelliJ IDEA. User: djbootcdn.net/ajax/ Date: 2024/12/4 Time: 下午7:50 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> </head> <body> 用户名<input type="text" id="username" onclick="test()" required> <script> function test(){ let name = document.getElementById("username").value; $.ajax({ url:"/AServlet", type:"post", data:JSON.stringify({"username":name}), dataType:"text", success:function (data) { alert(data) } }) } </script> </body> </html>
后端代码
package fs.Servlet; import com.alibaba.fastjson2.JSON; 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.BufferedReader; import java.io.IOException; @WebServlet("/AServlet") public class AServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求参数 BufferedReader reader = req.getReader(); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line); } String name = JSON.parseObject(sb.toString()).getString("username"); System.out.println(name); //输出 resp.setContentType("text/html; charset=UTF-8"); resp.getWriter().println("你好," + name); } }
最后结果是成功的,通过我们输入的用户名,会弹出一个 你好+用户名的 弹框。
在这里使用 键值对的方式也是可以成功的
前端代码如下
注意:key 值可以随便设,但不能违背之前说的规则【是特殊含义的字符;包含特殊的符号,;上文使用到的,都不行】
<%-- Created by IntelliJ IDEA. User: djbootcdn.net/ajax/ Date: 2024/12/4 Time: 下午7:50 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> </head> <body> 用户名<input type="text" id="username" onclick="test()" required> <script> function test(){ let name = document.getElementById("username").value; $.ajax({ url:"/AServlet", type:"post", data: {name:name}, dataType:"text", success:function (data) { alert(data) } }) } </script> </body> </html>
后端代码
package fs.Servlet; import com.alibaba.fastjson2.JSON; import fs.entity.Student; 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.BufferedReader; import java.io.IOException; @WebServlet("/AServlet") public class AServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置请求编码 req.setCharacterEncoding("UTF-8"); //获取请求参数 String name = req.getParameter("name"); System.out.println(name); //输出 resp.setContentType("text/html; charset=UTF-8"); resp.getWriter().println("你好," + name); } }
运行发现,成功!