1. 程式人生 > >前端Ajax/JS/HTML+後端SpringMVC(一)

前端Ajax/JS/HTML+後端SpringMVC(一)

過程 大致 傳輸 引號 mapping 開發 客戶 con int

1.JSON

1.1. 轉發或重定向的不足

對於發出的請求,最終需要給出“成功/失敗”的結果的話,轉發的方式來處理,給用戶的體驗就非常不好!即使用戶填錯了一項數據不達標,都需要回退至此前的頁面重新填寫,而原本填寫的其它數據可能需要再填寫一次!

並且,當用戶發出請求後,如果是轉發或者重定向,一定會發生頁面的跳轉!無法在頁面中局部來提示信息。

從服務端的角度出來,其實,還存在浪費流量的問題!如果只是為了表達“成功/失敗”,也許只需要1個“1/0”就可以了,根本就不需要使用整個網頁來表達!

所以,當服務器需要向客戶端響應某些數據,而不是響應整個頁面時,可以使用JSON來組織數據!

1.2. JSON簡介

早期,會使用XML來組織服務器響應的數據,例如:

<result>
    <state>-1</state>
    <message>修改密碼失敗!原密碼錯誤!</message>
</result>

不過,這種做法導致的問題就是:解析比較麻煩,傳輸的數據量略大!後來,改用了JSON格式:

{
    "state": -1, 
    "message":"修改密碼失敗!原密碼錯誤!"
}

JSON是一種組織數據的格式,JavaScript天生就支持解析JSON數據,並且,這種格式相對於XML更加簡潔,在傳輸過程中產生的流量將更小!

1.3. 語法格式

JSON是在JavaScript中的一種對象型數據,其數據的組成方式大致是:使用大括號框住所有內容,每項數據的名稱都是字符串,需要使用引號(單/雙均可)框住數據的名稱,然後使用冒號與值分隔,值可以是各種數據類型,例如:數值型的值可以直接寫,而字符串型的值需要引號,各個數據之間使用逗號進行分隔:

<script type="text/javascript">
var obj = { "state": -1, "message": "error" };
</script>

在JavaScript中,可以直接訪問JSON對象中的任意數據,語法為:

var state = obj.state;

JSON中的數組

在JSON中的數據的值也可以是數組,例如:

var obj = { "state": -1, "message": "error", "skill": ["Java", "MySQL", "AJAX"] };

即使用[]表示數組,各數組元素之間使用逗號分隔。

則通過obj.skill

可以訪問到整個數組,通過obj.skill[下標]可以訪問到數組中的某個元素,和其它語言一樣,數組的下標是從0開始編號的。

JSON中的對象

在JSON中的某個數據的值也可以是對象型的,例如:

var obj = { "state": -1, "message": "error", "skill": ["Java", "MySQL", "AJAX"], "user": { "username": "Jack", "age": 18 } };

則使用obj.user就可以訪問到整個對象,使用obj.user.username就可以訪問到"Jack"這個值!

其實,在JSON中,可以無限的嵌套下去,即:JSON對象中包括某個子級對象,子級對象中還可以繼續包含另一個子級對象,一直包含下去……

JSON對象與JSON字符串

在實際應用中,JSON對象往往並不是直接編寫出來的,而是通過服務器端返回的!而服務器端返回的一定是字符串,而不會是一個JSON對象!即服務端返回的會是:

‘{ "state": -1, "message": "error" }‘

即:內容本身是JSON語法所組織的,但是,數據類型卻是字符串,而不是JSON對象!

在JavaScript中,可以通過JSON.parse(str)函數將參數str進行轉換,得到JSON對象!

1.4. 小結

JSON是一種組織數據結構的對象,支持在對象中存放若幹個屬性,屬性的類型可以是各種類型,包括常用數據類型、數組和其它對象。

學習JSON重點掌握如何通過JSON組織數據。

JavaScript天生支持直接解析JSON對象,獲取其中的數據。

當獲取到的是JSON格式的字符串時,可以通過JSON.parse(str)函數將字符串轉換為JSON對象!

2. 服務器向客戶端響應數據

當服務器向客戶端響應的需要是某些數據,而不是轉發或者重定向時,需要在處理請求的方法之前添加@ResponseBody,而該註解默認是不識別的,在使用該註解之前,需要在Spring的配置文件中添加註解驅動:

<mvc:annotation-driven />

例如處理請求時:

@RequestMapping("/login.do")
@ResponseBody
public String showLogin() {
    return "hello, login"; // /WEB-INF/login.jsp
}

