1. 響應正文
在SpringMVC中,處理完請求之後,默認的響應方式是轉發或重定向,這種操作會導致用戶看到的界面會發生變化(將看到另一個頁面),這種做法的缺陷在於:
1)用戶體驗較差,例如操作失敗時,不能直接在當前頁面提示錯誤,只能用另一個頁面來提示,當用戶嘗試再次操作時,需要先返回到原有頁面,纔可以進行下一次操作;
2) 產生的流量消耗較大,用於提示錯誤的頁面,也是一個完整的頁面,相對於只響應正文而言,流量的消耗會大很多,直接導致用戶體驗較差,並且流量費會增加;
3)對多平臺設備的兼容較差,如果服務器端響應的是一個html頁面(含JSP),可能不適用於在手機端、平板電腦等其它設備上直接顯示。
目前,主流的開發模式是服務器端處理完請求之後,只向客戶端響應正文(客戶端應該得到的數據),由客戶端(前端頁面、Android APP、iOS APP及其它客戶端軟件)組織並呈現這些數據。
如需要服務器端處理請求時響應正文,需要在處理請求的方法之前添加@ResponseBody註解,並在Spring的配置文件中,添加註解驅動<mvc:annotation-driven />。
添加了@ResponseBody註解的方法,其返回值就是將響應到客戶端的數據。
2. 響應正文的數據格式
服務器端響應給客戶的數據應該是有數據格式的,否則當客戶端接收到響應結果時,可能無法分析出其中的數據意義,例如當客戶端請求的是某個用戶的資料,其中應該包含用戶的名稱、年齡、手機號碼、電子郵箱等,這些數據如果組織在1個字符串中,沒有特定的數據格式的話,客戶端將無從解析,從中得到哪些是用戶的名稱,哪些是年齡等。
早期推薦使用XML組織數據的格式,例如:
<data>
<username>root</username>
<age>16</age>
<email>[email protected]</email>
</data>
當客戶端接收到以上XML格式的字符串時,通過XML解析技術,就可以得到其中的用戶名、年齡、郵箱。
目前推薦使用更加輕量級的JSON格式的數據,例如:
{
"username":"root",
"age":16,
"email":"[email protected]"
}
相比下之,JSON數據的優點在於:
1. 數據量較小;
2. 解析方便;
3. JSON數據格式
1. 整個JSON數據是1個對象,必須使用 {} 框住。
2. JSON對象中可以有多個屬性,每個屬性的名稱使用引號框住,屬性值根據類型決定是否需要添加引號,數值型和布爾型的不需要添加引號,屬性名與屬性值之間使用冒號分隔,多個屬性之間使用逗號分隔。
{
"username":"root",
"age":16,
"email":"[email protected]",
"is_delete":false
}
3. 整個JSON中無視多餘的空白(含若干數量的空格、換行、空白製表位等)
4. JSON數據中,某個屬性的值可以是另一個對象,任何對象都使用大括號框住。
"department": {
"id":9527,
"name":"UI"
}
5. JSON數據中,某個屬性的值可以是一系列的數據,即數組,都使用中括號框住
"phones": ["13800138000","13800138001","13800138002"]
6. 各種複合類型的值可以互相嵌套,例如數組的元素也可以是對象,對象中再包含數組等
4. 在HTML頁面中處理JSON
JavaScript語言支持讀取JSON數據,例如:
<script type="text/javascript">
var json = {
"username":"root",
"age":18,
"hobby":["game","coding","run"],
"department":{
"id":7,
"name":"RD"
}
};
var username = json.username;
var age = json.age;
console.log("username=" + username);
console.log("age=" + age);
for (var i = 0; i < json.hobby.length; i++) {
console.log("hobby=" + json.hobby[i]);
}
console.log("department name=" + json.department.name)
</script>
對於客戶端而言,往往得到的並不一定是JSON對象,而是服務器給回的JSON格式的字符串!通過`JSON.parse(str)`就可以把字符串類型的`str`數據轉換回JSON對象。
5. 在服務器端向客戶端響應JSON數據
在服務器端添加`jackson-databind`依賴:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
當服務器端的控制器處理請求時,添加了`@ResponseBody`,即表示響應正文,則SpringMVC框架會根據匹配的converter將處理請求的方法的返回值轉換爲正文,如果返回值是`String`類型,則會自動使用`StringHttpMessageConverter`,還有一些其它內置的converter,如果方法的返回值類型不是SpringMVC默認就支持的(例如自定義的數據類型),則會自動使用jackson框架中的converter,而jackson框架中的converter就會將返回的對象組織爲JSON格式。
應用jackson框架並不需要編寫任何代碼,也不需要添加任何配置。
通常,某個應用中,向客戶端響應的數據格式應該是相對固定的,也就是說,無論是用戶登錄成功、登錄失敗、註冊成功、註冊失敗、發表文章成功等任何操作,服務器向客戶端響應的JSON的格式是相對固定的,都會包含某些特定的屬性,表達特定的意義,以便於客戶端處理。
所以,通常會在服務器端創建一個類,專門用於表示向客戶端響應的數據的類型:
public class ResponseResult {
private Integer state;
private String message;
get
}
6. 異步請求
在頁面中引用jQuery,然後,調用`$.ajax()`函數,即可發出請求,並獲取響應結果。
$("#btn-reg").click(function(){
// 發出異常請求,並處理結果
// url:將請求提交到哪裏去
// data:提交的請求參數,例如 username=root&password=1234
// type:提交方式
// dataType:服務器端即將響應的數據的類型,取值可以是"json"、"xml"、"text",例如服務器端響應的可能是application/json,該屬性值應該是"json"
// success:當服務器成功響應時(Http響應碼是2xx)的回調函數
$.ajax({
"url":"user/reg.do",
"data":"username=" + $("#username").val(),
"type":"POST",
"dataType":"json",
"success":function(json) {
alert(json.message);
}
});
});