十六、Ajax & Json

一、AJAX

1.1、概念: ASynchronous JavaScript And XML 異步的JavaScript 和 XML

異步和同步:客戶端和服務器端相互通信的基礎上

同步:客戶端必須等待服務器端的響應。在等待的期間客戶端不能做其他操作。

異步:客戶端不需要等待服務器端的響應。在服務器處理請求的過程中,客戶端可以進行其他的操作。

Ajax 是一種在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。(刷新局部頁面)

通過在後臺與服務器進行少量數據交換,Ajax 可以使網頁實現異步更新。這意味着可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。

傳統的網頁(不使用 Ajax)如果需要更新內容,必須重載整個網頁頁面。
使用Ajax可以提升用戶的體驗

2.1、實現方式

原生的JS實現方式(瞭解)

代碼實現:
前臺:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <title>原生js實現ajax</title>
    <script>

        //定義方法
        function fun() {
            //發送異步請求
            //1.創建核心對象
            var xmlhttp;
            if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
                xmlhttp = new XMLHttpRequest();
            }
            else {// code for IE6, IE5
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }

            //2. 建立連接
            /*
                參數:
                    1. 請求方式:GET、POST
                        * get方式,請求參數在URL後邊拼接。send方法爲空參
                        * post方式,請求參數在send方法中定義
                    2. 請求的URL:
                    3. 同步或異步請求:true(異步)或 false(同步)

             */
            xmlhttp.open("GET", "../ajaxServlet?username=tom", true);

            //3.發送請求
            xmlhttp.send();

            //4.接受並處理來自服務器的響應結果
            //獲取方式 :xmlhttp.responseText
            //什麼時候獲取?當服務器響應成功後再獲取

            //當xmlhttp對象的就緒狀態改變時,觸發事件onreadystatechange。
            xmlhttp.onreadystatechange = function () {
                //判斷readyState就緒狀態是否爲4,判斷status響應狀態碼是否爲200
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    //獲取服務器的響應結果
                    var responseText = xmlhttp.responseText;
                    alert(responseText);
                }
            }

        }

    </script>


</head>
<body>

<input type="button" value="發送異步請求" onclick="fun();">

<input>
</body>
</html>

後臺:

package cn.kinggm520.web;

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.IOException;

/**
 * 作者: kinggm Email:[email protected]
 * 時間:  2020-03-04 19:50
 */
@WebServlet("/ajaxServlet")
public class AjaxServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        獲取前端異步請求的參數
        String username = request.getParameter("username");
        System.out.println(username); //打印

//        響應
        response.getWriter().write("hello"+username);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

程序執行結果:
在這裏插入圖片描述
注意這裏寫的目錄爲: xmlhttp.open(“GET”, “…/ajaxServlet?username=tom”, true);
由於前臺頁面並不在web文件夾根目錄 所以Servlet的路徑前面要加 …/ 表示上一級目錄
在這裏插入圖片描述

JQeury實現方式(重要)

$.ajax()發送異步請求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/jquery-3.2.1.min.js"></script>
    <script>

        //定義方法
        function  fun() {
            //使用$.ajax()發送異步請求

            $.ajax({
                url:"../ajaxServlet" , // 請求路徑
                type:"POST" , //請求方式  默認不寫是GET
                //data: "username=jack&age=23",//請求參數 2種方式
                data:{"username":"jack","age":23},
                success:function (data) {
                    alert(data);
                },//響應成功後的回調函數
                error:function () {
                    alert("出錯啦...")
                },//表示如果請求響應出現錯誤,會執行的回調函數

                dataType:"text"//設置接受到的響應數據的格式
            });
        }

    </script>


</head>
<body>

<input type="button" value="發送異步請求" onclick="fun();">

<input>
</body>
</html>

後臺代碼同上:

程序執行結果:
在這裏插入圖片描述

$.get():發送get請求

語法:$.get(url, [data], [callback], [type])
參數:
url:請求路徑
data:請求參數
callback:回調函數
type:響應結果的類型

代碼示例:
前臺:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/jquery-3.2.1.min.js"></script>
    <script>
        //定義方法
        function  fun() {
            $.get("ajaxServlet",{username:"rose"},function (data) {
                alert(data);
            },"text");
        }

    </script>

</head>
<body>
<input type="button" value="發送異步請求" onclick="fun();">
<input>
</body>
</html>

程序執行結果:
在這裏插入圖片描述

$.post():發送post請求

語法:$.post(url, [data], [callback], [type])
參數:
url:請求路徑
data:請求參數
callback:回調函數
type:響應結果的類型

代碼示例:同GET

二、JSON

2.1、概念: JavaScript Object Notation JavaScript對象表示法

Java對象封裝數據:
Person p = new Person();
p.setName(“張三”);
p.setAge(23);
p.setGender(“男”);

