Servlet基礎(工作原理、生命週期)

(一)Servlet開發與配置

1.1 開發步驟

  •  1)編寫java類,繼承HttpServlet類

  •  2)重新doGet和doPost方法

  •  3)Servlet程序交給tomcat服務器運行!

配置信息:

複製代碼

 1     <servlet> 2         <!-- Servlet 的內部名稱,自定義 --> 3         <servlet-name>HelloServlet</servlet-name> 4         <!--servlet的類全名--> 5         <servlet-class>com.infaraway.HelloServlet</servlet-class> 6     </servlet> 7  8     <!--Servlet的映射配置--> 9     <servlet-mapping>10         <!--servlet的內部名稱,要和上面的保持一致-->11         <servlet-name>HelloServlet</servlet-name>12         <!--servlet的映射路徑(訪問servlet的名稱)-->13         <url-pattern>/HelloServlet</url-pattern>14     </servlet-mapping>

複製代碼

 

                     url-pattern                                    瀏覽器輸入
精確匹配        /HelloServlet            http://localhost:8080/day10/HelloServlet
                   /path/HelloServlet    http://localhost:8080/day10/path/HelloServlet

模糊匹配        /*           http://localhost:8080/projectName/任意路徑
       /path/*                http://localhost:8080/projectName/path/任意路徑
        *.後綴名                 http://localhost:8080/projectName/任意路徑.do
        *.do
           *.action
        *.html(僞靜態)

注意:
1)url-pattern要麼以 / 開頭,要麼以*開頭。 例如, path是非法路徑。
2)不能同時使用兩種模糊匹配,例如 /path/*.do是非法路徑
3)當有輸入的URL有多個servlet同時被匹配的情況下:
    a 精確匹配優先。(長的最像優先被匹配)
    b 以後綴名結尾的模糊url-pattern優先級最低!

 

1.2 servlet缺省路徑

servlet的缺省路徑(<url-pattern>/</url-pattern>)是在tomcat服務器內置的一個路徑。該路徑對應的是一個DefaultServlet(缺省Servlet)。這個缺省的Servlet的作用是用於解析web應用的靜態資源文件。

問題: URL輸入http://localhost:8080/projectName/index.html 如何讀取文件?

  • 1)到當前projectName應用下的web.xml文件查找是否有匹配的url-pattern。

  • 2)如果沒有匹配的url-pattern,則交給tomcat的內置的DefaultServlet處理

  • 3)DefaultServlet程序到projectName應用的根目錄下查找是存在一個名稱爲index.html的靜態文件。

  • 4)如果找到該文件,則讀取該文件內容,返回給瀏覽器。

  • 5)如果找不到該文件,則返回404錯誤頁面。


(二)Servlet的生命週期

2.1 Servlet重要的四個生命週期方法

  • 構造方法: 創建servlet對象的時候調用。默認情況下,第一次訪問servlet的時候創建servlet對象 只調用1次。證明servlet對象在tomcat是單實例的。

  • init方法: 創建完servlet對象的時候調用。只調用1次。

  • service方法: 每次發出請求時調用。調用n次。

  • destroy方法: 銷燬servlet對象的時候調用。停止服務器或者重新部署web應用時銷燬servlet對象。只調用1次。

2.2 僞代碼演示servlet的生命週期

Tomtcat內部代碼運行:
1)通過映射找到到servlet-class的內容,字符串: com.infaraway.HelloServlet
2)通過反射構造HelloServlet對象
  2a. 得到字節碼對象
    Class clazz = class.forName("com.infaraway.HelloServlet");
  2b. 調用無參數的構造方法來構造對象
    Object obj = clazz.newInstance(); ---1.servlet的構造方法被調用
3)創建ServletConfig對象,通過反射調用init方法
  3a 得到方法對象
    Method m = clazz.getDeclareMethod("init",ServletConfig.class);
  3b 調用方法
    m.invoke(obj,config); --2.servlet的init方法被調用
4)創建request,response對象,通過反射調用service方法
  4a 得到方法對象
    Method m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);
  4b 調用方法
    m.invoke(obj,request,response); --3.servlet的service方法被調用
5)當tomcat服務器停止或web應用重新部署,通過反射調用destroy方法
  5a 得到方法對象
    Method m = clazz.getDeclareMethod("destroy",null);
  5b 調用方法
    m.invoke(obj,null); --4.servlet的destroy方法被調用

 

(三)Servlet相關問題

3.1. 自動加載

默認情況下,第一次訪問servlet的時候創建servlet對象。如果servlet的構造方法或init方法中執行了比較多的邏輯代碼,那麼導致用戶第一次訪問sevrlet的時候比較慢。因此,爲了提高訪問的速度,我們需要改變servlet創建對象的時機: 提前到加載web應用的時候!在servlet的配置信息中,加上一個<load-on-startup>即可!

即在配置Servlet的時候在配置文件中加入

複製代碼

1     <servlet>2         <!-- Servlet 的內部名稱,自定義 -->3         <servlet-name>HelloServlet</servlet-name>4         <!--servlet的類全名-->5         <servlet-class>com.infaraway.HelloServlet</servlet-class>6         <!-- 讓servlet對象自動加載
7             注意: 整數值越大,創建優先級越低!!-->
8         <load-on-startup>1</load-on-startup>9     </servlet>

複製代碼

 

3.2. 有參數init方法和無參數的init方法

在原來的init方法中會調用無參數的init方法;無參數的Init用來編寫初始化的邏輯代碼;有參數的init方法是Servlet生命週期的方法,一定會被tomcat調用。如果編寫程序時,不需要覆蓋有參數的init方法,只需要將初始化代碼放到無參數的init方法即可;

3.3. 多線程併發問題

注意: servlet對象在tomcat服務器是單實例多線程的。

 

(四)ServletConfig對象

Servlet中需要學習的四個對象,其中前兩個在學習Http請求的時候已經詳細講述了:具體見之前的博文:

  • HttpServletRequest 請求對象:獲取請求信息

  • HttpServletResponse 響應對象: 設置響應對象

  • ServletConfig對象 servlet配置對象

  • ServletContext對象; servlet的上下文對象

作用:ServletConfig對象主要用於加載Servlet的初始化參數,在一個web應用中,可以存在多個ServletConfig對象(一個Servlet對應一個ServletConfig對象)

 

創建時間:在創建完servlet對象之後,在調用init方法之前會創建ServletConfig對象

獲取對象:直接從有參數的init方法中得到該對象;

其中Servlet中初始化參數的配置:

複製代碼

 1     <servlet> 2         <!-- Servlet 的內部名稱,自定義 --> 3         <servlet-name>HelloServlet</servlet-name> 4         <!--servlet的類全名--> 5         <servlet-class>com.infaraway.HelloServlet</servlet-class> 6         <!-- 初始參數: 這些參數會在加載web應用的時候,封裝到ServletConfig對象中 --> 7         <init-param>
 8             <param-name>path</param-name>
 9             <param-value>e:/b.txt</param-value>
10         </init-param>11     </servlet>

複製代碼

 

注意: servlet的參數只能由當前的這個sevlet獲取!

ServletConfig的API:

  • java.lang.String getInitParameter(java.lang.String name) 根據參數名獲取參數值

  • java.util.Enumeration getInitParameterNames() 獲取所有參數

  • ServletContext getServletContext() 得到servlet上下文對象

  • java.lang.String getServletName() 得到servlet的名稱

 

(五)ServletContext對象 

  ServletContext對象 ,叫做Servlet的上下文對象。表示一個當前的web應用環境。一個web應用中只有一個ServletContext對象。

創建時機:加載web應用時創建ServletContext對象。

獲取對象: 從ServletConfig對象的getServletContext方法得到

複製代碼

 1     1)創建ServletContext對象      ServletContext  context = new ServletContext()        
 2  3     2)創建ServletConfig對象       ServetConfig config = new ServletConfig(); 4                                               config.setServletContxt(context); 5                     class  ServletConfig{ 6                             ServletContext context; 7                             public ServletContext getServletContxt(){ 8                                 return contxt; 9                             }10                     } 
11 12                     public void init( ServletConfig config ){13                         得到ServletConfig對象14                         從ServletConfig對象中得到ServletContext對象15                         SerlvetContext context = config.getServletContext();16                     }

複製代碼

 

ServletContext對象的核心API

  • java.lang.String getContextPath() --得到當前web應用的路徑

  • java.lang.String getInitParameter(java.lang.String name) --得到web應用的初始化參數

  • java.util.Enumeration getInitParameterNames()

  • void setAttribute(java.lang.String name, java.lang.Object object) --域對象有關的方法

  • java.lang.Object getAttribute(java.lang.String name)

  • void removeAttribute(java.lang.String name)

  • RequestDispatcher getRequestDispatcher(java.lang.String path) --轉發(類似於重定向)

  • java.lang.String getRealPath(java.lang.String path) --得到web應用的資源文件

  • java.io.InputStream getResourceAsStream(java.lang.String path)

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章