整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JSON&Ajax介紹和實例

          JSON&Ajax介紹和實例

          .JSON介紹

          1. JSON指的是JavaScript對象表示法( JavaScript Object Notation),JSON的本質仍然是JavaScript對象
          2. JSON是輕量級的文本數據交互格式,也是前后端進行數據通訊的一種格式:
          3. JSON獨立于語言,即java,PHP,asp.net,go等都可以使用json
          4. JSON具有自我描述性,更易理解。一句話,JSON很好用。

          2.JSON快速入門

          2.1JSON的定義格式

          var 變量名={    "k1":value,//Number類型    "k2":"str",//字符串類型    "k3":[],//數組類型    "k4":{},//json對象類型    "k5":[{},{}]//json數組};

          例子:

          var myJson={    "key1":1234,//Number類型    "key2":"Hello",//字符串類型    "key3":[1,"he llo",2.3],//數組類型    "key4":{"age":12,"name":"jack"},//json對象類型    "key5":[  //json數組        {"k1":10,"k2":"milan"},        {"k3":30,"k4":"smith"}    ]};

          2.2格式規則

          k-v形式,然后v中又可以嵌套k-v,并且每對k-v之間用逗號隔開

          1. 映射(元素/屬性)用冒號:表示,"名稱":值,注意名稱是字符串,因此要用雙引號括起來
          2. 并列的數據之間用逗號,分隔,如"名稱1":值,"名稱2":值
          3. 映射的集合(對象)用大括號{}表示,如{"名稱1":值,"名稱2":值}
          4. 并列數據的集合(數組)用方括號[]表示,如[{"名稱1":值,"名稱2":值},{"名稱1":值,"名稱2":值}]
          5. 元素值類型:string,number,object,array,true,false,null

          2.3入門案例

          <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>json快速入門案例</title>    <script type="text/javascript">        window.onload=function () {            /**             * myJson 就是一個json對象             */            var myJson={                "key1": 1234,//Number類型                "key2": "Hello",//字符串類型                "key3": [1, "hello", 2.3],//數組類型                "key4": {"age": 12, "name": "jack"},//json對象                "key5": [  //json數組                    {"k1": 10, "k2": "milan"},                    {"k3": 30, "k4": "smith"}                ]            };             // 演示如何獲取到json對象的各個屬性/key            // 1.取出key1            console.log("key1=", myJson.key1);            // 2.取出key3            //這里使用逗號來避免myJson.key3變成字符串            console.log("key3=", myJson.key3);            // 可以對key3取出的值(array)遍歷            for (var i=0; i < myJson.key3.length; i++) {                //使用下標取出數組的值                console.log("第%i個元素的值=", i, myJson.key3[i]);            }            //3.取出key4            console.log("key4=", myJson.key4)            console.log("key4.name=", myJson.key4.name)            //4.取出key5            console.log("key5=", myJson.key5)            console.log("取出key5的第二個數組的key4值=", myJson.key5[1].k4)        }    </script></head><body><h1>json快速入門案例</h1></body></html>

          打開瀏覽器控制臺,輸出如下:


          3.JSON對象和字符串對象轉換

          1. JSON.stringify(json):將一個json對象轉換成為json字符串
          2. JSON.parse(jsonString):將一個json字符串轉換成為json對象
          3. 轉換前提是傳入的字符串的格式必須滿足json格式

          3.1應用實例

          <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>JSON對象和字符串對象轉換</title>    <script type="text/javascript">        window.onload=function () {            //解讀JSON            //1.JSON是一個js的內置對象(build-in),可以直接使用,不需要創建            console.log(JSON);             //演示如何將一個JSON對象轉成-->String            var jsonPerson={                "name": "jack",                "age": 23            }            console.log("jsonPerson=", jsonPerson, " jsonPerson類型=", typeof jsonPerson);            var strPerson=JSON.stringify(jsonPerson);            console.log("strPerson=", strPerson, " strPerson類型=", typeof strPerson);             //演示如何將一個String對象轉成-->JSON            //注意轉成json對象的字符串格式必須滿足json格式            var strDog="{\"name\":\"小黃狗\",\"age\":2}";            var jsonDog=JSON.parse(strDog);            console.log("jsonDog=", jsonDog)        }    </script></head><body><h1>JSON對象和字符串對象轉換</h1></body></html>

          打開瀏覽器控制臺,輸出如下:

          3.2注意事項和細節

          1. JSON.stringify(json對象)會返回對應的string,并不會影響原來json對象
          2. JSON.parse(jsonString)方法會返回對應的json對象,并不會影響原來的string
          3. 在定義Json對象時,可以使用單引號''或者雙引號""表示字符串,甚至前面的key可以不用任何引號
          4. 比如var json_person={"name":"jack","age":100};
          5. 也可以寫成var json_person={'name':'jack','age':100};
          6. 或者是var json_person={name:"jack",age:100};
          7. 但是在把原生字符串轉成json對象時,必須使用雙引號"",否則會報錯
          8. JSON.springfiy(json對象)方法返回的字符串都是雙引號""表示的字符串,所以在語法格式正確的情況下,是可以重新轉成json對象的。

          例子

          <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>JSON和字符串轉換的注意事項和細節</title>    <script type="text/javascript">        window.onload=function () {            var jsonPerson={                "name": "jack",                "age": 22            }             //1.JSON.stringify(json對象)會返回對應的string,并不會影響原來json對象            var strPerson=JSON.stringify(jsonPerson);            console.log("jsonPerson=", jsonPerson);             //2.JSON.parse(jsonString)方法會返回對應的json對象,并不會影響原來的string            var strDog="{\"name\":\"小黃狗\",\"age\":2}";            var jsonDog=JSON.parse(strDog);            console.log("strDog=", strDog, "類型=", typeof strDog)             //3.在定義Json對象時,可以使用單引號或者雙引號表示字符串            // 甚至前面的key可以不用任何引號            var jsonCat={                name: '貓貓',                age: 2            }            console.log("jsonCat=", jsonCat);             //4.但是在把原生字符串轉成json對象時,必須使用雙引號"",否則會報錯            //例如:            var str_dog2="{name:'小黃狗',age:2}";            // JSON.parse(str_dog2);--報錯             //JSON.springfiy(json對象)返回的字符串都是雙引號`""`表示的字符串,            // 所以在語法格式正確的情況下,是可以重新轉成json對象的            var strCat=JSON.stringify(jsonCat);            var parse=JSON.parse(strCat);            console.log("parse=", parse)        }    </script></head><body><h1>JSON和字符串轉換的注意事項和細節</h1></body></html>

          打開瀏覽器控制臺,輸出如下:

          4.JSON在Java中使用

          前面講述的是前端頁面中json對象和字符串之間的轉化。在實際開發中,前端將json格式的字符串發送給后端,后端拿到后,可以將其轉成java對象,進行其他操作,并可以在業務操作后,重新向前端發送json格式的字符串。

          這意味著在Java后端中,同樣有對象和字符串對象轉換的需求。

          4.1說明

          1. Java中使用json,需要引入第三方的包 gson.jar
          2. Gson是Google提供的用來在Java對象和 JSON數據之間進行映射的Java類庫
          3. 可以對JSON字符串和Java對象相互轉換

          4.2JSON在Java中的應用場景

          1. Javabean對象和json字符串的相互轉換
          2. List對象和json字符串的相互轉換
          3. Map對象和json字符串的相互轉換

          4.3Java對象和JSON字符串互轉

          在項目中的lib目錄下將gson.jar文件復制過來,點擊add as library作為庫

          Javabean:Book類

          package com.li.json; //這是一個Javabeanpublic class Book {    private Integer id;    private String name;     public Book(Integer id, String name) {        this.id=id;        this.name=name;    }     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;    }     @Override    public String toString() {        return "Book{" +                "id=" + id +                ", name='" + name + '\'' +                '}';    }}

          JavaJson:

          package com.li.json; import com.google.gson.Gson; public class JavaJson {    public static void main(String[] args) {        //創建一個gson對象,作為一個工具對象使用        Gson gson=new Gson();         //演示Javabean和json格式字符串的轉換        Book book=new Book(10001, "三國演義");         //1.演示把一個Javabean轉成json格式的字符串        String strBook=gson.toJson(book);        System.out.println("strBook=" + strBook);         //2.json字符串-->JavaBean        //(1)strBook 就是json字符串        //(2)Book.class 指定將json字符串轉成Book類型的對象        //(3)底層使用反射機制來完成        Book book2=gson.fromJson(strBook, Book.class);        System.out.println("book2=" + book2);    }}

          4.4List對象和JSON字符串互轉

          Book類見4.3

          JavaJson:

          package com.li.json; import com.google.gson.Gson;import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type;import java.util.ArrayList;import java.util.List; public class JavaJson {    public static void main(String[] args) {        //創建一個gson對象,做為一個工具對象使用        Gson gson=new Gson();         //3.演示把List對象-->json字符串        ArrayList<Book> bookList=new ArrayList<>();        bookList.add(new Book(100, "天龍八部"));        bookList.add(new Book(200, "紅樓夢"));         //因為把一個對象或者集合轉成字符串,相對比較簡單        //底層只需要遍歷,按照json格式拼接返回即可        String strBookList=gson.toJson(bookList);        System.out.println("strBookList=" + strBookList);         //4.把json字符串轉成-->list對象        //(1)如果要把json字符串,轉成 集合 這種比較復雜的類型,需要使用Gson提供的一個類:TypeToken        //(2)這個TypeToken類在com.google.gson.reflect下面,在反射對象的時候使用        //(3)TypeToken 是一個自定義泛型類,通過TypeToken來指定我們需要轉換成的類型        /*         * public class TypeToken<T> {         *     final Class<? super T> rawType;         *     final Type type;         *     final int hashCode;         *         *     protected TypeToken() {         *         this.type=getSuperclassTypeParameter(this.getClass());         *         this.rawType=Types.getRawType(this.type);         *         this.hashCode=this.type.hashCode();         *     }         *     ...         *     ...         *  }         */          /*        TypeToken        (1)下面的語句new TypeToken<List<Book>>(){}.getType(),          返回類型的完整的路徑 java.util.List<com.li.json.Book>        (2)gson的設計者需要得到類型的完整路徑,然后進行底層的反射        (3)所以gson設計者提供了一個TypeToken類來搞定         */        Type type=new TypeToken<List<Book>>(){}.getType();        System.out.println(type.getClass());//class com.google.gson.internal.$Gson$Types$ParameterizedTypeImp         // System.out.println("type=" + type);//java.util.List<com.li.json.Book>         List<Book> bookList2=gson.fromJson(strBookList, type);        System.out.println("bookList2="+bookList2);    }}


          4.4.1TypeToken

          TypeToken類的作用是:得到類型的完整路徑,然后進行底層的反射

          Type type=new TypeToken<List<Book>>(){}.getType();

          一個問題,TypeToken為什么要加{}?

          1. 如果我們把下面語句中的 {} 去掉,會提示
            'TypeToken()' has protected access in 'com.google.gson.reflect.TypeToken'
          2. 因為TypeToken的無參構造器是protected的,而語句TypeToken<List<Book>>()就是調用其無參構造器。我們知道,如果一個方法是protected,并且和當前類不在同一個包,那么就沒有該方法的訪問權限,因此報錯。

          1. 那為什么加上{} ,就可以訪問了呢?這里涉及到匿名內部類的知識。
          2. 當我們這樣使用的時候:new TypeToken<List<Book>>(){} ,其實這個類型就不是TypeToken,而是一個匿名內部類(可以理解為TypeToken的一個子類)
          3. 而且這個匿名內部類有自己的無參構造器(隱式),根據java基礎,當執行子類的無參構造器時,默認調用super(); 到父類的無參構造器執行

          我們在Type type=new TypeToken<List<Book>>() {}.getType();處打上斷點,并在TypeToken類中的無參構造器旁也打上斷點。點擊debug,點擊Resume Program按鈕

          可以看到光標跳轉到TypeToken類中的無參構造器:

          再點擊step over,可以看到,type屬性拿到了類型的完整路徑,這樣才能去進行底層的反射

          4.4.2二說TypeToken

          我們用兩個類來模擬一下上述4.4.1的過程

          在src目錄下創建兩個包:t1和t2,在t1中創建一個A類,在t2中創建一個Test類

          A類:

          package com.li.t1; public class A<T> {    protected A() {        System.out.println("A 的protected A() 被調用...");    }}

          這時如果在Test類中new一個A類對象,那么將會報錯,原因就是被 protected 修飾的成員對于本包和其子類可見。而A和Test類既不在同一個包,也不是繼承關系。這和4.4.1報錯的原因完全一致。

          實際上,protected的可見性在于兩點:1.基類的 protected 成員是包內可見的,并且對子類可見;2.若子類與基類不在同一包中,那么在子類中,子類實例可以訪問其從基類繼承而來的protected方法,而不能訪問基類實例的protected方法。

          Java protected 關鍵字詳解 | 菜鳥教程 (runoob.com)

          package com.li.t2; import com.li.t1.A; public class Test {    public static void main(String[] args) {        A a=new A<String>() {};        //1.因為A類和Test類不在同一個包,也不是繼承關系,不能訪問A的protected成員,包括構造器        //2. A(){}就是一個匿名內部類,可以理解成A的子類        //3. A(){} 有一個隱式的無參構造器,會調用super()        //4. 當你執行 new A(){} 時,會調用A類的 protected無參構造器        // 泛型+匿名內部類        System.out.println(a.getClass());//class com.li.t2.Test    }}

          4.5Map對象和JSON字符串互轉

          Book類見4.3

          JavaJson:

          package com.li.json; import com.google.gson.Gson;import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; public class JavaJson {    public static void main(String[] args) {        //創建一個gson對象,做為一個工具對象使用        Gson gson=new Gson();         //5.把map對象轉成-->json字符串        HashMap<String, Book> bookMap=new HashMap<>();        bookMap.put("k1", new Book(400, "射雕英雄傳"));        bookMap.put("k2", new Book(500, "楚留香傳奇"));        String strBookMap=gson.toJson(bookMap);        System.out.println("strBookMap=" + strBookMap);         //6.json字符串轉成-->map對象        //new TypeToken<Map<String,Book>>(){}.getType()        //===> java.util.Map<java.lang.String, com.li.json.Book>        Map<String,Book> bookMap2=gson.fromJson(strBookMap,                new TypeToken<Map<String,Book>>(){}.getType());        System.out.println(bookMap2);    }}

          1.Ajax基本介紹

          1.1Ajax是什么

          1. AJAX 即“Asynchronous JavaScript And XML”(異步JavaScript和XML)
          2. Ajax 是一種瀏覽器異步發起請求(指定發哪些數據),局部更新頁面的技術
          3. 傳統的網頁(不使用 AJAX)如果需要更新內容,必需重載整個網頁面。而使用Ajax,通過在后臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。
          4. 傳統的網頁(不使用 AJAX),如果沒有得到服務器的響應,瀏覽器程序會處于一個等待掛起的狀態,無法執行其他操作,直至得到http響應。

          1.2Ajax經典應用場景

          1. 搜索引擎根據用戶輸入關鍵字,自動提示檢索關鍵字
          2. 動態加載數據,按需取得數據 [樹形菜單,聯動菜單]
          3. 改善用戶體驗 [輸入內容前提示,帶進度條文件上傳]
          4. 電子商務應用 [購物車,郵件訂閱]
          5. 訪問第三方服務 [訪問搜索服務,rss閱讀器]
          6. 頁面局部刷新
          • Ajax的三個特點異步請求發送指定數據局部刷新

          2.Ajax原理示意圖

          2.1傳統的web應用數據通信方式

          傳統web應用數據通信方式

          1. 瀏覽器發出http請求(攜帶數據username=xxx&pwd=xxx)
          2. 服務端接收數據,并處理
          3. 通過http響應,把數據返回給瀏覽器

          缺點:

          1. 表單提交是把該表單的所有數據都提交給服務端,數據量大,沒有意義
          2. 在服務端沒有響應前,瀏覽器前端頁面處于等待狀態,處于一個掛起的狀態
          3. 不能進行局部刷新頁面,而是刷新整個頁面

          2.2Ajax數據通信方式

          Ajax數據通信方式:

          1. 瀏覽器發出http請求,使用XMLHttpRequest對象
          2. 服務端接收數據,并處理
          3. 通過http響應,把數據返回給瀏覽器(返回的數據格式可以多樣 如json,xml,普通文本)

          優點:

          1. 可以通過XMLHttpReques對象,發送指定數據,數據量小,速度快
          2. XMLHttpReques是異步發送,在服務端沒有Http響應前,瀏覽器不需要等待,用戶可以進行其他操作
          3. 可以進行局部刷新,提高了用戶體驗

          3.JavaScript原生Ajax請求

          3.1Ajax文檔

          AJAX - XMLHttpRequest 對象 (w3school.com.cn)

          • onreadystatechange 事件

          當請求被發送到服務器時,我們需要執行一些基于響應的任務。

          每當 readyState 改變時,就會觸發 onreadystatechange 事件。

          readyState 屬性存有 XMLHttpRequest 的狀態信息。

          下面是 XMLHttpRequest 對象的三個重要的屬性:

          在 onreadystatechange 事件中,我們規定當服務器響應已做好被處理的準備時所執行的任務。

          3.2應用實例

          演示JavaScript發送原生Ajax請求的案例

          1. 在輸入框輸入用戶名
          2. 點擊驗證用戶名,使用ajax方式,服務端驗證該用戶名是否已經被占用,如果已經被占用,以json格式返回該用戶信息
          3. 假定用戶名為king,就不可用,其他用戶名可以(后面我們接入DB)
          4. 對頁面進行局部刷新,顯示返回信息
          5. 思考:為什么直接返回用戶名是否可用信息?==>為什么返回json格式的字符串?
          6. 可以根據返回的json可以做更多的業務操作。

          思路


          1. 首先創建一個新項目,添加web支持(暫時不使用maven)
          2. 在web-inf文件夾下添加lib目錄,添加servlet和json的相關jar包
          3. 配置Tomcat服務器
          4. 創建login.html,使用ajax
          5. 大致的流程是:用戶點擊驗證用戶名按鈕后,操作dom獲取填寫的用戶名,然后創建XMLHttpRequest對象[ajax引擎對象],調用XMLHttpRequest 對象的 open() 和 send() 方法
          6. 在open中設置三個參數:1.請求方式、2.請求url(如果是get請求,url需包括請求參數)、3.是否使用異步發送
          7. 給XMLHttpRequest對象綁定一個事件onreadystatechange,該事件的觸發時機是XMLHttpRequest的readyState狀態改變。
          8. readyState狀態詳見:AJAX - 服務器響應 (w3school.com.cn)
          9. 然后調用send方法真正發送ajax請求(如果是post請求,參數就是在send方法中設置)
          10. 根據readyState的狀態判斷請求已完成且響應已就緒,然后進行業務操作。
          <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>用戶注冊</title>    <script type="text/javascript">        window.onload=function () {//頁面加載完畢后執行function            var checkButton=document.getElementById("checkButton");            checkButton.onclick=function () {                //1.創建XMLHttpRequest對象[ajax引擎對象]                var xhr=new XMLHttpRequest();                 //2.準備發送指定數據                // 2.1獲取用戶填寫的用戶名                var username=document.getElementById("uname").value;                 // 2.2XMLHttpRequest 對象的 open() 和 send() 方法                // (1)"GET" 請求方式,也可以是post                // (2)"/ajax/checkUserServlet?username="+username 就是url                // (3) true表示異步發送                xhr.open("GET", "/ajax/checkUserServlet?username=" + username, true);                 //2.3在send方法調用前,給XMLHttpRequest對象綁定一個事件==>onreadystatechange                //每當XMLHttpRequest對象的 readyState 改變時,就會觸發 onreadystatechange 事件                xhr.onreadystatechange=function () {                    //如果請求已完成,并且響應已經就緒,并且狀態碼是200                    if (xhr.readyState==4 && xhr.status==200) {                        //把返回的json數據顯示在div上                        document.getElementById("div1").innerText=xhr.responseText;                        // console.log("xhr=", xhr);                        //處理XMLHttpRequest對象中拿到的數據                        var responseText=xhr.responseText;                        // console.log("返回的信息="+responseText);                        if (responseText !="") {                            //根據在servlet設置的邏輯,如果返回的數據不是空串,說明該用戶名不可用                            document.getElementById("myres").value="用戶名不可用";                        } else {                            document.getElementById("myres").value="用戶名可用";                        }                     }                }                                //2.4真正發送ajax請求[底層還是http請求]                //如果前面open的第一個參數指定的是post請求,那么post的參數在send中指定                //如果open的第一個參數指定的是get請求,那么send中不需要寫任何數據,因為前面已經在url中指定了                xhr.send();            }        }    </script></head><body><h1>用戶注冊</h1><form action="/ajax/checkUserServlet" method="post">    用戶名字:<input type="text" name="username" id="uname">    <input type="button" id="checkButton" value="驗證用戶名">    <input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>    用戶密碼:<input type="password" name="password"><br/><br/>    電子郵件:<input type="text" name="email"><br/><br/>    <input type="submit" value="用戶注冊"></form><h1>返回的 json 數據</h1><div id="div1"></div></body></html>
          1. 在web.xml中配置servlet
          <?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"         version="4.0">    <servlet>        <servlet-name>CheckUserServlet</servlet-name>        <servlet-class>com.li.ajax.servlet.CheckUserServlet</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>CheckUserServlet</servlet-name>        <url-pattern>/checkUserServlet</url-pattern>    </servlet-mapping></web-app>
          1. CheckUserServlet:如果接收到的用戶名為king,就將其信息以json形式返回前端頁面,如果是其他名字,就返回空串。
          package com.li.ajax.servlet; import com.google.gson.Gson;import com.li.ajax.entity.User; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException;import java.io.PrintWriter; public class CheckUserServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        doPost(request, response);    }     @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //System.out.println("CheckUserServlet 被調用...");         //接收ajax提交的數據        request.setCharacterEncoding("utf-8");        response.setContentType("text/html;charset=utf-8");        String username=request.getParameter("username");//參數名取決于url中的參數名        System.out.println("uname=" + username);         //如果用戶名為king,就認為是不可用的        if ("king".equals(username)) {//假定king已經有人使用了             //后面這個信息是從數據庫db來獲取的            User king=new User(100, "king", "6666", "king@qq.com");            //把king 對象轉成 json 格式的字符串            String strKing=new Gson().toJson(king);            //返回信息            response.getWriter().print(strKing);        } else {            //如果用戶名可用,返回空串即可            response.getWriter().print("");        }    }}
          1. Javabean,為了完成對象-->json字符串的需求
          package com.li.ajax.entity; /** * User類就是一個Javabean/pojo/entity/domain */public class User {    private Integer id;    private String name;    private String pwd;    private String email;     public User(Integer id, String name, String pwd, String email) {        this.id=id;        this.name=name;        this.pwd=pwd;        this.email=email;    }     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 String getPwd() {        return pwd;    }     public void setPwd(String pwd) {        this.pwd=pwd;    }     public String getEmail() {        return email;    }     public void setEmail(String email) {        this.email=email;    }}

          3.3練習

          需求分析:到數據庫中驗證用戶名是否可用

          1. 點擊驗證用戶名,到數據庫中驗證用戶名是否可用
          2. 自己設計創建數據庫ajaxdb,創建users表
          3. 使用ajax方式,服務端驗證該用戶名是否已經被占用了,若已經被占用,以json格式返回該用戶信息
          4. 對頁面進行局部刷新,顯示返回信息
          5. 提示:[Mysql+JDBC+數據庫連接池]

          只需在前面的應用實例中進行升級改進,接入DB

          項目的整體架構:

          3.3.1創建數據庫表格

          # 創建數據庫CREATE DATABASE ajaxdb;# 創建users表CREATE TABLE `user` ( id INT(11) PRIMARY KEY, `username` VARCHAR(32) UNIQUE NOT NULL DEFAULT '', pwd CHAR(32) NOT NULL DEFAULT '', email VARCHAR(32) NOT NULL DEFAULT '')CHARSET utf8 COLLATE utf8_bin ENGINE INNODB; #插入測試數據INSERT INTO `user` VALUES(100,"king",MD5('123'),"king@qq.com");INSERT INTO `user` VALUES(200,"queen",MD5('666'),"queen@qq.com");INSERT INTO `user` VALUES(300,"princess",MD5('999'),"princess@163.com"); SELECT * FROM `user`;DESC `user`;#drop table `user`; #完成的工作SELECT COUNT(*) FROM `user` WHERE `username`="king"

          3.3.2創建工具類JdbcUtilsByDruid

          在項目的lib庫下添加德魯伊,Apache-DBUtils,mysql-connect數據庫連接驅動

          數據庫連接池詳見:javase基礎-jdbc和數據庫連接池

          在項目src目錄下添加德魯伊配置文件

          #key=valuedriverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/ajaxdb?rewriteBatchedStatements=trueusername=rootpassword=123456#initial connection SizeinitialSize=10#min idle connecton sizeminIdle=5#max active connection sizemaxActive=20#max wait time (5000 mil seconds)maxWait=5000

          創建德魯伊工具類JDBCUtilsByDruid

          package com.li.ajax.utils; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource;import java.sql.*;import java.util.Properties; /** * 基于Druid數據庫連接池的工具類 */public class JDBCUtilsByDruid {     private static DataSource ds;     //在靜態代碼塊完成ds的初始化    //靜態代碼塊在加載類的時候只會執行一次,因此數據源也只會初始化一次    static {        Properties properties=new Properties();        try {            /**             * 注意,目前我們是javaweb方式啟動             * 在web項目下要得到資源文件,需要使用類加載器,             * 得到它真正執行的目錄下的out/artifacts/項目名/WEB-INF/classes目錄中的資源             */            properties.load(JDBCUtilsByDruid.class.getClassLoader()                    .getResourceAsStream("druid.properties"));            //方式二:也可以使用絕對路徑            //properties.load(new FileInputStream("D:\IDEA-workspace\ajax\src\druid.properties"));            ds=DruidDataSourceFactory.createDataSource(properties);        } catch (Exception e) {            e.printStackTrace();        }    }     //編寫getConnection方法    public static Connection getConnection() throws SQLException {        return ds.getConnection();    }     //關閉連接(注意:在數據庫連接池技術中,close不是真的關閉連接,而是將Connection對象放回連接池中)    public static void close(ResultSet resultSet, Statement statemenat, Connection connection) {        try {            if (resultSet !=null) {                resultSet.close();            }            if (statemenat !=null) {                statemenat.close();            }            if (connection !=null) {                connection.close();            }        } catch (SQLException e) {            throw new RuntimeException(e);        }    }}

          3.3.3BaseDAO

          package com.li.ajax.dao; import com.li.ajax.utils.JDBCUtilsByDruid;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler; import java.sql.*; /** * 開發BasicDAO,是其他DAO的父類 */public class BaseDAO<T> {//泛型指定具體的類型     private QueryRunner queryRunner=new QueryRunner();     //查詢單行結果 的通用方法(單行多列)    public T querySingle(String sql, Class<T> clazz, Object... parameters) {        Connection connection=null;        try {            connection=JDBCUtilsByDruid.getConnection();            return queryRunner.query(connection, sql, new BeanHandler<T>(clazz), parameters);         } catch (SQLException e) {            throw new RuntimeException(e);//將一個編譯異常轉變為運行異常        } finally {            JDBCUtilsByDruid.close(null, null, connection);        }    }     //根據業務需求還可以有多行多列查詢,單行多列插敘,單行單列查詢等    //這里不再列舉,詳見javase基礎-滿漢樓BasicDAO}

          3.3.4User類

          修改3.2中的Javabean--User類

          package com.li.ajax.entity; /** * User類就是一個Javabean/pojo/entity/domain */public class User {    private Integer id;    private String username;    private String pwd;    private String email;     public User() {//注意,一定要有一個空的構造器,方便底層進行反射??!    }     public User(Integer id, String username, String pwd, String email) {        this.id=id;        this.username=username;        this.pwd=pwd;        this.email=email;    }     public Integer getId() {        return id;    }     public void setId(Integer id) {        this.id=id;    }     public String getUsername() {        return username;    }     public void setUsername(String username) {        this.username=username;    }     public String getPwd() {        return pwd;    }     public void setPwd(String pwd) {        this.pwd=pwd;    }     public String getEmail() {        return email;    }     public void setEmail(String email) {        this.email=email;    }     @Override    public String toString() {        return "User{" +                "id=" + id +                ", username='" + username + '\'' +                ", pwd='" + pwd + '\'' +                ", email='" + email + '\'' +                '}';    }}

          3.3.5UserDAO

          package com.li.ajax.dao; import com.li.ajax.entity.User; /** * 對user表的增刪查改 */public class UserDAO extends BaseDAO<User> {    //我們的UserDAO繼承了BasicDAO,并指定了User    //這時我們就可以使用BasicDAO中的方法}

          3.3.6UserService

          package com.li.ajax.service; import com.li.ajax.dao.UserDAO;import com.li.ajax.entity.User;import org.testng.annotations.Test; import java.sql.SQLException; /** * UserService 提供業務方法 */public class UserService {    //添加屬性UserDAO,方便操作    private UserDAO userDAO=new UserDAO();     //根據用戶名返回對應的user對象,如果沒有則返回null    @Test    public User getUserByName(String username) throws SQLException {        //使用 User.class 的目的是底層反射創建對象,而反射是調用的無參構造器去創建類,        // 因此在對應的實體類中一定要有無參構造器?。。?       User user=      userDAO.querySingle("SELECT * FROM `user` WHERE `username`=?", User.class, username);        return user;    }}

          3.3.7CheckUserServlet

          package com.li.ajax.servlet; import com.google.gson.Gson;import com.li.ajax.entity.User;import com.li.ajax.service.UserService; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException;import java.sql.SQLException; public class CheckUserServlet extends HttpServlet {    //定義一個UserService屬性    private UserService userService=new UserService();     @Override    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        doPost(request, response);    }     @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //System.out.println("CheckUserServlet 被調用...");         //接收ajax提交的數據        request.setCharacterEncoding("utf-8");        response.setContentType("text/html;charset=utf-8");        String username=request.getParameter("username");//參數名取決于url中的參數名        System.out.println("uname=" + username);         //從數據庫中查找有無相同的用戶名        try {            User userByName=userService.getUserByName(username);            if (userByName !=null) {//說明用戶名存在                // 返回該User對象的json格式的字符串                String strUser=new Gson().toJson(userByName);                //給瀏覽器返回信息                response.getWriter().print(strUser);            } else {                //如果返回了null,說明沒有重名的用戶                //用戶名可用,返回空串即可                response.getWriter().print("");            }        } catch (SQLException e) {            e.printStackTrace();        }    }}

          3.3.8login.html

          詳見3.2應用實例

          3.3.9測試

          重啟Tomcat,在瀏覽器中訪問http://localhost:8080/ajax/login.html

          4.jQuery的Ajax請求

          原生Ajax請求問題分析:

          1. 編寫原生的Ajax要寫很多的代碼,還要考慮瀏覽器兼容問題,使用不方便
          2. 在實際工作中,一般使用JavaScript的框架(比如jquery)發動Ajax請求,從而解決這個問題。

          4.1jQuery Ajax操作方法

          在線文檔:jQuery 參考手冊 - Ajax (w3school.com.cn)

          4.2$.ajax()方法

          完整的參數查看手冊:jQuery ajax - ajax() 方法

          $.ajax 常用參數:

          • url:請求的地址
          • type:請求的方式get或者post, 默認為 "GET"。
          • 注意:其它 HTTP 請求方法,如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支持。
          • data:發送到服務器的數據,將自動轉換為請求字符串格式
          • success:請求成功后的回調函數
          • 參數:由服務器返回,并根據 dataType 參數進行處理后的數據;描述狀態的字符串。
          • 這是一個 Ajax 事件。
          • error:默認值: 自動判斷 (xml 或 html),請求失敗時的回調函數。
          • dataType:指定返回的數據類型,常用json或text

          4.3$.get()和$.post()請求

          jQuery AJAX get() 和 post() 方法

          $.get()請求和$.post()請求常用參數:

          • url:請求的url地址
          • data:請求發送到服務器的數據
          • success:成功時的回調函數
          • type:返回內容的格式,xml,html,script,json,text

          說明:$.get()$.post()底層還是使用$.ajax()方法來實現異步請求

          4.3.1$.get()

          get() 方法通過遠程 HTTP GET 請求載入信息

          這是一個簡單的 GET 請求功能以取代復雜 $.ajax,請求成功時可調用回調函數。如果需要在出錯時執行函數,請使用 $.ajax().

          語法:

          $(selector).get(url,data,success(response,status,xhr),dataType)
          

          4.3.2$.post()

          post() 方法通過 HTTP POST 請求從服務器載入數據。

          語法:

          jQuery.post(url,data,success(data, textStatus, jqXHR),dataType)
          

          4.4$.getJSON()方法

          jQuery ajax - getJSON() 方法

          $.getJSON()常用參數

          • url:請求發送哪個url
          • data:請求發送到服務器的數據
          • success:請求成功時運行的函數

          說明:$.getJSON()底層使用$.ajax()方法來實現異步請求

          $.getJSON()方法通過 HTTP GET 請求載入 JSON 數據,語法:

          jQuery.getJSON(url,data,success(data,status,xhr))
          

          4.5應用實例

          4.5.1$.ajax()應用實例

          演示jquery發送ajax的案例

          1. 在輸入框輸入用戶名
          2. 點擊驗證用戶名,服務端驗證該用戶是否已經占用了,如果是,則以json格式返回該用戶信息
          3. 假定king為已使用的用戶名
          4. 對頁面進行局部刷新,顯示返回的信息

          思路分析:直接參考3.2的思路圖即可


          引入jquery庫:

          注意:如果有的資源是拷貝進來的,有時候運行目錄out沒有及時更新,這時可以點擊Rebuild Project,如果不行就redeploy Tomcat

          配置servlet:

          <servlet>
              <servlet-name>CheckUserServlet2</servlet-name>
              <servlet-class>com.li.ajax.servlet.CheckUserServlet2</servlet-class>
          </servlet>
          <servlet-mapping>
              <servlet-name>CheckUserServlet2</servlet-name>
              <url-pattern>/checkUserServlet2</url-pattern>
          </servlet-mapping>
          

          創建CheckUserServlet2:

          package com.li.ajax.servlet;
          
          import com.google.gson.Gson;
          import com.li.ajax.entity.User;
          
          import javax.servlet.*;
          import javax.servlet.http.*;
          import java.io.IOException;
          
          public class CheckUserServlet2 extends HttpServlet {
              @Override
              protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  doPost(request, response);
              }
          
              @Override
              protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  //接收jquery發送的ajax數據
                  String username=request.getParameter("username");//參數名取決于前端的參數名
          
                  response.setContentType("text/json;charset=utf-8");//指定MIME類型為json
          
                  Gson gson=new Gson();
                  if ("king".equals(username)) {
                      //后面可以接入數據庫database
                      User user=new User(100, "king", "123", "king@163.com");
                      response.getWriter().print(gson.toJson(user));
                  } else {
                      //返回一個不存在的User-->測試
                      User user=new User(-1, "", "", "");
                      response.getWriter().print(gson.toJson(user));
                  }
              }
          }
          

          login2.html:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>用戶注冊</title>
              <!--    引入jquery-->
              <script type="text/javascript" src="./script/jquery-3.6.1.min.js"></script>
              <script type="text/javascript">
                  $(function () {
                      //綁定事件
                      $("#btn1").click(function () {
                          //發出ajax請求
                          /**
                           * 1.指定參數時,需要在{}里面
                           * 2.指定參數時,需要指定參數名
                           * 3.dataType:"json" 代表要求服務器返回的數據是json,
                           *          如果服務器返回的不是json,就會解析出錯
                           */
                          $.ajax({
                              url: "/ajax/checkUserServlet2",
                              type: "post",
                              data: {//這里我們直接給一個json
                                  username: $("#uname").val(),
                                  date : new Date()//防止瀏覽器緩存
                              },
                              error:function () {//失敗后的回調函數
                                  console.log("失敗")
                              },
                              success:function (data,status,xhr) {
                                  console.log("成功");
                                  console.log("data=",data);
                                  console.log("status=",status);
                                  console.log("xhr=",xhr);
                                  //data是一個json對象,需要轉成json字符串
                                  $("#div1").html(JSON.stringify(data));
                                  //對返回的結果進行處理
                                  if (""==data.username){//說明用戶名可用
                                      $("#myres").val("該用戶名可用");
                                  }else {
                                      $("#myres").val("該用戶名不可用");
                                  }
                              },
                              dataType:"json"
                          })
                      })
                  })
              </script>
          </head>
          <body>
          <h1>用戶注冊-Jquery+Ajax</h1>
          <form action="/ajax/checkUserServlet2" method="post">
              用戶名字:<input type="text" name="username" id="uname">
              <input type="button" id="btn1" value="驗證用戶名">
              <input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>
              用戶密碼:<input type="password" name="password"><br/><br/>
              電子郵件:<input type="text" name="email"><br/><br/>
              <input type="submit" value="用戶注冊">
          </form>
          <h1>返回的 json 數據</h1>
          <div id="div1"></div>
          </body>
          </html>
          

          4.5.2$.get()應用實例

          使用4.5的應用實例,將上面的html頁面改寫,其他不變。

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>用戶注冊</title>
              <!--    引入jquery-->
              <script type="text/javascript" src="./script/jquery-3.6.1.min.js"></script>
              <script type="text/javascript">
                  $(function () {
                      //綁定事件
                      $("#btn1").click(function () {
                          //演示$.get()使用
                          // $.get()默認是get請求,不需要指定請求方式
                          //不需要寫參數名,但是參數的位置要正確對應,
                          // 順序是:url,data,success回調函數,返回的數據格式
                          $.get(
                              "/ajax/checkUserServlet2",
                              {//這里我們直接給一個json
                                  username: $("#uname").val(),
                                  date: new Date()//防止瀏覽器緩存
                              },
                              function (data, status, xhr) {
                                  console.log("$.get成功")
                                  console.log("data=", data);
                                  console.log("status=", status);
                                  console.log("xhr=", xhr);
                                  //data是一個json對象,需要轉成json字符串
                                  $("#div1").html(JSON.stringify(data));
                                  //對返回的結果進行處理
                                  if (""==data.username) {//說明用戶名可用
                                      $("#myres").val("該用戶名可用");
                                  } else {
                                      $("#myres").val("該用戶名不可用");
                                  }
                              },
                              "json"
                          )
                      })
                  })
              </script>
          </head>
          <body>
          <h1>用戶注冊-Jquery+Ajax</h1>
          <form action="/ajax/checkUserServlet2" method="post">
              用戶名字:<input type="text" name="username" id="uname">
              <input type="button" id="btn1" value="驗證用戶名">
              <input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>
              用戶密碼:<input type="password" name="password"><br/><br/>
              電子郵件:<input type="text" name="email"><br/><br/>
              <input type="submit" value="用戶注冊">
          </form>
          <h1>返回的 json 數據</h1>
          <div id="div1"></div>
          </body>
          </html>
          

          4.5.3$.post()應用實例

          使用4.5的應用實例,將上面的html頁面改寫,其他不變。

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>用戶注冊</title>
              <!-- 引入jquery-->
              <script type="text/javascript" src="./script/jquery-3.6.1.min.js"></script>
              <script type="text/javascript">
                  $(function () {
                      //綁定事件
                      $("#btn1").click(function () {
                          //$.post 和 $.get的調用方式基本一樣,只是這時是以post方式發送ajax請求
                          $.post(
                              "/ajax/checkUserServlet2",
                              {//這里我們直接給一個json
                                  username: $("#uname").val(),
                                  date: new Date()//防止瀏覽器緩存
                              },
                              function (data, status, xhr) {
                                  console.log("$.post成功")
                                  console.log("data=", data);
                                  console.log("status=", status);
                                  console.log("xhr=", xhr);
                                  //data是一個json對象,需要轉成json字符串
                                  $("#div1").html(JSON.stringify(data));
                                  //對返回的結果進行處理
                                  if (""==data.username) {//說明用戶名可用
                                      $("#myres").val("該用戶名可用");
                                  } else {
                                      $("#myres").val("該用戶名不可用");
                                  }
                              },
                              "json"
                          )
                      })
                  })
              </script>
          </head>
          <body>
          <h1>用戶注冊-Jquery+Ajax</h1>
          <form action="/ajax/checkUserServlet2" method="post">
              用戶名字:<input type="text" name="username" id="uname">
              <input type="button" id="btn1" value="驗證用戶名">
              <input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>
              用戶密碼:<input type="password" name="password"><br/><br/>
              電子郵件:<input type="text" name="email"><br/><br/>
              <input type="submit" value="用戶注冊">
          </form>
          <h1>返回的 json 數據</h1>
          <div id="div1"></div>
          </body>
          </html>
          

          4.5.4$.getJSON()應用實例

          使用4.5的應用實例,將上面的html頁面改寫,其他不變。

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>用戶注冊</title>
              <!--    引入jquery-->
              <script type="text/javascript" src="./script/jquery-3.6.1.min.js"></script>
              <script type="text/javascript">
                  $(function () {
                      //綁定事件
                      $("#btn1").click(function () {
                          //如果你通過jquery發出的ajax請求是get請求,并且返回的數據格式是json,
                          // 可以直接使用getJSON()函數,很方便
                          $.getJSON(
                              "/ajax/checkUserServlet2",
                              {//這里我們直接給一個json
                                  username: $("#uname").val(),
                                  date: new Date()//防止瀏覽器緩存
                              },
                              function (data, status, xhr) {//成功后的回調函數
                                  console.log("$.getJSON成功")
                                  console.log("data=", data);
                                  console.log("status=", status);
                                  console.log("xhr=", xhr);
                                  //data是一個json對象,需要轉成json字符串
                                  $("#div1").html(JSON.stringify(data));
                                  //對返回的結果進行處理
                                  if (""==data.username) {//說明用戶名可用
                                      $("#myres").val("該用戶名可用");
                                  } else {
                                      $("#myres").val("該用戶名不可用");
                                  }
                              }
                          )
                      })
                  })
              </script>
          </head>
          <body>
          <h1>用戶注冊-Jquery+Ajax</h1>
          <form action="/ajax/checkUserServlet2" method="post">
              用戶名字:<input type="text" name="username" id="uname">
              <input type="button" id="btn1" value="驗證用戶名">
              <input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>
              用戶密碼:<input type="password" name="password"><br/><br/>
              電子郵件:<input type="text" name="email"><br/><br/>
              <input type="submit" value="用戶注冊">
          </form>
          <h1>返回的 json 數據</h1>
          <div id="div1"></div>
          </body>
          </html>
          


          4.6練習

          ● 需求分析: 到數據庫去驗證用戶名是否可用

          1. 點擊驗證用戶名, 到數據庫中驗證用戶名是否可用
          2. 創建數據庫 ajaxdb , 創建表 user 表 自己設計
          3. 使用 Jquery + ajax 方式, 服務端驗證該用戶名是否已經占用了, 如果該用戶已經占用,以 json 格式返回該用戶信息
          4. 對頁面進行局部刷新, 顯示返回信息

          提示: 根據day34-JSON&Ajax02-3.3練習 的 ajax 請求+jdbc+mysql 到數據庫驗證案例完成


          根據之前的day34-JSON&Ajax02-3.3練習,我們已經寫了JDBCUtilsByDruid,BaseDAO,UserDAO,UserService,User等類,只需要在CheckUserServlet2中修改一下代碼即可完成:

          package com.li.ajax.servlet;
          
          import com.google.gson.Gson;
          import com.li.ajax.entity.User;
          import com.li.ajax.service.UserService;
          
          import javax.servlet.*;
          import javax.servlet.http.*;
          import java.io.IOException;
          import java.sql.SQLException;
          
          public class CheckUserServlet2 extends HttpServlet {
              private UserService userService=new UserService();
          
              @Override
              protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  doPost(request, response);
              }
          
              @Override
              protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  request.setCharacterEncoding("utf-8");
                  response.setContentType("text/json;charset=utf-8");//指定MIME類型為json
                  Gson gson=new Gson();
                  //接收jquery發送的ajax數據
                  String username=request.getParameter("username");//參數名取決于前端的參數名
                  //到數據庫中查找有無重名用戶
                  try {
                      User userByName=userService.getUserByName(username);
                      //如果有返回的就是一個User對象,如果沒有,返回的就是null
                      response.getWriter().print(gson.toJson(userByName));
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
          }
          

          前端html頁面使用4.5.4的$.getJSON()方法發送ajax請求,在4.5.4代碼的基礎上修改返回數據的判斷條件即可

          《大數據和人工智能交流》頭條號向廣大初學者新增C 、Java 、Python 、Scala、javascript 等目前流行的計算機、大數據編程語言,希望大家以后關注本頭條號更多的內容。


          使用Jquery的Ajax實現用戶注冊時候的重名檢測,如果注冊的用戶名為“lily”的時候則提示“該用戶名已存在”,否則提示“該用戶名可用”


          1、前端頁面

          頁面users.jsp代碼如下:

          <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>

          <script src="js/jquery-1.6.js"></script>

          <form method="get">

          用戶名:<input type="text" id="usersId" name="usersname"/>

          <input type="button" value="重名檢測" onclick="checkData()"/>

          <span id="s001" style="color:red"></span>

          </form>

          2、在前端頁面增加Ajax控制

          <script>

          function checkData(){

          var usersIdObj=$("#usersId");

          var usersName=usersIdObj.val();

          s001Obj=$("#s001");

          $.get("/ajaxServer/AjaxServlet", { get_usersName: usersName },

          function(data){

          if(data==1){

          s001Obj.text("該用戶名已存在");

          }else{

          s001Obj.text("該用戶名可用");;

          }

          }

          );

          }

          </script>


          3、Java的Servlet服務端及其配置

          【1】web服務端的Servlet的代碼如下:

          package com.test;

          import java.io.IOException;

          import java.io.PrintWriter;

          import javax.servlet.ServletException;

          import javax.servlet.http.HttpServlet;

          import javax.servlet.http.HttpServletRequest;

          import javax.servlet.http.HttpServletResponse;

          public class AjaxServlet extends HttpServlet {

          public void doGet(HttpServletRequest request, HttpServletResponse response)

          throws ServletException, IOException {

          PrintWriter out=response.getWriter();

          String usersname=request.getParameter("get_usersName");

          System.out.println(usersname);

          if (!"lily".equals(usersname)){

          out.println(0);

          }else{

          out.println(1);

          }

          }

          }

          【2】、web.xml配置如下:

          <?xml version="1.0" encoding="UTF-8"?>

          <web-app version="2.5"

          xmlns="http://java.sun.com/xml/ns/javaee"

          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

          <servlet>

          <servlet-name>AjaxServlet</servlet-name>

          <servlet-class>com.test.AjaxServlet</servlet-class>

          </servlet>

          <servlet-mapping>

          <servlet-name>AjaxServlet</servlet-name>

          <url-pattern>/AjaxServlet</url-pattern>

          </servlet-mapping>

          <welcome-file-list>

          <welcome-file>index.jsp</welcome-file>

          </welcome-file-list>

          </web-app>



          《大數據和人工智能交流》的宗旨

          1、將大數據和人工智能的專業數學:概率數理統計、線性代數、決策論、優化論、博弈論等數學模型變得通俗易懂。

          2、將大數據和人工智能的專業涉及到的數據結構和算法:分類、聚類 、回歸算法、概率等算法變得通俗易懂。

          3、最新的高科技動態:數據采集方面的智能傳感器技術;醫療大數據智能決策分析;物聯網智慧城市等等。

          根據初學者需要會有C語言、Java語言、Python語言、Scala函數式等目前主流計算機語言。

          根據讀者的需要有和人工智能相關的計算機科學與技術、電子技術、芯片技術等基礎學科通俗易懂的文章。

          • 復現Ajax跨域問題
          • Ajax跨域介紹
          • Ajax跨域解決方案
          • 一. 在服務端添加響應頭Access-Control-Allow-Origin
          • 二. 使用JSONP解決
          • 小結

          復現Ajax跨域問題

          • 做兩個簡單的小項目復現Ajax跨域問題. 后端語言使用Java
          • 首先是一個簡單的訂單系統, 通過訪問/loadOrderList, 最終以json串形式返回訂單集合. 該項目使用Tomcat發布在7070端口.
          @RequestMapping("/loadOrderList")
          @ResponseBody
          public List<Order> loadOrderList(String uid){
           //模擬訂單數據
           Order o1=new Order();
           o1.setId("111");
           o1.setTotal(333.33);
           o1.setDate("2019-4-29");
           Order o2=new Order();
           o2.setId("222");
           o2.setTotal(444.44);
           o2.setDate("2019-5-29");
           Order o3=new Order();
           o3.setId("333");
           o3.setTotal(555.55);
           o3.setDate("2019-6-29");
           List<Order> list=new ArrayList<>();
           list.add(o1);
           list.add(o2);
           list.add(o3);
           return list;
          }
          
          • 在另一個項目中做一個向訂單系統發送一個ajax請求, 獲取訂單集合. 該項目使用Tomcat插件發布在9090端口.
          //index.jsp
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
           <title>Title</title>
           <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>
           <script type="text/javascript">
           function sendAjax() {
           $.post("http://localhost:7070/order/loadOrderList", "uid=1234", function (data) {
           alert(data);
           });
           }
           </script>
          </head>
          <body>
           <a href="javascript:sendAjax()">sendAjax</a>
          </body>
          </html>
          

          • 點擊sendAjax超鏈接向訂單系統發送ajax請求.


          • 通過開發者工具發現雖然服務器以狀態碼200響應回來, 但是控制臺卻報錯了.



          • 這就是Ajax跨域出錯的一種表現, 下面分析原因.

          Ajax跨域介紹

          • Ajax跨域問題是由瀏覽器的同源策略造成的, 首先要理解源這個概念.
          • 我們可以通過協議+域名+端口確定一個源. 在上面的示例中, 你可以把一個項目理解為一個源. Ajax請求可以對源內的資源發起訪問, 但是不同源之間進行Ajax就會有問題.
          • 當向不同源的資源發起Ajax請求時, 瀏覽器會加上Origin字段來標識源
          Accept: */*
          Accept-Encoding: gzip, deflate, br
          Accept-Language: zh-CN,zh;q=0.9
          Connection: keep-alive
          Content-Length: 8
          Content-Type: application/x-www-form-urlencoded; charset=UTF-8
          Host: localhost:7070
          Origin: http://localhost:9090 協議+域名+端口
          
          • 服務器會根據Origin字段決定是否同意這次請求, 如果Origin指定的源不在許可范圍內, 服務器會返回一個不帶有Access-Control-Allow-Origin字段的響應. 瀏覽器解析時發現缺少了這個字段, 就會報錯. 這種錯誤不能通過狀態碼識別, 因為狀態碼很有可能就是200(見上面的案例).

          Ajax跨域解決方案

          • 下面介紹最常用Ajax跨域解決方案.

          一. 在服務端添加響應頭Access-Control-Allow-Origin

          • 既然我們已經知道了Ajax跨域失敗是因為響應中缺少了響應頭Access-Control-Allow-Origin, 那么就想辦法加上去.
          • 以Java項目為例, 在后端我們使用CORSFilter過濾器加上該響應頭.
          • (假設是Maven項目), 首先在pom.xml中添加坐標
          <dependency>
           <groupId>com.thetransactioncompany</groupId>
           <artifactId>cors-filter</artifactId>
           <version>2.5</version>
           <scope>runtime</scope>
          </dependency>
          
          • 然后在web.xml中對過濾器進行配置.
           <filter>
           <filter-name>CORS</filter-name>
           <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
           <init-param>
           <param-name>cors.allowOrigin</param-name><!--這個標簽是關鍵, *代表所有源都能訪問-->
           <param-value>*</param-value>
           </init-param>
           <init-param>
           <param-name>cors.supportedMethods</param-name>
           <param-value>GET, POST, HEAD, PUT, DELETE</param-value>
           </init-param>
           <init-param>
           <param-name>cors.supportedHeaders</param-name>
           <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
           </init-param>
           <init-param>
           <param-name>cors.exposedHeaders</param-name>
           <param-value>Set-Cookie</param-value>
           </init-param>
           <init-param>
           <param-name>cors.supportsCredentials</param-name>
           <param-value>true</param-value>
           </init-param>
           </filter>
           <filter-mapping>
           <filter-name>CORS</filter-name>
           <url-pattern>/*</url-pattern>
           </filter-mapping>
          

          • 配置后重啟訂單項目, 再次發起Ajax請求可以看到成功返回數據, 響應頭中包含了Access-Control-Allow-Origin, 值為發起Ajax請求的源.



          二. 使用JSONP解決

          • 上面直接通過過濾器添加響應頭的方法可以說是對癥下藥, 那么還有沒有什么偏方呢?
          • 還真的有. 在jsp文件中經常通過通過<script>標簽引入一段js代碼, 這段代碼通常來源于網絡, 也就是不同源. 那么我們不妨通過<srcipt>標簽完成Ajax請求, 這樣便順帶解決了跨域問題.
          • 下面還是沿用上面的案例進行演示.
          • 我們對發送ajax的jsp進行修改
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
           <title>Title</title>
           <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>
           <script>
           function doCallBack(data){
           var str=JSON.stringify(data);
           alert(str);
           }
           </script>
          </head>
          <body>
           <script src="http://localhost:7070/order/loadOrderList3?uid=111&callBack=doCallBack"></script>
          </body>
          </html>
          
          • 上面的代碼中, 我們首先定義了doCallBack()函數, 它接收一個字符串參數, 并且會把接收到的字符串顯示出來.
          • 然后在<body>標簽中編寫<script>標簽, 我們將通過<script>標簽請求訂單系統, 訂單系統將會返回一段js代碼, 這段js代碼會調用doCallBack()方法.
          • 為了能夠拼接出doCallBack(字符串參數...)js代碼, 我們在訂單系統中作如下操作.
          @RequestMapping("/loadOrderList3")
          @ResponseBody
          public String loadOrderList3(String uid, String callBack){
           //模擬訂單數據
           Order o1=new Order();
           o1.setId("111");
           o1.setTotal(333.33);
           o1.setDate("2019-4-29");
           Order o2=new Order();
           o2.setId("222");
           o2.setTotal(444.44);
           o2.setDate("2019-5-29");
           Order o3=new Order();
           o3.setId("333");
           o3.setTotal(555.55);
           o3.setDate("2019-6-29");
           List<Order> list=new ArrayList<>();
           list.add(o1);
           list.add(o2);
           list.add(o3);
           //拼接js代碼
           String result=callBack + "(" + JSON.toJSONString(list) + ")";
           return result;
          }
          

          • 這個想法是不是很妙? 明白這個原理之后, 我們可以使用jQuery方便進行JSONP操作, 在上面的代碼中我們人為指定了一個名為doCallBack的函數, 而jQuery會隨機用時間戳生成一個函數名, 原理和上面是一樣的.
          • 所以完成一開時點擊超鏈接發送Ajax請求只需要如下幾步.
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
           <title>Title</title>
           <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>
           <script>
           function sendAjax(){
           $.getJSON("http://localhost:7070/order/loadOrderList3?callBack=?","uid=111",
           function (data) {
           var str=JSON.stringify(data);
           alert(str);
           });
           }
           </script>
          </head>
          <body>
           <a href="javascript:sendAjax()">sendAjax</a>
          </body>
          </html>
          

          小結

          • 上面兩種解決辦法在思路上有著本質的不同. 方案一抓住CORS跨域訪問問題的本質, 在后端加上響應頭解決跨域問題. 方案二JSONP利用的是<script>標簽能夠跨域獲取js代碼的特性, 繞過跨域問題.

          主站蜘蛛池模板: 免费萌白酱国产一区二区| 无码免费一区二区三区免费播放 | 午夜视频在线观看一区二区| 亚洲国产欧美日韩精品一区二区三区 | 亚洲高清成人一区二区三区| 国产美女精品一区二区三区| 中文字幕视频一区| 精品成人一区二区三区免费视频| 亚洲国产精品一区二区三区久久| 无码精品人妻一区二区三区中| 伦精品一区二区三区视频| 视频一区视频二区在线观看| 精品亚洲A∨无码一区二区三区| 无码人妻精品一区二区三区9厂| 中文字幕在线观看一区二区 | 国产裸体舞一区二区三区| 在线精品亚洲一区二区小说| 韩国福利一区二区美女视频| 中文字幕乱码亚洲精品一区 | 日韩精品区一区二区三VR| 国产三级一区二区三区| 亚洲大尺度无码无码专线一区 | 国产日韩一区二区三区在线播放| 精品国产免费观看一区| 天堂va在线高清一区| 亚洲一区二区三区高清| 国产在线精品一区免费香蕉| 无码少妇一区二区三区芒果| 中文字幕一区日韩精品| 水蜜桃av无码一区二区| 国产一区二区三区高清在线观看 | 婷婷亚洲综合一区二区| 国产对白精品刺激一区二区| 国产日韩一区二区三区在线观看| 日韩精品无码Av一区二区| 国产精品一区二区综合| 国产精品一区二区无线| 日韩精品免费一区二区三区| 成人精品一区二区激情| 国产亚洲综合一区二区三区| 日本在线视频一区二区三区|