(一)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)