1. 什麼是Servlet
* Servlet是JavaWeb三大組件之一(Servlet、Filter、Listener)
* Servlet是用來處理客戶端請求的動態資源
* Servlet的任務有:
- 獲取請求數據
- 處理請求
- 完成響應
* Servlet接口方法:
- void init(ServletConfig)
- void service(ServletRequest,ServletResponse)
- void destory()
- ServletConfig getServletConfig()
- String getServletInfo()
2. 實現Servlet的方式
- 實現Servlet接口(不方便)
- 繼承GenericServlet類(不方便)
- 繼承HttpServlet類(方便)
3. Servlet第一例
- 寫一個類cn.itcast.MyServlet,實現Servlet接口
- 實現service()方法,在其中給出System.out.println("hello servlet!");
- 在web.xml文件中指定Servlet的訪問路徑爲:/myservlet
<servlet>
<servlet-name>xxx</servlet-name>
<servlet-class>cn.itcast.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>xxx</servlet-name>
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
當用戶在地址欄中訪問:http://localhost:8080/day04_1/myservlet時,會執行System.out.println("hello servlet!");
===============================
4,Servlet生命週期
Servlet接口一共5個方法,但其中只有三個是生命週期方法:
- void init(ServletConfig)
- void service(ServletRequest,ServletResponse)
- void destory()
1). 服務器創建Servlet:
* 當Servlet第一次被請求時,或服務器啓動時,服務器會創建Servlet實例。
* 服務器默認是在servlet第一次被請求時創建Servlet實例,如果希望服務器啓動時就創建Servlet實現需要在web.xml中配置
* 服務器只爲一個類型的Servlet創建一個實例對象,所以Servlet是單例的;
2). 服務器初始化Servlet:
- 當服務器創建Servlet實例後會馬上調用Servlet的init(ServletConfig)方法,完成對Servlet的初始化;
- init(ServletConfig)只會被調用一次
- 服務器會在調用init()方法時傳遞ServletConfig參數
3). 服務器使用Servlet處理請求:
- 當Servlet被請求時,服務器會調用Servlet的service(ServletRequest,ServletResponse)方法
- service(ServletRequest,ServletResponse)方法每處理一次請求,就會被調用一次,所以它可能會被調用N次
- 因爲Servlet是單例的,所以可能在同一時刻一個Servlet對象會被多個請求同時訪問,所以這可能出現線程案例問題
- Servlet不是線程案例的,這有助與提高效率,但不能讓Servlet具有狀態,以免多個線程爭搶數據
4). 服務器銷燬Servlet
- 服務器通常不會銷燬Servlet,通常只有在服務器關閉時纔會銷燬Servlet
- 服務器會在銷燬Servlet之前調用Servlet的destory()方法
- 可以在destory()方法中給出釋放Servlet佔有的資源,但通常Servlet是沒什麼可要釋放的,所以該方法一般都是空的
===============================
,5,ServletConfig
ServletConfig是Servlet中的init()方法的參數類型,服務器會在調用init()方法時傳遞ServletConfig對象給init()方法。
ServletConfig對象封裝了Servlet在web.xml中的配置信息,它對應<servlet>元素。ServletConfig類的功能有:
- String getServletName():獲取Servlet配置名,即<servlet-name>的值;
- ServletContext getServletContext():獲取ServletContext對象,這個對象稍後介紹
- String getInitParameter(String name):獲取初始化參數
- Enumeration getInitParameterNames():獲取所有初始化參數的名稱
在web.xml文件中,配置<servlet>時可以爲<servlet>配置0~N個初始化參數,例如:
<servlet>
<servlet-name>xxx</servlet-name>
<servlet-class>cn.itcast.servlet.MyServlet</servlet-class>
<init-param>
<param-name>p1</param-name>
<param-value>v1</param-value>
</init-param>
<init-param>
<param-name>p2</param-name>
<param-value>v2</param-value>
</init-param>
</servlet>
===============================
6,GenericServlet
GenericServlet是Servlet接口的實現類,但它是一個抽象類,它唯一的抽象方法就是service()方法
GenericServlet實現了Servlet方法:
- 實現了String getServletInfo()方法
- 實現了void destory()方法,空實現
- 實現了void init(ServletConfig)方法,用來保存ServletConfig參數
- 實現了ServletConfig getServletConfig()方法
GenericServlet實現了ServletConfig接口:
- 實現了ServletContext getServletContext()方法
- 實現了String getInitParameter()方法
- 實現了String getServletName()方法
- 實現了Enumeration getInitParameterNames()方法
GenericServlet添加了init()方法:
- 該方法會被init(ServletConfig)方法調用
- 如果希望對Servlet進行初始化,那麼應該覆蓋init()方法,而不是init(ServletConfig)方法
===============================
7,HttpServlet
HttpServlet是GenericServlet的子類,它專注HTTP請求
HttpServlet類的方法:
1》 實現了void service(ServletRequest,ServletResponse)方法,實現內容是:
- 把ServletRequest強轉成HttpServletRequest
- 把ServletResponse強轉成HttpServletResponse
- 調用本類添加的void service(HttpServletRequest,HttpServletResponse)方法
2》添加了void service(HttpServletRequest,HttpServletResponse)方法,內容是:
- 調用request的getMethod()獲取請求方式
- 如果請求方式爲GET,那麼調用本類添加的doGet(HttpServletRequest,HttpServletResponse)方法
- 如果請求方式爲POST,那麼調用本類添加的doPost(HttpServletRequest,HttpServletResponse)方法
3》 添加了doGet(HttpServletRequest,HttpServletResponse)方法,內容是響應405,表示錯誤,所以我們應該去覆蓋這個方法
4》添加了doPost(HttpServletRequest,HttpServletResponse)方法,內容是響應405,表示錯誤,所以我們應用去覆蓋這個方法
如果是通過繼承HttpServlet類來自定義Sevlet的話,那麼:
- 不要去覆蓋void service(ServletRequest,ServletResponse)
- 不要去覆蓋void service(HttpServletRequest, HttpServletResponse)
- *而應該去覆蓋doGet()或doPost()方法。
===============================
7,<url-pattern>
<url-pattern>是<servlet-mapping>的子元素,用來綁定Servlet的訪問路徑
可以在一個<servlet-mapping>中給出多個<url-pattern>,也就是說一個Servlet可以有多個訪問路徑:
<servlet-mapping>
<servlet-name>xxx</servlet-name>
<url-pattern>/helo1<url-pattern>
<url-pattern>/hello2<url-pattern>
</servlet-mapping>
還可以在<url-pattern>中使用通配符,即“*”。
- <url-pattern>/*<url-pattern>:表示匹配任何路徑
- <url-pattern>/do/*<url-pattern>:表示匹配以/do開頭的任何路徑
- <url-pattern>*.do<url-pattern>:表示匹配任何以“.do”結尾的路徑
注意:
* 通配符要麼在開頭,要麼在結尾,不能在中間,例如:/*.do就是錯誤的使用。 如果不使用通配符,那麼<url-pattern>必須以“/”開頭,例如:<url-pattern>abc</url-pattern>就是錯誤的
===============================
===============================
===============================
8,ServletContext
ServletContext是Servlet三大域對象之一
ServletContext在服務器啓動時創建,在服務器關閉時銷燬,一個JavaWeb應用只創建一個ServletContext對象
1》. 它的功能分類:
- 存取數據
- 讀取web.xml中的應用初始化參數
- 讀取應用資源
2》. 獲取ServletContext對象
在HttpServlet中可以通過以下方法來獲取ServletContext對象
- ServletContext sc = this.getServletContext()
- ServletContext sc = this.getServletConfig().getServletContext()
3》. 存取數據
因爲在一個JavaWeb應用中,只有一個ServletContext對象,所以在ServletContext中保存的數據可以共整個JavaWeb應用中的動態資源共享
ServletContext是Servlet三大域對象之一,域對象內部有一個Map,用來保存數據
a,void setAttribute(String name, Object value):用來添加或替換ServletContext域數據
- servletContext.setAttribute("xxx", "XXX"),添加域數據
- servletContext.setAttribute("xxx", "XXXX"),覆蓋域數據,因爲在域中已經存在了名爲xxx的數據,所以這次就是覆蓋了
b,Object getAttribute(String name):通過名稱來獲取域數據
c, void removeAttribute(String name):通過名稱移除域數據
d,Enumeration<String> getAttributeNames():獲取所有ServletContext域數據的名稱
4》. 讀取web.xml中配置的應用初始化參數
<context-param>
<param-name>p1</param-name>
<param-value>v1</param-value>
</context-param>
<context-param>
<param-name>p2</param-name>
<param-value>v2</param-value>
</context-param>
* servletContext.getInitParameter("p1"),返回v1
* servletContext.getInitParameter("p2"),返回v2
* servletContext.getInitParameterNames(),返回Enumeration<String>,包含p1和p2
5》. 獲取項目資源
a,String getRealPath(String path):獲取資源的真實名稱
String path = servletContext.getRealPath("/WEB-INF/a.jpg");
返回值爲/WEB-INF/a.jpg真實路徑,即磁盤路徑:C:/tomcat6/wabapps/hello/WEB-INF/a.jpg
b, InputStream getResourceAsStream(String path):獲取資源的輸入流
InputStream in = servletContext.getResourceAsStream("/WEB-INF/a.jpg");
返回的是a.jpg的輸入流對象,可以從流中得到a.jpg的數據
c, Set<String> getResourcePaths(String path):獲取指定目錄下的所有資源路徑
Set<String> paths = servletContext.getResourcePaths("/WEB-INF");
返回的Set中包含如下字符串:
> /WEB-INF/lib/
> /WEB-INF/classes/
> /WEB-INF/web.xml
> /WEB-INF/a.jpg
===============================
===============================
===============================
9,獲取類路徑資源
可以通過Class類的對象來獲取類路徑下的資源,對應JavaWeb應用的類路徑就是classes目錄下的資源
例如:
InputStream in = cn.itcast.servlet.MyServlet.class.getResourceAsStream("a.jpg");
獲取的是:/WEB-INF/classes/cn/itcast/servlet/a.jpg,即與MyServlet.class同目錄下的資源
例如:
InputStream in = cn.itcast.servlet.MyServlet.class.getResourceAsStream("/a.jpg");
獲取的是:/WEB-INF/classes/a.jpg,即類路徑的根目錄下的資源,類路徑的根目錄就是/classes目錄