則在瀏覽器中得到的將是"hello, login"字符串,而不是網頁的源代碼!

註意:在沒有進一步的配置之前,返回的內容中並不支持中文!

以“處理登錄”為例,可以為處理請求的方法添加@ResponseBody註解,然後,調整各種情況下的返回值,無論是哪種情況(成功或失敗),都使用JSON語法組織數據:

@RequestMapping(value="/handle_login.do", 
    method=RequestMethod.POST)
@ResponseBody
public String handleLogin(
    @RequestParam("username") String username,
    @RequestParam("password") String password,
    HttpSession session) {
    
    try {
        User user 
            = userService.login(username, password);
        session.setAttribute("uid", user.getId());
        session.setAttribute("username", user.getUsername());
        return "{ \"state\": 1 }";
    } catch (UserNotFoundException e) {
        return "{ \"state\": -1, \"message\": \"" + e.getMessage() + "\" }";
    } catch (PasswordNotMatchException e) {
        return "{ \"state\": -2, \"message\": \"" + e.getMessage() +"\" }";
    }
}

3. Jackson框架

使用Jackson框架,可以解決響應的數據可能亂碼的問題(本質上是設置了響應頭中的響應字符編碼),並且,當響應某個對象時,會自動裝響應頭中的響應類型設置為json類型。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.7</version>
</dependency>

除此以外,Jackson框架還可以將響應的對象自動轉換為JSON字符串格式!通常,可以在項目中添加ResponseResult類:

public class ResponseResult {

    private Integer state;
    private String message;

    public Integer getState() {
        return state;
    }

    public void setState(Integer state) {
        this.state = state;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

SpringMVC框架對Jackson框架的支持性非常好,添加了Jackson依賴後,無須添加任何配置,也不需要在項目的任何位置顯式的使用它。

4. AJAX

4.1. 簡介

AJAX是一種異步提交請求並處理響應結果的做法,它本身是基於JavaScript實現的!

通常使用基於jQuery的AJAX處理方式,可以解決不同瀏覽器的版本兼容問題,並且使得代碼的可讀性變得更高,所以,通常需要:

<script type="text/javascript" src="${pageContext.request.contextPath }/jquery-3.3.1.min.js"></script>

然後調用jQuery中的ajax()函數來處理AJAX。

在ajax()函數的參數中,至少配置5個屬性:

  • url:將請求提交到哪個URL
  • data:提交的參數
  • type:請求的類型
  • dataType:服務端響應的數據類型,可以是text、xml、json
  • success:當服務器正確響應(200)時如何處理,值是匿名函數,函數的參數就是服務端響應的JSON字符串轉換得到的JSON對象

4.2. 小結

使用這種模式開發時,關於控制器端,應該:

1 處理請求的方法需要添加@ResponseBody註解;

2 處理請求的方法的返回值應該是ResponseResult

3 在處理請求的方法內部,無論是成功還是失敗,當決定執行響應時,都應該在ResponseResult對象中封裝必要的數據,然後返回ResponseResult對象。

關於前端,應該:

1 由於需要使用jQuery,所以,必須引入jQuery框架;

2 前端頁面不強制需要<form>,並且,用戶的提交操作觸發的不是傳統的提交表單,而應該觸發JS事件,例如:可以將提交按鈕的類型調整為type="button",並配置onclick="doReg()",表示當點擊這個按鈕時,執行JavaScript中的doReg()方法;

3 自定義JavaScript函數,且函數名與以上步驟中點擊事件對應一致:

<script type="text/javascript">
function doReg() {
    
}
</script>

4 然後編寫函數體,主要任務是調用jQuery框架中的ajax()函數來實現提交請求並獲取響應結果:

function doReg() {
    // 獲取用戶輸入的數據
    var u = $("#username").val();
    var p = $("#password").val();
    // 處理請求的URL
    var url = "handle_reg.do";
    // 提交到服務端的參數
    var data = "username=" + u + "&password=" + p;
    // 發出請求,並獲取響應結果
    $.ajax({
        "url": url,
        "data": data,
        "type": "post",
        "dataType": "json",
        "success": function(json) {
            // 由於服務端使用了Jackson
            // 所以響應頭中由Jackson自動設置了響應正文是json
            // 所以dataType的值就是"json"
            // 且當前成功時的處理函數的參數就是服務端響應的json對象
            if (json.state == 1) {
                alert("註冊成功!");
            } else {
                alert("註冊失敗!" + json.message);
            }
        }
    });
}

前端Ajax/JS/HTML+後端SpringMVC(一)