什么是上下文?什么是資源名,請求流程是怎么樣的?
昨晚我在群里問了個問題,沒人回答,也許是我過於執着,還是要說一說!對我個人而言也是一種學習態度,課上講的專業術語,老師不講,自己也要搞明白,這倒底是什么,任何老師都會在課上講,上下文對象,資源路徑等等!
那么,http://localhost:80/day3/hello 這個路徑哪個是上下文,哪個是資源名稱?
答案是:上下文 /day3 資源名 /hello
第2個問題,如何通過上下文和資源名找到對應的servlet?
這個就要從發布項目說起,我們在eclipse中將項目同步或發布到tomcat發生了什么?好下圖的操作,倒底給tomcat帶去什么樣的變化!
可以說每發布一個項目,都會生成一個上下文配置,我們可以試一個發布一個項目,然后到tomcat 下的conf中找到server.xml,打開看一下,會有類似這樣的節點產生:
<Context docBase="D:\JavaApps\Servlet\webapp" path="day3"/>
<Context docBase="D:\JavaApps\Servlet\webapp1" path="day4"/>
每一行代表一個項目!其中docBase表示真實項目路徑 path代表上下文也就是訪問的根路徑!
知道了上面這個問題,我們就可以知道tomcat如何解析了!
tomcat 解析流程:
1、瀏覽器先發送請求:http://localhost:80/day3/hello
2、DNS解析域名
3、Tomcat解析請求:/day3/hello 得到上下文 /day3 資源名 /hello
4、解析Tomcat根/conf/server.xml文件,獲取其中所有的上下文元素,並找到path屬性為/day3的元素,再讀取該元素,再獲取docBase屬性值,該屬性值就是當前訪問的WEB項目的根路徑
5、從該web的根路徑/WEB-INF下找到web.xml文件
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.gwd.aa.He</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
6、讀取web.xml文件,獲取所有的
7、通過/hello,找到當前Servlet的全限定名com.gwd.aa.He
8、從Servlet的實例緩沖池中去獲取com.gwd.aa.He對應的對象.(這就是為什么init只執行一次的原因)
Map<String,Servlet> cache = .....;
Servlet obj = cache.get("com.gwd.aa.He");
if(obj == null{
//第一次請求:GOTO 9.
}else{
//非第一次請求:GOTO 12;
9、使用反射創建Servlet對象.
Servlet obj = Class.forName("com.gwd.aa.He").newInstance();
10、把創建的Servlet對象,存儲到Servlet實例緩存池中,供下一次請求使用.
cache.put("com.gwd.aa.He",obj);
11、容器創建ServletConfig對象,並調用init方法,來完成初始化操作.
obj.init(config);
12、容器創建ServletRequest和ServletResponse對象,並調用service方法,處理請求.
obj.service(req,resp);
13、在service方法中,對當前請求的客戶端做相應.
做doget和dopost處理(底程是個模板方法),這個可以自己寫個模板方法體驗一下!
Servletcontext對象和ServletConfig對象的區別
前者當前項目有效,后者對當前servlet有效,拿xml初始參數來說ServletConfig只能獲取當前Servlet的參數,而Servletcontext獲取的是整個項目共有的設置,我們開發中一般用Servletcontext,因為ServletConfig太麻煩,每一個url都要單獨配!
今日可以擴展的(模板方法 ServletConfig常用方法 Servletcontext常用方法 servlet繼承體系 )