參考:http://www.cnblogs.com/xdp-gacl/p/3760336.html 這個博主的知識點寫的非常棒而且細致,推薦新手入門的大家直接過去充能~
servlet是按照servlet規范編寫的java類。它運行于支持java的應用服務器中,主要用于響應web(HTTP)方面的請求。
servlet在服務器端運行,主要用于處理客戶端的請求。 web服務器習慣于處理靜態頁面,對于動態請求,一般交由一個幫助程序進行處理,再將處理后的靜態頁面返回給web服務器。servlet就是這樣的幫助程序。通常由瀏覽器向web容器發送HTTP請求,根據web容器中的web.xml文件,決定由具體的某個servlet來對其進行處理。
servlet生命周期指的是,從創建servlet實例后,servlet存在到銷毀的整個過程。 生命周期中主要有以下幾個階段: 1.實例化。servlet容器加載servlet類,并將.class 文件讀取到內存中,由servlet容器創建一個servlet實例。 2.初始化。servlet容器調用init()函數完成參數的初始化。 3.運行。當servlet容器接收到請求時,會根據請求創建ServletRequest和ServletResponse對象,并將其傳遞給調用的service()方法。service()方法通過request獲取請求的內容,并對其進行處理,將請求的結果封裝在response中。每個請求均在獨立的線程中運行。 4.銷毀。servlet容器調用destroy()方法,銷毀servlet對象,并釋放它占用的資源。
在一個生命周期中,init()方法和destroy()方法都只會被調用一次。而service方法執行的次數則取決于被客戶端訪問的次數。
1.新建一個web-PRoject,生成的目錄如下: 2.在src目錄下,新建一個servlet文件
那么,自動生成的servlet文件和在web.xml文件中的配置如下: AutoServlet文件:
對于每一個具體的程序塊的用途,MyEclipse自動生成時都附上了詳細的注釋。 web.xml文件:
<?xml version="1.0" encoding="UTF-8"?><web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name> <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>AutoServlet</servlet-name> <servlet-class>com.test1.AutoServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AutoServlet</servlet-name> <url-pattern>/servlet/AutoServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></web-app>主要看<servlet></servlet><servlet-mapping></servlet-mapping>
這兩對標簽中的內容。在這里,配置了對特定servlet文件的映射關系。
注意: (1)兩個servlet-name必選相同; (2)默認的url-pattern為:/servlet/servlet-name
接下來,將這個web-project部署到tomcat上,啟動tomcat后,就可以在網頁上訪問這個servlet了。
訪問的地址為: http://localhost:8080/servlet-test/servlet/AutoServlet 也就是:"http://localhost:8080/"
+ web項目名稱+web.xml中配置的url-pattern
由于客戶端是根據url來訪問web中的資源,因此,要想訪問一個servlet,就要把它映射到一個url地址上,這個工作,在web.xml中,由<servlet></servlet><servlet-mapping></servlet-mapping>
這兩對標簽來完成。 <servlet></servlet>
標簽用于注冊servlet,其中,servlet-name是servlet的名稱,servlet-class中寫servlet所在的完整類名。 <servlet-mapping></servlet-mapping>
標簽用于映射一個已注冊的servlet和它的對外訪問路徑。一個注冊的servlet可以有多個訪問路徑。 如:
那么,使用地址: http://localhost:8080/servlet-test/servlet/AutoServlet http://localhost:8080/servlet-test/1.html http://localhost:8080/servlet-test/2.jsp http://localhost:8080/servlet-test/3.php http://localhost:8080/servlet-test/4.ASPX 都可以訪問同一servlet。
此外,還可以使用*通配符來匹配映射的url地址。 使用通配符時,只有兩種固定格式: 1.使用*.擴展名 2.使用正斜杠(/)開頭,并以/*結尾。 如: 對于上述例子中的servlet,在web.xml中配置
<servlet-mapping> <servlet-name>AutoServlet</servlet-name> <url-pattern>/servlet/AutoServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AutoServlet</servlet-name> <url-pattern>/find/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AutoServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>那么,就可以使用: http://localhost:8080/servlet-test/find/aabbcc 或: http://localhost:8080/servlet-test/aabbcc.do 來訪問上述servlet (aabbcc可以由任意字符串代替)
對于多個注冊的servlet都使用了通配符的情況,在映射過程中,遵循那個更相似,就匹配到哪一個的原則
<load-on-startup>
標簽根據上面的知識點,可以知道,在處理客戶端的servlet請求時,首先需要有一個servlet實例。對于多次請求,僅創建一個實例,調用一次init()方法。每次請求過程中,servlet引擎將創建新的HttpServletRequest請求對象和HttpServletResponse響應對象,并將其作為參數傳遞給service(),service()再根據請求的內容,調用響應的doXXX方法,對請求進行處理。 在web.xml中配置<load-on-startup>
,那么,在web應用啟動時,就會裝載并實例化servlet,并調用實例對象的init()方法。
標簽中的數字,用于標記容器是否在啟動時就加載這個servlet,以及加載的優先級。 當數字為負數或是無指定值時,容器只在該servlet被選擇是才對它進行加載。 當數字為非負數是,表示容器在啟動時就加載這個servlet。數字越小,啟動這個servlet的優先級越高(如:0的優先級大于1)
當一個servlet的訪問路徑(url-pattern)配置為一個正斜杠(/)時,這個servlet就稱為web容器的缺省servlet。 即,凡是找不到對應的<servlet-mapping></servlet-mapping>
的url請求,都將訪問該缺省servlet。
當多個客戶端并發訪問一個servlet時,web服務器就會為每一個訪問創建一個線程,每個線程分別調用servlet實例的service()方法。如果多個service()方法同時訪問同一個資源,就會導致線程安全問題。 線程安全問題只存在多個線程并發操作同一個資源的情況下,所以在編寫Servlet的時候,如果并發訪問某一個資源(變量,集合等),就會存在線程安全問題。 就之前學過的java基礎部分的知識點而言,可以使用線程鎖synchronized來解決線程問題.即,將可能產生線程安全問題的程序塊寫在
synchronized(this) { ....}中。當有線程訪問該資源時,它就拿到了這把鎖。那么,如果有并發的線程同時訪問該資源,就必須等待上一個線程訪問完畢,將鎖釋放出來。 但是,在實際的應用中,使用servlet時,不可以使用該方式。針對線程安全問題,在servlet2.4之前,采用的方法是,讓servlet繼承Sun公司提供的標記接口:SingleThreadModel,這樣,這個servlet無論何時,都將單線程運行。 需要注意的是,這種方法的實質是產生多個Servlet實例對象,每個并發的線程分別對應一個實例對象。因此,這種方法并沒有真正解決多并發的線程安全性問題,在servlet2.4以后,已被標記為deprecated(過時)
新聞熱點
疑難解答