MVC 是一個老生常談的東西早已不是什麼稀罕物件,不過在這裏仍是扒一扒到底都有多少種 MVC。javascript
先說最經典的 MVC,一個請求控制器的請求,負責讀取數據,而後將數據派發到試圖上。如圖:html
在經典 MVC 中,能夠看到咱們請求的頁面並非真正的頁面,而是一個控制器。具體顯示的頁面由這個控制器來決定,大名頂頂的 struts 框架就是這樣一種模式。然而,一般爲了記憶方便,基於這種經典模式的 MVC 咱們一般是把 Controller 的名字起的和 View 同樣。前端
這種模式下,Controller 的職責主要有兩個:一、肯定顯示的最終頁面。二、執行頁面邏輯準備相關數據。java
在 View 中使用的數據是來自 Controller 給予的。ajax
例如「判斷當前用戶是否登陸,若是登陸則展示用戶詳細信息,若是未登陸則展示登陸界面」。這種場景比較適合這種模式。json
這是 MVC 的一個變版,在這種模式中 View 的地位被提高到 Controller 以前。也就是說請求是先獲得了要顯示的頁面,而頁面中的數據的獲取邏輯被後置的 Controller 提供。後端
這種模式下,Controller 的職責變得只有一個,那就是:執行頁面邏輯準備相關數據。視圖前置這種模式在職責上更加清晰,可是它失去了對頁面展示的控制。設計模式
一般在某個數據集中展示的地方會有這種模式的身影,例如:List 頁面,在List 頁面一般伴隨着查詢、分頁。這種頁面中頁面自己通常是不會有太大的變化,更多的是後臺的數據提取邏輯。瀏覽器
其實這種 MVC 咱們也並不陌生,jsp + bean 就是這樣一種形式。mvc
這是 視圖前置 MVC 的一個變版,它的工做模式沒有太大的變化。不一樣的是 View 被進一步前置到 瀏覽器中,經過 javascript 經過 ajax 的方式訪問 Controller。
這種模式下,通常有兩類工程師共同開發一個應用程序,他們是:前段工程師、後段工程師。
這種模式的優勢在於,先後端開發工程師,只須要協議數據交換格式。便可開始各自的開發工做。也是最多見的一種模式。這也是先後端分離的一種體現。
咱們先以 Controller 爲例子進行說明,下面是使用 Hasor 開發的 Controller。
@MappingTo("/index.htm") public class Index { public void execute(RenderData data) { data.put("data", new UserData()); } }
在例子中,咱們簡單的把 UserData 這個數據寫入到 RenderData 對象中。最後在頁面渲染的時候再把這個對象拿出來。
固然您也能夠像這樣,直接把對象塞到 Request 中。
data.getHttpRequest().setAttribute("data", new UserData());
或者乾脆更直接一點
@MappingTo("/index.htm") public class Index { public void execute(HttpServletRequest request) { request.setAttribute("data", new UserData()); } }
除了前面三種方式以外,Haosr 還學習優秀的 JFinal 框架。您能夠繼承一個類,經過繼承類的各類工具方法來實現數據的設置,例如:
@MappingTo("/index.htm") public class Index extends WebController { public void execute() { this.putData("data", new UserData()); // or this.setAttr("data", new UserData()); } }
具體想用哪一種方式,你喜歡就好。
咱們能夠經過這種方式實現 經典MVC模式。以下:
@MappingTo("/index.htm") public class Index extends WebController { public void execute() throws ServletException, IOException { // 方式 1 this.setAttr("data", new UserData()); getRequest().getRequestDispatcher("/userinfo.htm").forward(getRequest(),getResponse()); // 方式 2 this.setAttr("data", new UserData()); getResponse().sendRedirect("/userinfo.htm"); // 方式 3 this.setAttr("data", new UserData()); renderTo("/userInfo.htm"); } }
你也能夠這樣:
@MappingTo("/index.htm") public class Index { public void execute(RenderData data) { data.put("data", new UserData()); data.viewName("/userInfo.htm"); } }
前面提到過,前置 mvc 就是一種 jsp + bean 的模式。那麼索性就 「JSP + Bean」把。先看負責獲取數據的 ManagerBean,爲了減小每次獲取 UserInfo 時重複建立 Manager 的問題。下面還特地添加了@Singleton註解實現了單例。
@Singleton public class UserManager { public UserInfo getUserById(long userId) { return new UserInfo(); } }
接下來真的 JSP 登場,爲了JSP能夠訪問到咱們的 Bean,你須要引入 Hasor 的 JSP 標籤庫。接下來經過 hs 庫訪問咱們的 ManagerBean 獲取 UserInfo。
<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> <%@ taglib prefix="hs" uri="http://project.hasor.net/hasor/schema/jstl" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html lang="zh-CN"> <body> <hs:findType var="userManager" type="net.demo.hasor.manager.UserManager"/> <c:set var="userInfo" scope="request" value="${userManager.getUserById(1234)}"/> 姓名:${userInfo.name}<br/> 年齡:${userInfo.age}<br/> </body> </html>
下面這個是運行結果:
在這種模式下咱們須要藉助一個 Controller 幫咱們把數據透給前端 js 程序。瀏覽器經過請求咱們的接口 Controller 來獲取數據。接口 Controller 負責返回 json 數據。
@MappingTo("/getUserInfo.json") public class GetUserInfo { public UserInfo execute(RenderData data) { return new UserInfo(); } }
訪問URL運行結果:
其實這種模式,本質上仍是經典MVC模式。