目錄
前言
概述
什么是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 默認是getdata: 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/4Time: 下午7:50To 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 {@Overrideprotected 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/4Time: 下午7:50To 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 {@Overrideprotected 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);} }
運行發現,成功!