Servlet入門

Servlet是JavaWeb三大組件(Servlet,Filter,Listener)之一,是SUN公司提供的一門動態資源開發的技術,下面簡單記錄一下如何在IDEA下建立一個自定義Servlet、如何修改Servlet模板、Servlet運行過程簡單分析等。html

IDEA建立自定義Servlet

Servlet是頂級接口,下面是GenericServlet抽象類,這個抽象類實現了Servlet的大部分方法,只有一個抽象方法service。若是要作web應用,須要擴展爲httpServlet,它實現了Http協議。上一篇Tomcat入門已經介紹了手寫一個簡單Servlet並放到tomcat目錄下,這裏使用IDEA來建立並完成部署。java

(1)新建一個新項目,選擇Java Enterprise,Application Server中找到本身安裝的tomcat,選擇Web Application,點擊next。web

(2)Project name輸入本身的項目名,這點相似eclipse,能夠看到它的位置在D盤的IDEAproject目錄下,IDEAproject相似eclipse中的workspace工做空間,點擊finish。瀏覽器

(3) IDEA新建的項目,WEB-INF下是沒有classes和lib的,須要手動創建文件夾並關聯項目。tomcat

 

進入project structure設置界面(IDEA在eclipse使用習慣下使用ctrl+shift+alt+S),需設置java編譯後輸出的class路徑和外部導入jar包的路徑lib,就是剛纔建立的目錄。服務器

class輸出文件夾關聯設置:app

lib文件夾關聯設置,選擇Jar Directory:eclipse

勾選lib後確認。webapp

(4) 設置項目部署的位置,這裏修改成部署到tomcat的webapp目錄下。測試

(5)配置Tomcat服務器,選擇Server選項,能夠修改服務器名,After lauch不勾選,選擇就是使用默認打開地址,這裏使用咱們本身的打開路徑,所以不勾選。On frame deactivation設置爲Update classes and resources,表明鼠標離開IDEA界面也能夠實現類和資源的更新。最後將Deploy application configured in Tomcat instance勾選上,表明支持熱部署?

繼續選擇Deployment,Application Context名字設置和工程名字同樣的名字,點擊OK就完成前期基本配置。

自定義一個Servlet 

如圖,IDEA中能夠方便的建立servlet(選擇Create New Servlet),只須要咱們重寫doGet方法和doPost方法。

自動生成代碼以下,在Servlet3.0版本中,除了配置web.xml來配置servlet,還可使用註解的方式,二者均可以實現,可是不能共存,不然啓動tomcat就會報錯。

 1 package com.boe.servlet;
 2 
 3 import javax.servlet.ServletException;
 4 import javax.servlet.annotation.WebServlet;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 import java.io.IOException;
 9 
10 //@WebServlet("/MyFirstServlet")
11 public class MyFirstServlet extends HttpServlet {
12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
13         //測試向瀏覽器發送一段文字
14         response.getWriter().write("<a style='color:blue;font-family:微軟雅黑;font-size:20px'>this is my first servlet</a>");
15     }
16 
17     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
18         doPost(request, response);
19     }
20 }

等效web.xml中的以下配置

1     <!--配置servlet-->
2     <servlet>
3         <servlet-name>myservlet</servlet-name>
4         <servlet-class>com.boe.servlet.MyFirstServlet</servlet-class>
5     </servlet>
6     <servlet-mapping>
7         <servlet-name>myservlet</servlet-name>
8         <url-pattern>/MyFirstServlet</url-pattern>
9     </servlet-mapping>

部署完成後啓動tomcat,訪問servlet能夠正常向頁面返回信息(暫時不考慮中文亂碼問題,後續考慮),如下是部署到tomcat的webapp下的目錄結構。

測試結果。

