JSON和Ajax學習的知識(供回顧)

學習B站狂神的視頻,轉載狂神的博客

文章鏈接:https://www.cnblogs.com/hellokuangshen/p/11283224.html#springmvcajax和json

什麼是JSON?

JSON(JavaScript Object Notation, JS 對象標記) 是一種輕量級的數據交換格式,目前使用特別廣泛。

採用完全獨立於編程語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得 JSON 成爲理想的數據交換語言。 易於人閱讀和編寫,同時也易於機器解析和生成,並有效地提升網絡傳輸效率。

在 JS 語言中,一切都是對象。因此,任何JS支持的類型都可以通過 JSON 來表示,例如字符串、數字、對象、數組等。看看他的要求和語法格式:

  • 對象表示爲鍵值對
  • 數據由逗號分隔
  • 花括號保存對象
  • 方括號保存數組

 JSON 鍵值對是用來保存 JS 對象的一種方式,和 JS 對象的寫法也大同小異,鍵/值對組合中的鍵名寫在前面並用雙引號 "" 包裹,使用冒號 : 分隔,然後緊接着值:

{"name": "QinJiang"}
{"age": "3"} 
{"sex": "男"}
很多人搞不清楚 JSON 和 Js 對象的關係,甚至連誰是誰都不清楚。其實,可以這麼理解:
JSON 是 JS 對象的字符串表示法,它使用文本表示一個 JS 對象的信息,本質是一個字符串。
var obj = {a: 'Hello', b: 'World'}; //這是一個對象,注意鍵名也是可以使用引號包裹的 
var json = '{"a": "Hello", "b": "World"}'; //這是一個 JSON 字符串,本質是一個字符串

JSON 和 JS 對象互轉

要實現從JSON字符串轉換爲JS對象,使用 JSON.parse() 方法:

var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //結果是 {a: 'Hello', b: 'World'}

要實現從JS對象轉換爲JSON字符串,使用 JSON.stringify() 方法:

var json = JSON.stringify({a: 'Hello', b: 'World'}); //結果是 '{"a": "Hello", "b": "World"}'

我們去代碼中測試下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JSON_秦疆</title>
</head>
<body>

<script type="text/javascript">
    //編寫一個js的對象
    var user = {
        name:"秦疆",
        age:3,
        sex:"男"
    };
    //將js對象轉換成json字符串
    var str = JSON.stringify(user);
    console.log(str);
    //將json字符串轉換爲js對象
    var user2 = JSON.parse(str);
    console.log(user2.age,user2.name,user2.sex);
    
</script>

</body>
</html>

運行:

 

使用Controller實現返回JSON數據

Jackson應該是目前比較好的json解析工具了,當然工具不止這一個,比如還有阿里巴巴的fastjson等等。

我們這裏使用Jackson,使用它需要導入它的jar包;

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>

我們隨便編寫一個User的實體類,然後我們去編寫我們的測試Controller;這裏我們需要兩個新東西,一個是@ResponseBody,一個是ObjectMapper對象,我們看下具體的用法

package com.kuang.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kuang.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {

    @RequestMapping("/json")
    @ResponseBody
    public String json1() throws JsonProcessingException {

        //創建一個jackson的對象映射器,用來解析數據
        ObjectMapper mapper = new ObjectMapper();
        //創建一個對象
        User user = new User("秦疆1號", 3, "男");
        //將我們的對象解析成爲json格式
        String str = mapper.writeValueAsString(user);

        return str; //由於@ResponseBody註解,這裏會將str轉成json格式返回;十分方便
    }

}

我們運行測試一下:

發現出現了亂碼問題,我們需要設置一下他的編碼格式爲utf-8,以及它返回的類型;通過@RequestMaping的produces屬性來實現,修改下代碼

//produces:指定響應體返回類型和編碼
@RequestMapping(value = "/json",produces = "application/json;charset=utf-8")

再次測試:

注意:使用json記得處理亂碼問題

上一種方法比較麻煩,如果項目中有許多請求則每一個都要添加,可以通過Spring配置統一指定,這樣就不用每次都去處理了!

<mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

 我們去打印一個集合試試;

 @RequestMapping("/json3")
    @ResponseBody
    public String json3() throws JsonProcessingException {

        //創建一個jackson的對象映射器,用來解析數據
        ObjectMapper mapper = new ObjectMapper();
        //創建一個對象
        User user1 = new User("秦疆1號", 3, "男");
        User user2 = new User("秦疆2號", 3, "男");
        User user3 = new User("秦疆3號", 3, "男");
        User user4 = new User("秦疆4號", 3, "男");
        List<User> list = new ArrayList<>();
        list.add(user1);
        list.add(user2);
        list.add(user3);
        list.add(user4);
        //將我們的對象解析成爲json格式
        String str = mapper.writeValueAsString(list);

        return str; //由於@ResponseBody註解,這裏會將str轉成json格式返回;十分方便
    }

 運行結果 : 十分完美,沒有任何問題!

 

我們創建一個時間日期的對象試試,看看能不能轉換成功!

@RequestMapping("/time")
    @ResponseBody
    public String json2() throws JsonProcessingException {

        ObjectMapper mapper = new ObjectMapper();
        //創建時間一個對象
        Date date = new Date();
        //將我們的對象解析成爲json格式
        String str = mapper.writeValueAsString(date);

        return str; //由於@ResponseBody註解,這裏會將str轉成json格式返回;十分方便
    }

運行結果:

默認日期格式會變成一個數字,是1970年1月1日到當前日期的毫秒數!Jackson 默認是轉成timestamps形式

 解決方案:取消timestamps形式 , 自定義時間格式

@RequestMapping("/time")
    @ResponseBody
    public String json2() throws JsonProcessingException {

        ObjectMapper mapper = new ObjectMapper();
        //不使用時間戳的方式
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        //自定義日期格式對象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //指定日期格式
        mapper.setDateFormat(sdf);

        Date date = new Date();
        String str = mapper.writeValueAsString(date);

        return str; //由於@ResponseBody註解,這裏會將str轉成json格式返回;十分方便
    }

 結果:完美解決OK!

如果要經常使用的話,這樣是比較麻煩的,我們可以將這些代碼封裝到一個工具類中;我們去編寫下

package com.kuang.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.text.SimpleDateFormat;

public class JsonUtils {
    
    public static String getJson(Object object) {
        return getJson(object,"yyyy-MM-dd HH:mm:ss");
    }

