MVC模式概述
? MVC是三個單詞的縮寫,分別為:
模型(Model),視圖(View)和控制Controller)。
MVC模式的目的就是實現(xiàn)Web系統(tǒng)的職能分工。
? Model層實現(xiàn)系統(tǒng)中的業(yè)務邏輯,通常可以用JavaBean或EJB來實現(xiàn)。
? View層用于與用戶的交互,通常用JSP來實現(xiàn)。
? Controller層是Model與View之間溝通的橋梁,它可以分派用戶的請求并選擇恰當?shù)囊晥D以用于顯示,同時它也可以解釋用戶的輸入并將它們映射為模型層可執(zhí)行的操作。
MVC模式的好處
? 各施其職,互不干涉
在MVC模式中,三個層各施其職,所以如果一旦哪一層的需求發(fā)生了變化,就只需要更改相應的層中的代碼而不會影響到其它層中的代碼。
? 有利于開發(fā)中的分工
在MVC模式中,由于按層把系統(tǒng)開,那么就能更好的實現(xiàn)開發(fā)中的分工。網(wǎng)頁設計人員可以進行開發(fā)視圖層中的JSP,對業(yè)務熟悉的開發(fā)人員可開發(fā)業(yè)務層,而其它開發(fā)人員可開發(fā)控制層。
? 有利于組件的重用
分層后更有利于組件的重用。如控制層可獨立成一個能用的組件,視圖層也可做成通用的操作界面。
不同JSP構造的應用
為什么要組合使用servlet & JSP?
? 典型的做法:使用JSP來簡化HTML內(nèi)容的開發(fā)與維護
? 對于簡單的動態(tài)代碼,使用由腳本元素調(diào)用JAVA代碼來完成。
? 對于稍微復雜一些的應用,則可使用腳本元素調(diào)用定制的類來完成。(即所謂的help類)
? 對于比較復雜的應用,則使用JAVA BEAN和定制標簽
? 但,這些是不夠的
? 對于復雜的處理過程,從JSP開始做起會難以處理。
? JSP除了能夠帶來將實際的代碼隔離成單獨的類、bean、和定制標簽的便利以外,它所隱含的假定是單個頁面給出單個基本視圖。
對MVC的誤解
? 必須采用復雜的框架
? 框架有時很有用
? Struts
? JavaServer Faces (JSF)
? 但并非必需!
? 對于大多簡單或者適度復雜的應用來說,使用內(nèi)建的RequestDispatcher就能夠很好地實現(xiàn)MVC
? MVC影響整個系統(tǒng)的設計
? 我們可以用MVC來處理單個請求
? 可以將它認為是MVC方案,而非MVC框架。
? 也被稱為是模型2方案
用RequestDispatcher實現(xiàn)MVC
? 1. 定義用以表示數(shù)據(jù)的java bean
? 2. 使用一個servlet處理請求
? servlet讀取請求參數(shù),檢查數(shù)據(jù)的缺失或異常等。
? 3. 填充bean
? 該servlet調(diào)用業(yè)務邏輯或數(shù)據(jù)訪問代碼得到最終的結果。得出的結果被放在第一步中定義的bean中。
? 4. 將bean存儲在請求,會話或servlet的上下文中
? 該servlet調(diào)用請求、會話或servlet上下文對象的setAttribute存儲表達請求結果的bean的引用。
? 5. 將請求轉發(fā)到JSP頁面
? 該servlet確定哪個JSP頁面適合于處理當前的情形,并使用RequestDispatcher的forward方法將控制轉移到那個頁面。
?
? 6. 從bean中提取數(shù)據(jù)
? JSP頁面使用jsp:useBean和與第4步匹配的位置訪問之前存儲的bean,然后使用jsp:getProperty輸出bean的屬性。
? JSP頁面并不創(chuàng)建或修改bean;它只是提取并顯示由servlet創(chuàng)建的數(shù)據(jù)。
jsp:useBean在MVC中的使用與在
獨立JSP頁面中有什么不同
? JSP頁面不應該創(chuàng)建對象
? 應該由servlet創(chuàng)建所有的數(shù)據(jù)對象。因此,為了保證JSP頁面不會創(chuàng)建對象,我們應該使用<jsp:useBean ... type=“package.Class” />
而不是
<jsp:useBean ... class="package.Class" />
? JSP頁面也不應該修改已有的對象
? 因此,我們應該只使用jsp:getProperty,不使用jsp:setProperty
。 提示:jsp:useBean的scope選項
? request
? <jsp:useBean id="..." type="..." scope="request" />
? session
? <jsp:useBean id="..." type="..." scope="session" />
? application
? <jsp:useBean id=".." type=".." scope="application" />
? page
? <jsp:useBean id=“...” type=“...” scope=“page” />
或者僅僅使用<jsp:useBean id="..." type="..." />
? MVC (Model 2)構架不使用這個scope。
不同數(shù)據(jù)共享方式
? 向用戶顯示一個隨機的數(shù)字。
? 由于每次請求應該產(chǎn)生新的數(shù)字,因而基于請求的共享是恰當?shù)摹?nbsp;
?
? 顯示用戶的姓和名
? 數(shù)據(jù)要為每個客戶存儲,因而基于會話的共享比較適用。
?
? 顯示一個指定長度的質(zhì)數(shù)。
? 數(shù)據(jù)在多個客戶間共享,因此,基于應用的共享比較恰當。
基于請求的數(shù)據(jù)共享
? Servlet
ValueObject value = new ValueObject(...);
request.setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
? JSP
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="request" />
<jsp:getProperty name="key" property="someProperty" />
基于會話的數(shù)據(jù)共享
? Servlet
ValueObject value = new ValueObject(...);
HttpSession session = request.getSession();
session.setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
? JSP
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="session" />
<jsp:getProperty name="key" property="someProperty" />
基于ServletContext的數(shù)據(jù)共享
? Servlet
synchronized(this)
{
ValueObject value = new ValueObject(...);
getServletContext().setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
}
? JSP
<jsp:useBean id="key" type="somePackage.ValueObject“ scope="application" />
<jsp:getProperty name="key" property="someProperty" />
JSP頁面中的相對URL
? 問題:
? 使用請求分配器進行的轉發(fā)對客戶來說是透明的。初始的URL是瀏覽器惟一知道的URL。
? 為什么這會比較重要?
? 瀏覽器會如何處理類似下面的這些標簽:
<IMG SRC="foo.gif" …>
<LINK REL=STYLESHEET
HREF="JSP-Styles.css" TYPE="text/css">
<A HREF="bar.jsp">…</A>
? 答案:瀏覽器將會把它們看作是相對于servlet的URL
?
? 最簡單的解決方案:
? 使用以斜杠開始的URL
Summary
? MVC (Model 2) 方式適用于:
? 單次提交會產(chǎn)生多個基本外觀。
? 幾個頁面擁有大量公共的處理過程。
? 需要為同樣的數(shù)據(jù)提供多個視圖的應用程序,它很好地實現(xiàn)了數(shù)據(jù)層與表示層的分離,特別適用于開發(fā)與用戶圖形界面有關的應用程序
?
? 構架
? 由一個servlet應答初始的請求
? Servlet完成實際的數(shù)據(jù)處理并將結果存儲在bean中
? Bean存儲在HttpServletRequest, HttpSession, 或ServletContext中
? Servlet使用RequestDispatcher的forward方法將請求轉發(fā)到JSP頁面
? JSP頁面通過使用jsp:useBean和相應的作用域(request, session, application)從bean中讀出數(shù)