JavaScript對象表示法:(Json)
var p = {“name”:“張三”,“age”:23,“gender”:“男”};

json現在是存儲和交換文本信息的語法
進行數據的傳輸
JSON 比 XML 更小、更快,更易解析。

2.2、語法:

基本規則
數據在名稱/值對中:json數據是由鍵值對構成的
鍵用引號(單雙都行)引起來,也可以不使用引號
{“name”:“張三”, “age”:23, “gender”:“男”}

值的類型:
數字(整數或浮點數)
字符串(在雙引號中)
邏輯值(true 或 false)
數組(在方括號中) {“persons”:[{},{}]} 數組中可存儲對象
對象(在花括號中) {“address”:{“province”:“陝西”…}}
null

數據由逗號分隔:多個鍵值對由逗號分隔
花括號保存對象:使用{}定義json 格式
方括號保存數組:[ ]

獲取數據:
json對象.鍵名
json對象[“鍵名”]
數組對象[索引]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        //1.定義基本格式
        var person = {"name": "張三", age: 23, 'gender': true};

        //獲取name的值
        //var name = person.name;
        var name = person["name"];
        // alert(name);

        //alert(person);
        //2.嵌套格式   {}———> []
        var persons = {
            "persons": [
                {"name": "張三", "age": 23, "gender": true},
                {"name": "李四", "age": 24, "gender": true},
                {"name": "王五", "age": 25, "gender": false}
            ]
        };
        // alert(persons);
        //獲取王五值
        var name1 = persons.persons[2].name;
        // alert(name1);


        //2.嵌套格式   []———> {}
        var ps = [{"name": "張三", "age": 23, "gender": true},
            {"name": "李四", "age": 24, "gender": true},
            {"name": "王五", "age": 25, "gender": false}];
        //獲取李四值
        //alert(ps);
        alert(ps[1].name);


    </script>

</head>
<body>
</body>
</html>

遍歷Json數據

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        //1.定義基本格式
        var person = {"name": "張三", age: 23, 'gender': true};

        var ps = [{"name": "張三", "age": 23, "gender": true},
            {"name": "李四", "age": 24, "gender": true},
            {"name": "王五", "age": 25, "gender": false}];

        //獲取person對象中所有的鍵和值
        //for in 循環
        /* for(var key in person){
             //這樣的方式獲取不行。因爲相當於  person."name"
             //alert(key + ":" + person.key);

             alert(key+":"+person[key]);
         }*/

        //獲取ps中的所有值
        for (var i = 0; i < ps.length; i++) {
            var p = ps[i];
            for(var key in p){
                alert(key+":"+p[key]);
            }
        }
    </script>
</head>
<body>
</body>
</html>

2.3、JSON數據和Java對象的相互轉換

JSON解析器:
常見的解析器:Jsonlib,Gson,fastjson,jackson

jackson解析器jar包下載
鏈接:https://pan.baidu.com/s/1ClAjP3cM4oQ7-l8D1ZcM-Q
提取碼:9yo7

學習使用jackson解析器
JSON轉爲Java對象
導入jackson的相關jar包
創建Jackson核心對象 ObjectMapper
調用ObjectMapper的相關方法進行轉換
readValue(json字符串數據,Class)


//    Json轉Java對象
    @Test
    public void test4() throws IOException {
        String json="{\"name\":\"張三\",\"age\":22,\"gender\":\"男\",\"birthday\":null}";
        ObjectMapper objectMapper = new ObjectMapper();

        User user = objectMapper.readValue(json, User.class);
        System.out.println(user);

    }

程序執行結果:
User{name=‘張三’, age=22, gender=‘男’, birthday=null}

Java對象轉換JSON
使用步驟:
導入jackson的相關jar包
創建Jackson核心對象 ObjectMapper
調用ObjectMapper的相關方法進行轉換

轉換方法:

writeValue(參數1,obj):
參數1
File:將obj對象轉換爲JSON字符串,並保存到指定的文件中
Writer:將obj對象轉換爲JSON字符串,並將json數據填充到字符輸出流中
OutputStream:將obj對象轉換爲JSON字符串,並將json數據填充到字節輸出流中 (常用該方法 將數據輸出到頁面)
writeValueAsString(obj):將對象轉爲json字符串

代碼示例:

package cn.kinggm520.test;

import cn.kinggm520.domain.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

/**
 * 作者: kinggm Email:[email protected]
 * 時間:  2020-03-04 21:30
 */
public class JacksonTest {

    @Test
    public void test() throws JsonProcessingException {

        User user = new User();
        user.setName("張三");
        user.setAge(22);
        user.setGender("男");

        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(user);

        System.out.println(json);

    }

}

程序執行結果:
在這裏插入圖片描述