    public static String getJson(Object object,String dateFormat) {
        ObjectMapper mapper = new ObjectMapper();
        //不使用時間差的方式
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        //自定義日期格式對象
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        //指定日期格式
        mapper.setDateFormat(sdf);
        try {
            return mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

 我們使用工具類,代碼就更加簡潔了!

@RequestMapping("/utils")
    @ResponseBody
    public String json3() throws JsonProcessingException {

        Date date = new Date();
        String json = JsonUtils.getJson(date);

        return json;
    }

我們上面都是用的是 @ResponseBody 註解,它就是把後臺的對象轉換成json對象,返回到頁面 , 和它對應的當然就是@RequestBody,一般用來負責接收前臺的json數據,把json數據自動封裝到pojo中;我們之後Ajax來測試這一塊。這兩個註解一般都會在異步獲取數據中使用到; 

1|2AJAX

 

AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。

AJAX 是一種在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。

Ajax 不是一種新的編程語言,而是一種用於創建更好更快以及交互性更強的Web應用程序的技術。

在 2005 年,Google 通過其 Google Suggest 使 AJAX 變得流行起來。

Google Suggest 使用 AJAX 創造出動態性極強的 web 界面:當您在谷歌的搜索框輸入關鍵字時,JavaScript 會把這些字符發送到服務器,然後服務器會返回一個搜索建議的列表。

就和國內百度的搜索框一樣:

傳統的網頁(即不用ajax技術的網頁),想要更新內容或者提交一個表單,都需要重新加載整個網頁。
使用ajax技術的網頁,通過在後臺服務器進行少量的數據交換,就可以實現異步局部更新。

使用Ajax,用戶可以創建接近本地桌面應用的直接、高可用、更豐富、更動態的Web用戶界面。

利用AJAX可以做:

註冊時,輸入用戶名自動檢測用戶是否已經存在。
登陸時,提示用戶名密碼錯誤
刪除數據行時,將行ID發送到後臺,後臺在數據庫中刪除,數據庫刪除成功後,在頁面DOM中將數據行也刪除。

我們可以使用前端的一個標籤來僞造一個ajax的樣子。 iframe標籤

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>kuangshen</title>
</head>
<body>

<script type="text/javascript">
    window.onload = function(){
        var myDate = new Date();
        document.getElementById('currentTime').innerText = myDate.getTime();
    };

    function LoadPage(){
        var targetUrl =  document.getElementById('url').value;
        console.log(targetUrl);
        document.getElementById("iframePosition").src = targetUrl;
    }

</script>

<div>
    <p>請輸入要加載的地址:<span id="currentTime"></span></p>
    <p>
        <input id="url" type="text" value="https://www.baidu.com/"/>
        <input type="button" value="提交" onclick="LoadPage()">
    </p>
</div>

<div>
    <h3>加載頁面位置:</h3>
    <iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe>
</div>

</body>
</html>
1|3 jQuery.Ajax

1|3 jQuery.Ajax

 

純JS實現Ajax我們不去講解這裏,直接使用jquery提供的,更方便學習,避免重複造輪子,有興趣的同學可以去了解下本質XMLHttpRequest !

Ajax的核心是XMLHttpRequest對象(XHR)。XHR爲向服務器發送請求和解析服務器響應提供了接口。能夠以異步方式從服務器獲取新數據。

jQuery 提供多個與 AJAX 有關的方法。

通過 jQuery AJAX 方法,您能夠使用 HTTP Get 和 HTTP Post 從遠程服務器上請求文本、HTML、XML 或 JSON – 同時您能夠把這些外部數據直接載入網頁的被選元素中。

jQuery 不是生產者,而是大自然搬運工。

jQuery Ajax本質就是 XMLHttpRequest,對他進行了封裝,方便調用!我們來看下他的方法;

1. jQuery.get(...)
       所有參數:
              url: 待載入頁面的URL地址
             data: 待發送 Key/value 參數。
          success: 載入成功時回調函數。
         dataType: 返回內容格式,xml, json,  script, text, html

2.jQuery.post(...)
       所有參數:
              url: 待載入頁面的URL地址
             data: 待發送 Key/value 參數
          success: 載入成功時回調函數
         dataType: 返回內容格式,xml, json,  script, text, html

3.jQuery.getJSON(...)
       所有參數:
              url: 待載入頁面的URL地址
             data: 待發送 Key/value 參數。
          success: 載入成功時回調函數。

4.jQuery.getScript(...)
       所有參數:
              url: 待載入頁面的URL地址
             data: 待發送 Key/value 參數。
          success: 載入成功時回調函數。

5.jQuery.ajax(...)
       部分參數:
              url:請求地址
             type:請求方式,GET、POST(1.9.0之後用method)
          headers:請求頭
             data:要發送的數據
      contentType:即將發送信息至服務器的內容編碼類型(默認: "application/x-www-form-urlencoded; charset=UTF-8")
            async:是否異步
          timeout:設置請求超時時間(毫秒)
       beforeSend:發送請求前執行的函數(全局)
         complete:完成之後執行的回調函數(全局)
          success:成功之後執行的回調函數(全局)
            error:失敗之後執行的回調函數(全局)
          accepts:通過請求頭髮送給服務器,告訴服務器當前客戶端課接受的數據類型
         dataType:將服務器端返回的數據轉換成指定類型
            "xml": 將服務器端返回的內容轉換成xml格式
           "text": 將服務器端返回的內容轉換成普通文本格式
           "html": 將服務器端返回的內容轉換成普通文本格式,在插入DOM中時,如果包含JavaScript標籤,則會嘗試去執行。
         "script": 嘗試將返回值當作JavaScript去執行,然後再將服務器端返回的內容轉換成普通文本格式
           "json": 將服務器端返回的內容轉換成相應的JavaScript對象
          "jsonp": JSONP 格式使用 JSONP 形式調用函數時,如 "myurl?callback=?" jQuery 將自動替換 ? 爲正確的函數名,以執行回調函數

 我們來個簡單的測試,使用最原始的HttpServletResponse處理 , .最簡單 , 最通用

 編寫一個AjaxController

package com.kuang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
@RequestMapping("/ajax")
public class AjaxController {

    @RequestMapping("/a1")
    public void ajax1(String name , HttpServletResponse response) throws IOException {
        if ("admin".equals(name)){
            response.getWriter().print("true");
        }else{
            response.getWriter().print("false");
        }
    }

}

編寫index.jsp測試

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<head>
    <title>ajax</title>
    <script src="${pageContext.request.contextPath}/statics/js/jquery-3.4.1.min.js"></script>
    <script>

        /*
       jQuery.post(...)
       所有參數:
              url: 待載入頁面的URL地址 (必填)
             data: 待發送 Key/value 參數
          success: 載入成功時回調函數
            data:請求返回的數據
            status:請求返回的狀態
         */
        function a1(){
            $.post({
                url:"${pageContext.request.contextPath}/ajax/a1",
                data:{'name':$("#txtName").val()},
                success:function (data,status) {
                    alert(data);
                    alert(status);
                }
            });
        }

    </script>
</head>
<body>
<%--onblur:失去焦點觸發事件--%>
用戶名:<input type="text" id="txtName" onblur="a1()"/>
</body>

我們可以打開瀏覽器測試一下,查看返回的彈窗結果!

SpringMVC實現

我們來獲取一個集合對象,展示到前端頁面

controller

 @RequestMapping("/a2")
    @ResponseBody
    public List<User> ajax2(){
        List<User> list = new ArrayList<User>();
        list.add(new User("秦疆1號",3,"男"));
        list.add(new User("秦疆2號",3,"男"));
        list.add(new User("秦疆3號",3,"男"));
        return list; ////由於@ResponseBody註解,將list轉成json格式返回
    }

前端頁面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<input type="button" id="btn" value="獲取數據"/>
<table width="80%" align="center">
    <tr>
        <td>姓名</td>
        <td>年齡</td>
        <td>性別</td>
    </tr>
    <tbody id="content">
    </tbody>
</table>

<script src="${pageContext.request.contextPath}/statics/js/jquery-3.4.1.min.js"></script>
<script>

    $(function () {
        $("#btn").click(function () {
            $.post("${pageContext.request.contextPath}/ajax/a2",function (data) {
                console.log(data)
                var html="";
                for (var i = 0; i <data.length ; i++) {
                    html+= "<tr>" +
                        "<td>" + data[i].name + "</td>" +
                        "<td>" + data[i].age + "</td>" +
                        "<td>" + data[i].sex + "</td>" +
                        "</tr>"
                }
                $("#content").html(html);
            });
        })
    })
</script>
</body>
</html>

 我們點擊按鈕,成功加載出來我們Controller返回的數據;

 成功實現了數據回顯!可以體會一下Ajax的好處!

註冊提示

我們再測試一個小Demo,思考一下我們平時註冊時候,輸入框後面的實時提示怎麼做到的;如何優化

我們寫一個Controller

@RequestMapping("/a3")
    @ResponseBody
    public String ajax3(String name,String pwd){
        String msg = "";
        //模擬數據庫中存在數據
        if (name!=null){
            if ("admin".equals(name)){
                msg = "OK";
            }else {
                msg = "用戶名輸入錯誤";
            }
        }
        if (pwd!=null){
            if ("123456".equals(pwd)){
                msg = "OK";
            }else {
                msg = "密碼輸入有誤";
            }
        }
        return msg; //由於@ResponseBody註解,將list轉成json格式返回
    }

編寫前端頁面,進行異步處理

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ajax</title>
    <script src="${pageContext.request.contextPath}/statics/js/jquery-3.4.1.min.js"></script>
    <script>

        function a1(){
            $.post({
                url:"${pageContext.request.contextPath}/ajax/a3",
                data:{'name':$("#name").val()},
                success:function (data) {
                    if (data.toString()=='OK'){
                        //學習鏈接:https://www.w3school.com.cn/jquery/css_css.asp
                        $("#userInfo").css("color","green");
                    }else {
                        $("#userInfo").css("color","red");
                    }
                    $("#userInfo").html(data);
                }
            });
        }
        function a2(){
            $.post({
                url:"${pageContext.request.contextPath}/ajax/a3",
                data:{'pwd':$("#pwd").val()},
                success:function (data) {
                    if (data.toString()=='OK'){
                        $("#pwdInfo").css("color","green");
                    }else {
                        $("#pwdInfo").css("color","red");
                    }
                    $("#pwdInfo").html(data);
                }
            });
        }

    </script>
</head>
<body>
<p>
    用戶名:<input type="text" id="name" onblur="a1()"/>
    <span id="userInfo"></span>
</p>
<p>
    密碼:<input type="text" id="pwd" onblur="a2()"/>
    <span id="pwdInfo"></span>
</p>
</body>
</html>

測試一下效果,動態請求響應,局部刷新,就是如此!

 

github的項目鏈接

https://github.com/kzj666/demo06_springmvc_ajax_json

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