本節內容:
- Servlet簡介
- Servlet的API
- Servlet的配置
- ServletContext對象
一、Servlet簡介
1. 什么是Servlet
Servlet是運行在服務端的Java小程序,是sun公司提供一套規范(接口),用來處理客戶端請求、響應給瀏覽器的動態資源。但servlet的實質就是java代碼,通過java的API 動態的向客戶端輸出內容。
Servlet規范:包含三個技術點。或者說是servlet的三大組件。
- servlet技術
- filter技術(過濾器)
- listener技術(監聽器)
2. Servlet入門小例子
實現步驟:
(1)創建類實現Servlet接口
(2)覆蓋尚未實現的方法(重點實現service方法)
(3)在web.xml進行servlet的配置
Eclipse創建一個“Dynamic Web Project”,在src下創建一個包,然后在包里新建一個Servlet,目前我們只實現service方法。service代碼如下:
@Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("QuickStratServlet running...."); res.getWriter().write("QuickStratServlet running...."); }
WEB-INF/web.xml文件里添加配置:
<!-- servlet的類的配置 --> <servlet> <servlet-name>abc</servlet-name> <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class> </servlet> <!-- servlet的虛擬路徑的配置 --> <servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/quickStratServlet</url-pattern> </servlet-mapping>
右鍵項目,"Run As"——>"Run On Server",然后瀏覽器訪問"http://localhost:8080/project_name/quickStratServlet"
頁面顯示:
QuickStratServlet running....
Servlet訪問過程:
我們在創建Servlet時,默認是實現Servlet接口,但是該接口要實現的方法有很多,有init(ServletConfig config),service(ServletRequest request,ServletResponse response),destroy()等。
所以在實際開發中,我們不會直接去實現Servlet接口,因為那樣需要覆蓋的方法太多, 我們一般創建類繼承HttpServlet。
實現步驟:
(1)創建類繼承HttpServlet類
(2)覆蓋doGet和doPost
(3)在web.xml中進行servlet的配置
二、Servlet的API(生命周期)
1. Servlet接口中的方法
(1)init(ServletConfig config)
何時執行:servlet對象創建的時候執行。因為接下來要調用service方法,該方法不是靜態的,需要一個對象來調用,這個對象就是tomcat服務器幫我們創建的。
ServletConfig : 代表的是該servlet對象的配置信息。
(2)service(ServletRequest request,ServletResponse response)
何時執行:每次請求,service方法都會執行。
ServletRequest :代表請求。認為ServletRequest內部封裝的是http請求的信息。
ServletResponse :代表響應。認為要封裝的是響應的信息。
(3)destroy()
何時執行:servlet對象銷毀的時候執行。
2. HttpServlet類的方法
- init()
- doGet(HttpServletRequest request,HttpServletResponse response)
- doPost(HttpServletRequest request,HttpServletResponse response)
- destroy()
3. Servlet的生命周期
一般面試的時候會問這個。
(1)Servlet何時創建
默認第一次訪問servlet時創建該對象。可以通過配置讓servlet對象不是第一次訪問的時候創建,而是在服務器一啟動時就創建。
(2)Servlet何時銷毀
服務器關閉,servlet就銷毀了。
Servlet對象是存儲在內存中,這個對象不是你創建的,而且tomcat服務器幫你創建的,你無法拿到它的引用。
(3)每次訪問必然執行的方法
service(ServletRequest req, ServletResponse res)方法。
三、Servlet的配置
1. 基本配置
<!-- servlet的類的配置 --> <servlet> <servlet-name>abc</servlet-name> <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class> <!-- 初始化參數示例 --> <init-param> <param-name>url</param-name> <param-value>jdbc:mysql:///mydb</param-value> </init-param> </servlet> <!-- servlet的虛擬路徑的配置 --> <servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/quickStratServlet</url-pattern> </servlet-mapping>
其中url-pattern的配置方式有三種:
(1)完全匹配。訪問的資源與配置的資源完全相同才能訪問到。
<servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/quickStratServlet</url-pattern> </servlet-mapping>
(2)目錄匹配 格式:/虛擬的目錄../* *代表任意
<servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/aaa/bbb/ccc/*</url-pattern> </servlet-mapping>
(3)擴展名匹配 格式:*.擴展名
<servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>*.abcd</url-pattern> </servlet-mapping>
注意:第二種與第三種不要混用。比如:/aaa/bbb/*.abcd,這種配置方式是錯誤的。
2. 服務器啟動實例化Servlet配置
Servlet何時創建:默認第一次訪問時創建。
當在servlet的配置上,加上一個配置 <load-on-startup>,servlet對象就會在服務器啟動時就創建。配置示例如下:
<!-- servlet的類的配置 --> <servlet> <servlet-name>abc</servlet-name> <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class> <!-- servlet在服務器啟動時創建對象,默認是第一次訪問時創建對象。該配置必須放在servlet所有配置的最下面。 --> <!-- 里面的數字1-5都可以。數字代表優先級,數字越小,優先級越高。在開發中,一般不要配置為1,配置為中間的數。 --> <load-on-startup>3</load-on-startup> </servlet>
3. 缺省Servlet
可以將url-pattern配置一個/,代表該servlet是缺省的servlet。
什么是缺省的servlet?
當你訪問資源地址所有的servlet都不匹配時 ,缺省的servlet負責處理該請求。
其實,web應用中所有的資源的響應都是servlet負責,包括靜態資源請求。
現在在WebContent下新建一個1.html,web.xml里的url-pattern只配置一個/,如下:
<servlet> <servlet-name>abc</servlet-name> <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>abc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
瀏覽器輸入http://localhost:8080/web13/1.html訪問,你發現是訪問的結果不是1.html的內容,而是QuickStratServlet的返回結果。
而當我們注釋了“缺省的servlet”配置,再次訪問http://localhost:8080/web13/1.html就可以訪問到1.html的內容了。這是為什么呢?打開tomcat配置文件conf/web.xml,這個web.xml是全局的web.xml,對在該tomcat下的所有web應用都適用,但是有個前提,如果全局的web.xml和web應用的web.xml里面某些配置有沖突,則使用web應用自己的web.xml里面的配置。打開tomcat全局的web.xml,查找"<url-pattern>/</url-pattern>",
<!-- The mapping for the default servlet --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
在找這個default對應的servlet:
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
所以在訪問1.html的時候,其實找的是org.apache.catalina.servlets.DefaultServlet,並不是直接找的1.html這個文件。DefaultServlet去應用的目錄下尋找1.html這個文件, 把1.html逐句輸出。如果沒有找到1.html,會返回一個頁面,顯示404。這個頁面也是DefaultServlet幫我們輸出的。
4. 歡迎頁面
我們在訪問一個網站時,經常像這么訪問,比如訪問localhost:8080/web13/,后面什么資源都不寫,這個時候會自動去找index.html,index.jsp或者其他的資源。這些都是可以在web.xml中配置的。
如果在web應用的web.xml中沒有配置<welcome-file-list></welcome-file-list>,你在訪問localhost:8080/web13/時,這時就會去找tomcat全局的web.xml文件中該配置。
<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list>
四、ServletContext對象
1. 什么是ServletContext對象
ServletContext代表是一個web應用的環境(上下文)對象(可以理解為就是代表web應用),ServletContext對象內部封裝的是該web應用的信息。一個web應用只有一個ServletContext對象。
問題:一個web應用有幾個servlet對象?多個。
ServletContext對象的生命周期?
創建:該web應用被加載(服務器啟動或發布web應用,前提時服務器是啟動狀態)
銷毀:web應用被卸載(服務器關閉,移除該web應用)
2. 怎樣獲得ServletContext對象
兩種方式:
(1)ServletContext servletContext = config.getServletContext(); 一般不用這種,比較麻煩。因為這個config是servlet的init方法里才有的。
(2)ServletContext servletContext = this.getServletContext();
3. ServletContext的作用
(1) 獲得web應用全局的初始化參數
web.xml中配置初始化參數。比如配置如下:
<context-param> <param-name>driver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </context-param>
今后在學習spring的時候,spring加載配置文件,配置文件位置就可以通過類似上面的配置來配置。
通過context對象獲得參數:
public class ContextServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得ServletContext對象 ServletContext context = getServletContext(); //或者this.getServletContext() this代表當前對象,不寫也可以。 //這個方法在當前類中沒有,找它爸爸HttpServlet也沒有,找爺爺找到了 //1、獲得初始化參數 String initParameter = context.getInitParameter("driver"); System.out.println(initParameter); } }
(2)獲得web應用中任何資源的絕對路徑
方法:String path = context.getRealPath(相對於該web應用的相對地址);
public class ContextServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得ServletContext對象 ServletContext context = getServletContext(); //2、獲得a.txt b.txt c.txt d.txt的絕對路徑。(這4個txt文件分別建在不同的目錄) //發布時,tomcat下的webapps下,建一個文件夾名和項目名一一致。將項目下的WebConten下的全部資源放到WEB13目錄下。 //String path = context.getRealPath(相對於該web應用的相對地址); //2.1 獲得a.txt,a.txt建在WebContent目錄下 String realPath_A = context.getRealPath("a.txt"); System.out.println(realPath_A); //2.2 獲得b.txt,b.txt建在WEB-INF目錄下 String realPath_B = context.getRealPath("WEB-INF/b.txt"); System.out.println(realPath_B); //2.3 獲得c.txt,c.txt建在src目錄下。src下面的源代碼最終會被發布到WEB-INF/classes/目錄下 String realPath_C = context.getRealPath("WEB-INF/classes/c.txt"); System.out.println(realPath_C); //2.4 獲得d.txt。d.txt建在WEB13_servlet目錄下。----獲取不到 //補充另外一個獲取路徑的方法 //在讀取src(classes) 下的資源時,還可以通過類加載器(專門加載classes下的文件的)。只是寫的比較麻煩 //getResource() 參數是一個相對地址 相對classes String path = ContextServlet.class.getClassLoader().getResource("c.txt").getPath(); System.out.println(path); } }
(3)ServletContext是一個域對象
什么是域對象?什么是域?
域就是區域的意思,存儲數據的區域就是域對象。
ServletContext域對象的作用范圍:整個web應用(所有的web資源都可以隨意向 servletcontext域中存取數據,數據可以共享)
【例子】:寫兩個Servlet,一個向ServletContext域對象中存數據,一個向ServletContext域對象中寫數據。

public class ContextServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得ServletContext對象 ServletContext context = getServletContext(); //3、域對象---向servletContext中存數據 context.setAttribute("name", "zhangsan"); } }

public class ContextServlet2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //域對象---從servletContext中取數據 String attribute = (String) this.getServletContext().getAttribute("name"); System.out.println(attribute); } }
域對象的通用的方法:
- setAtrribute(String name,Object obj);
- getAttribute(String name);
- removeAttribute(String name);