這樣就完成了一個基本的Servlet,查看HttpServlet源碼,發現service方法底層會根據method類型,執行不一樣的方法,如GET和POST請求,就會執行doGet和doPost方法,所以重寫這兩個方法,跟重寫service方法效果同樣,如下爲service方法源碼。

 1     protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 2         String method = req.getMethod();
 3         long lastModified;
 4         if (method.equals("GET")) {
 5             lastModified = this.getLastModified(req);
 6             if (lastModified == -1L) {
 7                 this.doGet(req, resp);
 8             } else {
 9                 long ifModifiedSince;
10                 try {
11                     ifModifiedSince = req.getDateHeader("If-Modified-Since");
12                 } catch (IllegalArgumentException var9) {
13                     ifModifiedSince = -1L;
14                 }
15 
16                 if (ifModifiedSince < lastModified / 1000L * 1000L) {
17                     this.maybeSetLastModified(resp, lastModified);
18                     this.doGet(req, resp);
19                 } else {
20                     resp.setStatus(304);
21                 }
22             }
23         } else if (method.equals("HEAD")) {
24             lastModified = this.getLastModified(req);
25             this.maybeSetLastModified(resp, lastModified);
26             this.doHead(req, resp);
27         } else if (method.equals("POST")) {
28             this.doPost(req, resp);
29         } else if (method.equals("PUT")) {
30             this.doPut(req, resp);
31         } else if (method.equals("DELETE")) {
32             this.doDelete(req, resp);
33         } else if (method.equals("OPTIONS")) {
34             this.doOptions(req, resp);
35         } else if (method.equals("TRACE")) {
36             this.doTrace(req, resp);
37         } else {
38             String errMsg = lStrings.getString("http.method_not_implemented");
39             Object[] errArgs = new Object[]{method};
40             errMsg = MessageFormat.format(errMsg, errArgs);
41             resp.sendError(501, errMsg);
42         }
43 
44     }

訪問原理分析

以下是request請求頭和請求行裏的內容,請求行裏host爲localhost表明訪問的虛擬主機,另外默認端口號是80,經過這兩個說明訪問的是本機的tomcat服務器。若是Host中沒寫localhost就訪問默認虛擬主機,這個在tomcat的server.xml中Engine標籤的defaultHost屬性指定了。而後請求行裏還包括訪問的資源路徑,如MyServlet就是一個web應用的虛擬路徑,經過它能夠找到實際web資源的目錄,這裏使用的是第二種虛擬路徑-實際路徑映射的配置,能夠在IDEA的tomcat目錄下,找到同名的xml文件,裏面寫的就是實際資源的路徑。

如下爲文件路徑和內容。

而後肯定了web資源的位置後,最後需讀取web.xml或者@WebServlet中配置的關係,來肯定要訪問的真實資源,這裏web.xml中就指定了真實資源的位置,即com/boe/servlet/MyFirstServlet,這是一個手寫的servlet,訪問它後執行doGet方法,最後返回一個字符到頁面。

訪問靜態資源

前面tomcat入門就知道,web目錄下,WEB-INF目錄外的圖片,音頻等資源爲靜態資源,也能夠直接訪問。本次將一張圖片放到了web目錄下,從新設置部署後能夠直接讀取圖片內容,以下所示。

放入圖片,到web目錄下,注意不要放到WEB-INF下,萬一放到WEB-INF下也能夠,可是須要先建立一個static文件夾,將圖片放入,也能夠直接訪問。

設置資源

從新部署後訪問結果,發現能夠直接訪問。

爲何能夠訪問靜態資源呢,首先會讀取當前web應用下的web.xml,匹配全部url-pattern發現沒有匹配的資源,而後會讀取conf/web.xml,調用缺省的servlet來匹配靜態資源,若是匹配到就顯示,沒有就報錯404。

servlet模板修改

Servlet默認的模板是包含name屬性和value屬性的,對應就是web.xml中的servlet-name和url-pattern,而且doGet方法和doPost須要單獨實現,這裏能夠修改。

這樣修改後的,就只有省略value屬性後的地址,若是有多個參數,value就不能省略了。

Servlet運行過程與生命週期

運行過程:

i. 經過Host標籤肯定訪問虛擬主機。
ii. 經過資源名稱部分肯定訪問的是哪個web應用,能夠設置缺省web應用。
iii. 經過資源名稱部分肯定訪問的是哪個web資源,這裏就是servlet或者圖片。
iv. 肯定是哪個Servlet資源後,會建立對應Servlet對象,執行其中的service方法,這裏是執行doGet方法和doPost方法,本質上同樣。
v. 在service方法執行完成以後,會將response緩衝區中的內容在服務器組織成必定結構。
vi. 最終將組織好的結果數據響應到瀏覽器中。
 
生命週期:
在Servlet被初次訪問的時候,會在tomcat內存中建立一個當前Servlet的對象,而且會馬上調用init方法完成初始化的操做。這個對象會駐留在內存中的,再次訪問這個servlet時,都是訪問這個對象,當web應用移除後,就會自動調用destroy方法完成銷燬,人爲調用這個方法無效。 
 

參考博文:

(1)http://www.javashuo.com/article/p-rehityym-a.html servlet

相關文章
相關標籤/搜索