今天我們一起來(lái)了解一下關(guān)于JSP應(yīng)用的JSP的隱式對(duì)像和MVC設(shè)計(jì)模式。
首先我們先來(lái)說(shuō)一下JSP的隱式對(duì)象:JSP隱式對(duì)象是Web容器加載的一組類(lèi)的實(shí)例。它是可以直接在JSP頁(yè)面使用的對(duì)象。分為4個(gè)主要類(lèi)別:1、 輸入和輸出對(duì)象:控制頁(yè)面的輸入和輸出(request、response、out)。
2、 作用域通信對(duì)象:檢索與JSP頁(yè)面的Servlet相關(guān)的信息(session、application、pageContext)。
3、 Servlet對(duì)象:提供有關(guān)頁(yè)面環(huán)境的信息(page、config)。
4、 錯(cuò)誤對(duì)象:處理頁(yè)面中的錯(cuò)誤(exception)。
我們先了解一下輸入和輸出對(duì)象:request對(duì)象:request隱式對(duì)象表示客戶(hù)端的請(qǐng)求,包含了所有的請(qǐng)求信息,常用的方法:voidsetContentType(String name):設(shè)置作為響應(yīng)生成的內(nèi)容的類(lèi)型和字符編碼。
void sendRedirect(Stringname):發(fā)送一個(gè)響應(yīng)給瀏覽器,指示其應(yīng)請(qǐng)求另一個(gè)URL(會(huì)丟失數(shù)據(jù),跳轉(zhuǎn)后不再執(zhí)行sendRedirect方法下面的代碼。
out對(duì)象:在JSP頁(yè)面中應(yīng)使用out隱式對(duì)象來(lái)向客戶(hù)端發(fā)送文本形式的實(shí)體內(nèi)容。
out對(duì)象是通過(guò)調(diào)用pageContext對(duì)象的getOut方法返回的,其作用和用法與ServletResponse.getWriter方法返回的PrintWriter對(duì)象非常相似。
JSP頁(yè)面中的out隱式對(duì)象的類(lèi)型為JspWriter,JspWriter相當(dāng)于一種帶緩存功能的PrintWriter,設(shè)置JSP頁(yè)面的page指令的buffer屬性可以調(diào)整它的緩存大小,甚至關(guān)閉它的緩存。
JSP頁(yè)面中的out隱式對(duì)象相當(dāng)于插入到ServletResponse.getWriter方法返回的PrintWriter對(duì)象前面的緩沖包裝類(lèi)對(duì)象。
只有向out對(duì)象中寫(xiě)入了內(nèi)容,且滿(mǎn)足如下任何一個(gè)條件時(shí),out對(duì)象才去調(diào)用ServletResponse.getWriter方法,并通過(guò)該方法返回的PrintWriter對(duì)象將out對(duì)象的緩沖區(qū)中的內(nèi)容真正寫(xiě)入到Servlet引擎提供的緩沖區(qū)中:設(shè)置page指令的buffer屬性關(guān)閉了out對(duì)象的緩存功能寫(xiě)入到out對(duì)象中的內(nèi)容充滿(mǎn)了out對(duì)象的緩沖區(qū)整個(gè)JSP頁(yè)面結(jié)束作用域通信對(duì)象:pageContext對(duì)象是javax.servlet.jsp.PageContext類(lèi)的實(shí)例對(duì)象,javax.servlet.jsp.PageContext類(lèi)是javax.servlet.jsp.JspContext的子類(lèi)。
pageContext對(duì)象是通過(guò)調(diào)用JspFactory.getPageContext方法返回的。
pageContext對(duì)象封裝了當(dāng)前JSP頁(yè)面的運(yùn)行信息,它提供了返回JSP頁(yè)面的其他隱式對(duì)象的方法。
在JSP頁(yè)面中只需將pageContext對(duì)象傳遞給某個(gè)Java類(lèi)的實(shí)例對(duì)象,在該Java對(duì)象中就可以訪(fǎng)問(wèn)和調(diào)用其他隱式對(duì)象的功能了。
pageContext對(duì)象使用戶(hù)可以訪(fǎng)問(wèn)當(dāng)前頁(yè)面作用域中定義的所有隱式對(duì)象。
getException()方法返回exception隱式對(duì)象getPage()方法返回page隱式對(duì)象getRequest()方法返回request隱式對(duì)象getResponse()方法返回response隱式對(duì)象getServletConfig()方法返回config隱式對(duì)象getServletContext()方法返回application隱式對(duì)象getSession()方法返回session隱式對(duì)象getOut()方法返回out隱式對(duì)象PageContext類(lèi)中定義了一個(gè)setAttribute方法來(lái)將對(duì)象存儲(chǔ)進(jìn)pageContext對(duì)象內(nèi)部的一個(gè)HashMap對(duì)象中,同時(shí)也定義了一個(gè)getAttribute方法來(lái)檢索存儲(chǔ)在該HashMap對(duì)象中的對(duì)象。
void setAttribute(String name, Object value)
Object getAttribute(String name)
(注意:PageContext類(lèi)除了可以存儲(chǔ)和檢索自身中的屬性對(duì)象外,還定義了可以存儲(chǔ)和檢索其他域范圍內(nèi)的屬性對(duì)象的方法。)
在application、session、request、pageContext對(duì)象中都可以調(diào)用setAttribute方法和getAttribute方法來(lái)設(shè)置和檢索各自域范圍內(nèi)的屬性。
存儲(chǔ)在application對(duì)象中的屬性可以被同一個(gè)WEB應(yīng)用程序中的所有Servlet和JSP頁(yè)面訪(fǎng)問(wèn)。
存儲(chǔ)在session對(duì)象中的屬性可以被屬于同一個(gè)會(huì)話(huà)的所有Servlet和JSP頁(yè)面訪(fǎng)問(wèn)。
存儲(chǔ)在request對(duì)象中的屬性可以被屬于同一個(gè)請(qǐng)求的所有Servlet和JSP頁(yè)面訪(fǎng)問(wèn),例如使用PageContext.forward和PageContext.include方法連接起來(lái)的多個(gè)Servlet和JSP頁(yè)面。
存儲(chǔ)在pageContext對(duì)象中的屬性?xún)H可以被當(dāng)前JSP頁(yè)面的當(dāng)前響應(yīng)過(guò)程中調(diào)用的各個(gè)組件訪(fǎng)問(wèn),例如,正在響應(yīng)當(dāng)前請(qǐng)求的JSP頁(yè)面和它調(diào)用的各個(gè)自定義標(biāo)簽類(lèi)。
PageContext類(lèi)中還提供了對(duì)各個(gè)域范圍的屬性進(jìn)行統(tǒng)一管理的方法,以簡(jiǎn)化對(duì)各個(gè)域范圍內(nèi)的屬性的訪(fǎng)問(wèn)。
public void setAttribute(java.lang.String name,java.lang.Object value,int scope)
public java.lang.Object getAttribute(String name,int scope)
其中參數(shù)scope的取值為:PageContext.APPLICATION_SCOPE PageContext.SESSION_SCOPE PageContext.REQUEST_SCOPE PageContext.PAGE_SCOPE publicvoid removeAttribute(String name)
publicvoid removeAttribute(String name,int scope)
getAttributeNamesInScope方法findAttribute方法PageContext類(lèi)中定義了一個(gè)forward方 法和兩個(gè)include方法來(lái)分別簡(jiǎn)化和替代RequestDispatcher.forward方法和 RequestDispatcher.include方法的調(diào)用:public void forward(java.lang.String relativeUrlPath)throwsjavax.servlet.ServletException,java.io.IOException public voidinclude(java.lang.String relativeUrlPath)
throwsjavax.servlet.ServletException,java.io.IOException public void include(java.lang.String relativeUrlPath,boolean flush)throws javax.servlet.ServletException,java.io.IOException傳遞給這些方法的資源路徑都只能是相對(duì)路徑,如 果路徑以“/”開(kāi)頭,表示相對(duì)于當(dāng)前WEB應(yīng)用程序的根目錄,否則,表示相對(duì)于當(dāng)前JSP所映射到的訪(fǎng)問(wèn)路徑。
session對(duì)象session對(duì)象表示用戶(hù)的會(huì)話(huà)狀況,用此項(xiàng)機(jī)制可以輕易識(shí)別每一個(gè)用戶(hù),能保存和跟蹤用戶(hù)的會(huì)話(huà)狀態(tài)。session對(duì)象最常用的方法:void setAttribute(String name, Object value)
void getAttribute(String name)
application對(duì)象application對(duì)象作用于整個(gè)應(yīng)用程序,所有的客戶(hù)端窗口都可以共享該對(duì)象,從服務(wù)器開(kāi)始就存在,直到服務(wù)器關(guān)閉為止。application對(duì)象最常用的方法:void setAttribute(String name, Object value):以名稱(chēng)/值的方式,將一個(gè)對(duì)象的值存放到application中(存的值的類(lèi)型為Object)。
void getAttribute(String name):根據(jù)名稱(chēng)去獲取application中存放對(duì)象的值(獲取的值的類(lèi)型為Object)。
設(shè)置context初始參數(shù)。在web.xml文件適當(dāng)?shù)奈恢迷黾觾?nèi)容:
<context-param> <param-name>website</param-name> <param-value>www.sohu.com</param-value> </context-param>
在JSP頁(yè)面中,使用applicatin對(duì)象的getInitParameter()方法可以取得 website參數(shù)對(duì)應(yīng)的參數(shù)值。在Servlet中用ServletContext對(duì)象的同名方法獲得參數(shù)值。
使用log()方法記錄日志。
可以使用application對(duì)象提供的log()方法,實(shí)現(xiàn)日志記錄功能,在Tomcat服務(wù)器中,記錄的日志都保存在Tomcat根目錄的logs目錄下。日志內(nèi)容分成不同文件進(jìn)行記錄。
Servlet對(duì)象:page對(duì)象page對(duì)象提供對(duì)網(wǎng)頁(yè)上定義的所有對(duì)象的訪(fǎng)問(wèn)。page對(duì)象表示頁(yè)面本身,它是java.lang.Object類(lèi)的一個(gè)實(shí)例。
config對(duì)象config對(duì)象存儲(chǔ)Servlet的一些初始信息。config對(duì)象是 javax.servlet.ServletConfig接口的一個(gè)實(shí)例,ServletConfig接口提供方法以檢索Servlet初始化參數(shù)。 config對(duì)象表示編譯JSP頁(yè)面的Servlet初始化數(shù)據(jù)的配置。
錯(cuò)誤對(duì)象exception:exception對(duì)象處理JSP頁(yè)面中的錯(cuò)誤:printStackTrace()方法用于顯示異常的堆棧跟蹤 在上面我們以經(jīng)介紹了JSP的隱式對(duì)象,下面我們來(lái)講一下MVC的設(shè)計(jì)模式:在開(kāi)發(fā)一個(gè)軟件之前,必須先設(shè)計(jì)好其架構(gòu),一個(gè)基本的架構(gòu)思想是將軟件分成不 同的模塊,問(wèn)題的關(guān)鍵就是如何劃分模塊。
MVC(模型-視圖-控制器)是20世紀(jì)80年代為Smalltalk-80編程語(yǔ)言發(fā)明的一種軟件設(shè)計(jì)模式,它是一種分離業(yè)務(wù)邏輯與顯示界面的設(shè)計(jì)方法。
MVC的模型(Model)部分負(fù)責(zé)管理程序的業(yè)務(wù)數(shù)據(jù),視圖(View)部分負(fù)責(zé)顯示界面,控制器(Controller)部分則負(fù)責(zé)與用戶(hù)進(jìn)行交互(接受請(qǐng)求和選擇響應(yīng)視圖)。
JSP的設(shè)計(jì)模式:JSP規(guī)范給出了使用JSP頁(yè)面構(gòu)建Web應(yīng)用程序的兩個(gè)方案—JSP模式1和模式2.兩個(gè)模式的區(qū)別在于處理的位置。
JSP模式1(JSP + JavaBean):在模式1的體系結(jié)構(gòu)中,JSP頁(yè)面負(fù)責(zé)處理請(qǐng)求并將響應(yīng)發(fā)送給客戶(hù)端。
Model1的典型的交換過(guò)程:首先用戶(hù)通過(guò)瀏覽器調(diào)用Web應(yīng)用中的JSP頁(yè)面,發(fā)送request請(qǐng)求,JSP頁(yè)面接收到瀏覽器的請(qǐng)求后,通過(guò)調(diào)用JavaBean對(duì)象的方法從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù),然后JSP頁(yè)面再把數(shù)據(jù)返回瀏覽器,最終在瀏覽器中顯示相應(yīng)的信息。
優(yōu)點(diǎn):非常適合小型Web項(xiàng)目的快速開(kāi)發(fā);對(duì)Java Web開(kāi)發(fā)人員的技術(shù)要求不高。
弊端:Java和HTML柔和在一起,在Web項(xiàng)目開(kāi)發(fā)的后期和維護(hù)階段會(huì)造成很大的困難。
JSP模式2(MVC):模式2體系結(jié)構(gòu)集成使用了Servlet和JSP頁(yè)面。在該模式中,JSP頁(yè)面用于表示層,并且Servlet負(fù)責(zé)處理各類(lèi)任務(wù)。
Model2交互過(guò)程:首先用戶(hù)通過(guò)瀏覽器向Web應(yīng)用中的Servlet發(fā)送請(qǐng)求,Servlet接收到請(qǐng)求后實(shí)例化JavaBean對(duì)象, 調(diào)用JavaBean對(duì)象的方法,JavaBean對(duì)象返回從數(shù)據(jù)庫(kù)中讀取的數(shù)據(jù),Servlet選擇合適的JSP,并且把從數(shù)據(jù)庫(kù)中讀取的數(shù)據(jù)通過(guò)這個(gè) JSP進(jìn)行顯示,最后JSP頁(yè)面把最終的結(jié)果返回給瀏覽器。
優(yōu)點(diǎn):業(yè)務(wù)邏輯和表示內(nèi)容得到了很好的分離,這種開(kāi)發(fā)方式適合多人合作開(kāi)發(fā)大型的項(xiàng)目。
弊端:Web項(xiàng)目開(kāi)發(fā)的難度加大了,對(duì)開(kāi)發(fā)人員的技術(shù)要求也提高了。
Servlet作為一個(gè)控制器,負(fù)責(zé)處理請(qǐng)求并創(chuàng)建JSP頁(yè)面所需的任何Bean.該控制器也負(fù)責(zé)確定將該請(qǐng)求傳遞到哪個(gè)JSP頁(yè)面。JSP頁(yè)面檢索Servlet創(chuàng)建的對(duì)象,并提取動(dòng)態(tài)內(nèi)容插入在一個(gè)模板中。
注意:由于模型位于web服務(wù)器端,而最終的視圖位于用戶(hù)瀏覽器端,只有瀏覽器發(fā)出請(qǐng)求后,服務(wù)器才會(huì)做出響應(yīng),沒(méi)有請(qǐng)求就沒(méi)有響應(yīng),所以在 web應(yīng)用中難以實(shí)現(xiàn)模型的“狀態(tài)改變通知”事件,視圖不能隨著模型的改變而自動(dòng)更新。由于在web應(yīng)用中無(wú)法完全實(shí)現(xiàn)真正意義上的mvc模型,模式2只 能算是mvc設(shè)計(jì)模式的一種變體,有人干脆將他稱(chēng)之為“webMVC”。
更多信息請(qǐng)查看IT技術(shù)專(zhuān)欄