============================================================
一、什麼是Servlet?(非常非常重要)
servlet 是運行在 Web 服務器中的小型 Java 程序(即:服務器端的小應用程序)。
servlet 作用:通常通過 HTTP(超文本傳輸協議) 接收和響應來自 Web 客戶端的請求。
Servlet也是一個java類,但比較特殊,不需要new,自動就可以運行。也有創建、垃圾回收和銷燬過程。
1.1、編寫一個servlet程序
a、寫一個java類,實現Servlet接口,實現了該接口,該類就不是普通的類了。
b、修改 web.xml 文件,給servlet提供(映射)一個可訪問的URI地。
c、部署應用到tomcat服務器。
d、測試:http://localhost:8080/day08_00_servlet/demo1 在MyEcplise控制檯輸出 hello servlet,初體驗成功!
e、執行流程:demo1 --> servletDemo1 --> com.itheima.servlet.ServletDemo1 -->
Tomcat安裝目錄/webroot/Demo1/WEB-INF/classes/com.itheima.servlet.ServletDemo1.class --> service() --> hello servlet
============================================================
二、Servlet執行過程圖解
============================================================
三、Servlet的生命週期(重要)
實例化-->初始化-->服務->銷燬
出生:(實例化-->初始化)第一次訪問Servlet就出生了(默認情況下)。(說明我可以改變它的出生時機,比如讓servlet在服務器啓動時就創建)
活着:(服務)應用活着,servlet就活着。(Servlet是單實例,其中的service()方法是多線程的。)
死亡:(銷燬)應用被卸載了,servlet就銷燬了。
如何在網頁界面下卸載應用呢?
2.再訪問http://localhost:8080/,點擊 Manager App 輸入賬戶名和密碼,登錄管理界面成功後就可以開啓、停止、重新加載、卸載你的應用了,如下圖所示:
小知識:
如何設置讓servlet在服務器啓動時就創建,數值越小越先啓動 (不建議寫0)。
============================================================
四、Servlet的三種創建方式
4.1、實現javax.servlet.Servlet接口(參見:編寫一個servlet程序)
4.2、繼承javax.servlet.GenericServlet類(抽象類)(適配器模式)
GenericServlet類(抽象類)已經實現了Servlet接口,我們用哪個方法就調用哪方法,不用再去全部實現了,哪怕是全部的空實現。
4.3、繼承javax.servlet.http.HttpServlet類(抽象類)(模板方法設計模式)
模板是HttpServlet類中的私有service()方法(開發中常用方式)
HttpServlet類(抽象類)繼承了GenericServlet類(抽象類)
// 注意: 不要重寫父類Httpservlet中的service()方法,因爲該方法會調用Httpservlet中私有的service()方法,
// 而該私有的service()方法會根據不同的提交表單的方式,會調用相應的doGet()、doPost()、doHead()等方法。
// 我們去重寫這些不同的表單提交的方法即可。
Servlet(接口) --> GenericServlet(抽象類/適配器) --> HttpServlet(功能抽象類/模板) --> (繼承HttpServlet,具體實現類,重寫其功能)
爺爺 爸爸 兒子 孫子
-----------------------------------------------------------------------------
ServletDemo4.java中我們新建的文件是Servlet,不是Class了,裏面的配置如下:
該方式可以自動生成web.xml文件,不用我們去手動配置了!
這種方式生成的文件包含無用的註釋和標籤太多了,如何變得小清新呢?即:修改Servlet的默認模板代碼。
小技巧:使自動生成的servlet文件更清新一些(太多的標籤和註釋了): 找到:MyEclipse\Common\plugins目錄 把 com.genuitec.eclipse.wizards_9.0.0.me201108091322.jar 複製到上面目錄。
詳細過程鏈接:https://www.cnblogs.com/chenmingjun/p/9148107.html
servet的映射細節:
servet的映射細節1:
一個servlet可以配置多個映射路徑(或者說:多個映射路徑可以指向同一個servlet),只要是name是一樣的就行。
servet的映射細節2:
通配符* 代表任意字符串
url-pattern:*.xxx 以.xxx結尾的請求都可以訪問 注:不要加/
url-pattern:/* 以任意字符串結尾的請求都可以訪問
url-pattern:/xxxx/* 以/xxxx/開頭的請求都可以訪問
servet的映射細節3:
匹配規則:
優先級:從高到低
絕對匹配 優先 /開頭匹配 優先 擴展名方式(後綴名)匹配
如果url-pattern的值是/,表示的是執行默認映射。所有資源都是經過servlet。
============================================================
五、Servlet的線程安全
整個生命週期是單實例,但每次訪問時爲多線程。
法一:單實例變成多實例,但過時了,因爲耗費資源多,服務器壓力大。
法二:加線程鎖,但數據會重複出現(沒有同步機制),且運行效率低。
法三:解決線程安全問題的最佳辦法:不要寫全局變量,而寫局部變量(即改變變量的作用域)。
============================================================
六、Servlet獲取配置信息
ServletConfig對象的使用
作用1:可以獲取servlet配置文件的信息,即web.xml的信息。
作用2:可以獲取ServletContext對象。
方式1:重寫HttpServlet父類GenericServlet類(抽象類)的int()方法,ServletConfig對象由服務器創建。
方式2:通過調用HttpServlet父類GenericServlet類(抽象類)的方法得到ServletConfig對象,因爲GenericServlet類(抽象類)實現了Servlet接口和ServletConfig接口。
方式3:原理同方式2。
============================================================
七、ServletContext對象(重要)
ServletContext: 代表的是整個應用。一個應用只有一個ServletContext對象。單實例。
作用:
1、作爲域對象使用:
即在一定範圍內(當前應用),使多個Servlet通過ServletContext對象實現數據共享。因爲當前應用中會有很多java類,很多Servlet。
常用方法:
public void setAttribute(String name, Object value) // 向ServletContext對象的map集合中添加數據
public Object getAttribute(String name) // 從ServletContext對象的map集合中取出數據
public void rmoveAttribute(String name) // 根據name移除數據
2、獲取全局配置信息:
修改web.xml文件:
方法:public String getInitParamenter(String name) // 根據配置文件中的key得到value
3、讀取簡單的資源文件(即只包含key=value的形式):
方法:public String getRealPath(String path)// 根據資源名稱得到資源的絕對路徑,可以得到當前應用任何位置的任何資源。
4、實現Servlet的請求轉發:
方法:public RequestDispatcher getRequestDispatcher(String path) //參數表示要跳轉到哪去
、
5、依賴和關聯
如果是通過參數傳過來的對象,就叫依賴。
通過方法得到的對象,就叫關聯。