MVC 是一種經典的設計模式,全名爲 Model-View-Controller
,即 模型-視圖-控制器
。javascript
其中,模型
是用於封裝數據的載體,例如,在 Java 中通常經過一個簡單的 POJO
(Plain Ordinary Java Object)來表示,其本質是一個普通的 Java Bean,包含一系列的成員變量及其 getter/setter 方法。對於 視圖
而言,它更加偏重於展示,也就是說,視圖決定了界面到底長什麼樣子,在 Java 中可經過 JSP 來充當視圖,或者經過純 HTML 的方式進行展示,然後者纔是目前的主流。模型和視圖須要經過 控制器
來進行粘合,例如,用戶發送一個 HTTP 請求,此時該請求首先會進入控制器,而後控制器去獲取數據並將其封裝爲模型,最後將模型傳遞到視圖中進行展示。前端
綜上所述,MVC 的交互過程以下圖所示:java
MVC 模式早在上個世紀 70 年代就誕生了,直到今天它依然存在,可見生命力至關之強。MVC 模式最先用於 Smalltalk 語言中,最後在其它許多開發語言中都獲得了很好的應用,例如,Java 中的 Struts、Spring MVC 等框架。正是由於這些 MVC 框架的出現,才讓 MVC 模式真正落地,讓開發更加高效,讓代碼耦合度儘可能減少,讓應用程序各部分的職責更加清晰。web
既然 MVC 模式這麼好,難道它就沒有不足的地方嗎?我認爲 MVC 至少有如下三點不足:spring
爲了使數據展示過程更加直接,而且提供更好的用戶體驗,咱們有必要對 MVC 模式進行改進。不妨這樣來嘗試,首先從瀏覽器發送 AJAX 請求,而後服務端接受該請求並返回 JSON 數據返回給瀏覽器,最後在瀏覽器中進行界面渲染。typescript
改進後的 MVC 模式以下圖所示:數據庫
也就是說,咱們輸入的是 AJAX 請求,輸出的是 JSON 數據,市面上有這樣的技術來實現這個功能嗎?答案是 REST。編程
REST 全稱是 Representational State Transfer(表述性狀態轉移),它是 Roy Fielding 博士在 2000 年寫的一篇關於軟件架構風格的論文,此文一出,威震四方!國內外許多知名互聯網公司紛紛開始採用這種輕量級的 Web 服務,你們習慣將其稱爲 RESTful Web Services,或簡稱 REST 服務。json
若是將瀏覽器這一端視爲前端,而服務器那一端視爲後端的話,能夠將以上改進後的 MVC 模式簡化爲如下先後端分離模式:後端
可見,有了 REST 服務,前端關注界面展示,後端關注業務邏輯,分工明確,職責清晰。那麼,如何使用 REST 服務將應用程序進行先後端分離呢?咱們接下來繼續探討,首先咱們須要認識 REST。
REST 本質上是使用 URL 來訪問資源種方式。衆所周知,URL 就是咱們日常使用的請求地址了,其中包括兩部分:請求方式
與 請求路徑
,比較常見的請求方式是 GET 與 POST,但在 REST 中又提出了幾種其它類型的請求方式,彙總起來有六種:GET、POST、PUT、DELETE、HEAD、OPTIONS。尤爲是前四種,正好與 CRUD
(Create-Retrieve-Update-Delete,增刪改查)四種操做相對應,例如,GET(查)、POST(增)、PUT(改)、DELETE(刪),這正是 REST 與 CRUD 的殊途同歸之妙!須要強調的是,REST 是「面向資源」的,這裏提到的資源,實際上就是咱們常說的領域對象,在系統設計過程當中,咱們常常經過領域對象來進行數據建模。
REST 是一個「無狀態」的架構模式,由於在任什麼時候候均可以由客戶端發出請求到服務端,最終返回本身想要的數據,當前請求不會受到上次請求的影響。也就是說,服務端將內部資源發佈 REST 服務,客戶端經過 URL 來訪問這些資源,這不就是 SOA 所提倡的「面向服務」的思想嗎?因此,REST 也被人們看作是一種「輕量級」的 SOA 實現技術,所以在企業級應用與互聯網應用中都獲得了普遍應用。
下面咱們舉幾個例子對 REST 請求進行簡單描述:
REST 請求 | 描述 |
---|---|
GET:/advertisers | 獲取全部的廣告主 |
GET:/advertiser/1 | 獲取 ID 爲 1 的廣告主 |
PUT:/advertiser/1 | 更新 ID 爲 1 的廣告主 |
DELETE:/advertiser/1 | 刪除 ID 爲 1 的廣告主 |
POST:/advertiser | 建立廣告主 |
可見,請求路徑相同,但請求方式不一樣,所表明的業務操做也不一樣,例如,/advertiser/1 這個請求,帶有 GET、PUT、DELETE 三種不一樣的請求方式,對應三種不一樣的業務操做。
雖然 REST 看起來仍是很簡單的,實際上咱們每每須要提供一個 REST 框架,讓其實現先後端分離架構,讓開發人員將精力集中在業務上,而並不是那些具體的技術細節。下面咱們將使用 Java 技術來實現這個 REST 框架,總體框架會基於 Spring 進行開發。
使用 REST 框架實現先後端分離架構,咱們須要首先肯定返回的 JSON 響應結構是統一的,也就是說,每一個 REST 請求將返回相同結構的 JSON 響應結構。不妨定義一個相對通用的 JSON 響應結構,其中包含兩部分:元數據
與 返回值
,其中,元數據表示操做是否成功與返回值消息等,返回值對應服務端方法所返回的數據。該 JSON 響應結構以下:
{
"meta": { "success": true, "message": "ok" }, "data": ... }
爲了在框架中映射以上 JSON 響應結構,咱們須要編寫一個 Response
類與其對應:
public class Response { private static final String OK = "ok"; private static final String ERROR = "error"; private Meta meta; private Object data; public Response success() { this.meta = new Meta(true, OK); return this; } public Response success(Object data) { this.meta = new Meta(true, OK); this.data = data; return this; } public Response failure() { this.meta = new Meta(false, ERROR); return this; } public Response failure(String message) { this.meta = new Meta(false, message); return this; } public Meta getMeta() { return meta; } public Object getData() { return data; } public class Meta { private boolean success; private String message; public Meta(boolean success) { this.success = success; } public Meta(boolean success, String message) { this.success = success; this.message = message; } public boolean isSuccess() { return success; } public String