註解:
@JsonIgnore:排除屬性。
@JsonFormat:屬性值格式化
@JsonFormat(pattern = “yyyy-MM-dd”)
代碼示例:

public class User {
    private String name;
    private int age;
    private String gender;

      //        對日期忽略  當該對象轉換成Json數據格式時忽略該成員變量 
    @JsonIgnore
    private Date birthday;
}


    //對日期進行格式化
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date birthday;

複雜java對象轉換

List:數組

@Test
    public void test2() throws JsonProcessingException {

        List<User> list = new ArrayList<>();
        User user = new User();
        user.setName("張三");
        user.setAge(22);
        user.setGender("男");
        user.setBirthday(new Date());

        User user2 = new User();
        user2.setName("張三");
        user2.setAge(22);
        user2.setGender("男");
        user2.setBirthday(new Date());

        User user3 = new User();
        user3.setName("張三");
        user3.setAge(22);
        user3.setGender("男");
        user3.setBirthday(new Date());

        list.add(user);
        list.add(user2);
        list.add(user3);
        
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(list);

        System.out.println(json);
    }

程序執行結果:[{“name”:“張三”,“age”:22,“gender”:“男”,“birthday”:“2020-03-04”},…]

Map:對象格式一致

 @Test
    public void test3() throws JsonProcessingException {

        Map<String,User> map = new HashMap<>();

        User user = new User();
        user.setName("張三");
        user.setAge(22);
        user.setGender("男");
        user.setBirthday(new Date());

        User user2 = new User();
        user2.setName("張三");
        user2.setAge(22);
        user2.setGender("男");
        user2.setBirthday(new Date());

        User user3 = new User();
        user3.setName("張三");
        user3.setAge(22);
        user3.setGender("男");
        user3.setBirthday(new Date());

        map.put("u1",user);
        map.put("u2",user2);
        map.put("u3",user3);

        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(map);

        System.out.println(json);
    }

程序執行結果:
{“u1”:{“name”:“張三”,“age”:22,“gender”:“男”,“birthday”:“2020-03-04”},…}

案例

校驗用戶名是否存在

在這裏插入圖片描述
注意:
服務器響應的數據,在客戶端使用時,要想當做json數據格式使用。

有兩種解決方案:
$.get(type):將最後一個參數type指定爲"json"

在服務器端設置MIME類型
response.setContentType(“application/json;charset=utf-8”);

這裏代碼沒有去查數據庫 將已存在的用戶名固定設置爲jerry
前臺頁面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>註冊頁面</title>
    <script src="js/jquery-3.2.1.min.js"></script>
    <script>
        //在頁面加載完成後
        $(function () {
            //給username綁定blur事件
            $("#username").blur(function () {
                //獲取username文本輸入框的值
                var username = $(this).val();
                //發送ajax請求
                //期望服務器響應回的數據格式:{"userExsit":true,"msg":"此用戶名太受歡迎,請更換一個"}
                //                         {"userExsit":false,"msg":"用戶名可用"}
                $.get("registerServlet",{username:username},function (data) {
                    //判斷userExsit鍵的值是否是true

                    // alert(data);
                    var span = $("#s_username");
                    if(data.userExsit){
                        //用戶名存在
                        span.css("color","red");
                        span.html(data.msg);
                    }else{
                        //用戶名不存在
                        span.css("color","green");
                        span.html(data.msg);
                    }
                },"JSON");
            });
        });

    </script>
</head>
<body>
<form>

    <input type="text" id="username" name="username" placeholder="請輸入用戶名">
    <span id="s_username"></span>
    <br>
    <input type="password" name="password" placeholder="請輸入密碼"><br>
    <input type="submit" value="註冊"><br>

</form>

</body>
</html>

後臺代碼:

package cn.kinggm520.web;
import com.fasterxml.jackson.databind.ObjectMapper;
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.IOException;
import java.util.HashMap;
import java.util.Map;

@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解決response數據亂碼
        response.setContentType("text/html;charset=utf-8");

        //        獲取用戶名
        String username = request.getParameter("username");

//        定義返回數據
        Map<String, Object> map = new HashMap<>();
//        判斷用戶名是否存在
//        這裏設置已存在的用戶名爲jerry
        if ("jerry".equals(username)) {
//            用戶名已存在
            map.put("userExsit", true);
            map.put("msg", "用戶名已存在,請換個用戶名");
            ObjectMapper objectMapper = new ObjectMapper();
//            Map轉Json輸出到頁面 方式一
//            String string = objectMapper.writeValueAsString(map);
//            response.getWriter().write(string);
            //            Map轉Json輸出到頁面 方式二
            objectMapper.writeValue(response.getWriter(),map);
        } else {
            map.put("userExsit", false);
            map.put("msg", "用戶名可用");
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.writeValue(response.getWriter(),map);
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

程序執行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章