servlet体系
為什么80%的碼農都做不了架構師?>>> ??
?抽象機制:
?
?
?
我們知道 Java Web 應用是基于Servlet 規范運轉的,那么 Servlet 本身又是如何運轉的呢?為何要設計這樣的體系結構
圖1:
?
從 上圖可以看出Servlet 規范就是基于這幾個類運轉的,與 Servlet 主動關聯的是三個類,分別是 ServletConfig、ServletRequest 和 ServletResponse。這三個類都是通過容器傳遞給 Servlet 的,其中 ServletConfig 是在 Servlet 初始化時就傳給 Servlet 了,而后兩個是在請求達到時調用 Servlet 時傳遞過來的。我們很清楚 ServletRequest 和 ServletResponse 在 Servlet 運行的意義,但是 ServletConfig 和 ServletContext 對 Servlet 有何價值?仔細查看 ServletConfig 接口中聲明的方法發現,這些方法都是為了獲取這個Servlet 的一些配置屬性,而這些配置屬性可能在 Servlet 運行時被用到。而 ServletContext 又是干什么的呢? Servlet 的運行模式是一個典型的“握手型的交互式”運行模式。所謂“握手型的交互式”就是兩個模塊為了交換數據通常都會準備一個交易場景,這個場景一直跟隨個這個 交易過程直到這個交易完成為止。這個交易場景的初始化是根據這次交易對象指定的參數來定制的,這些指定參數通常就會是一個配置類。所以對號入座,交易場景 就由 ServletContext 來描述,而定制的參數集合就由ServletConfig 來描述。而 ServletRequest 和 ServletResponse 就是要交互的具體對象了,它們通常都是作為運輸工具來傳遞交互結果。
?
ServletConfig 是在 Servlet init 時由容器傳過來的,那么ServletConfig 到底是個什么對象呢?
下圖是ServletConfig 和 ServletContext 在 Tomcat 容器中的類關系圖。
圖 6. ServletConfig 在容器中的類關聯圖
上 圖可以看出StandardWrapper 和 StandardWrapperFacade 都實現了 ServletConfig 接口,而 StandardWrapperFacade 是 StandardWrapper 門面類。所以傳給 Servlet 的是 StandardWrapperFacade 對象,這個類能夠保證從StandardWrapper 中拿到 ServletConfig 所規定的數據,而又不把 ServletConfig 不關心的數據暴露給 Servlet。
同樣ServletContext 也與 ServletConfig 有類似的結構,Servlet 中能拿到的 ServletContext 的實際對象也是 ApplicationContextFacade 對象。ApplicationContextFacade 同樣保證 ServletContex 只能從容器中拿到它該拿的數據,它們都起到對數據的封裝作用,它們使用的都是門面設計模式。
通過ServletContext 可以拿到 Context 容器中一些必要信息,比如應用的工作路徑,容器支持的 Servlet 最小版本等。
>>servletContext:
一個servlet上下文是servlet引擎提供用來服務于Web應用的接口,在web項目之前被創建,由交易的對象指定的參數進行初始化(他與tomcat的整個容器有關)。
內涵:
1.一個web應用只有一個servletContext,并且生命周期伴隨著整個web應用,所以servletContext的數據是共享的,能在多個servlet中使用。
2.servletContext能獲取web應用的配置信息等,ServletContext 是一個接口
都是由容器來實例化產生對象,傳遞給servletConfig
例:ServletConfig:
public ServletContext getServletContext();
3. ServletContext 是負責和 Servlet 的上文和下文交互,上面和 Servlet 容器交互,下面和Servlet 中的請求和相應進行交互
例:
ServletContext? application=sce.getServletContext();//公共的對象
?
聯系:服務器的四大域對象:裝數據的空間
?PageContext:只在一個頁面內有效
Request:一次請求范圍內有效 相對ie而言
?Session: 與瀏覽器有關,瀏覽器關閉session銷毀。
?Application:應用對象,在應用啟動的時候產生,應用關閉的時候注銷
>>servletConfig:
servletConfig是給servlet指定配置一些屬性的類,在容器對servlet初始化的時候會將對servlet所配置的參數(web.xml),記錄到servletConfig中。
代碼參考(servlet api.html)
內涵:
1.? servletConfig由容器來實例化,本身是個接口,是由容器產生一格 ServletConfig 的實現類的對象,然后傳遞給 Servlet
例:
public void init(ServletConfig config) throws ServletException {
?????? ?System.out.println("初始化 ....init");
?????? //取參數
?????? ?pwd=config.getInitParameter("pwd");
??? }
Servlet 中定義的兩個 ServletRequest 和 ServletResponse 它們實際的對象又是什么呢?,我們在創建自己的 Servlet 類時通常使用的都是 HttpServletRequest 和 HttpServletResponse,它們繼承了 ServletRequest 和 ServletResponse。為何 Context 容器傳過來的 ServletRequest、ServletResponse 可以被轉化為 HttpServletRequest 和 HttpServletResponse 呢?
圖 7.Request 相關類結構圖
上 圖是 Tomcat 創建的 Request 和 Response 的類結構圖。Tomcat 一接受到請求首先將會創建org.apache.coyote.Request 和 org.apache.coyote.Response,這兩個類是 Tomcat 內部使用的描述一次請求和相應的信息類它們是一個輕量級的類,它們作用就是在服務器接收到請求后,經過簡單解析將這個請求快速的分配給后續線程去處理,所 以它們的對象很小,很容易被 JVM 回收。接下去當交給一個用戶線程去處理這個請求時又創建 org.apache.catalina.connector. Request 和org.apache.catalina.connector. Response 對象。這兩個對象一直穿越整個Servlet 容器直到要傳給 Servlet,傳給Servlet 的是 Request 和 Response 的門面類 RequestFacade 和 RequestFacade,這里使用門面模式與前面一樣都是基于同樣的目的——封裝容器中的數據。一次請求對應的 Request 和 Response 的類轉化如下圖所示:
圖 8.Request 和Response 的轉變過程
?
1.ServletContext與ServletConfig:
ServletContext是Servlet容器上下文環境對象,定義一組方法,servlet 使用這些方法與其 servlet 容器進行通信,例如,獲取文件的 MIME 類型、分發請求或寫入日志文件
每個web應用都有且僅有一個ServletContext對象,這個對象在所有的Servlet都可以使用。
?
ServletContext 對象包含在ServletConfig 對象中,ServletConfig 對象在初始化Servlet 時由Web 服務器提供給Servlet。?
?
ServletContext在jsp中用application內置對象來表示,而在Servlet中通過調用方法
ServletContext sc = getServletContext();
來獲取。?
?
因為一個web應用就一個ServletContext 對象,因此可以使用ServletContext 來做一些全局性的屬性設置等。比如網站訪問計數器等等。下面給出一個簡單的頁面計數器:?
?<body><%Integer x = (Integer) application.getAttribute("num");if (x == null) {application.setAttribute("num", 1);}else{application.setAttribute("num", ++x);}out.println("您是第"+x+"位訪客!");%></body>獲取資源絕對路徑:
getServletContext().getRealPath("/");
?
轉載于:https://my.oschina.net/wii01/blog/983752
總結
- 上一篇: 从无到有写一个运维APP(三)完结篇
- 下一篇: PurchaseOrder创建成功,然而