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