JAVA EE-SERVLET
未來將屬於兩種人:思想的人和勞動的人。實際上這兩種人是一種人,因爲思想也是勞動。 —— 雨果
什麼是servlet?
- Servlet => Server Applet => 服務器端的小程序(類)
- Servlet技術中的三大組件之一
- Servlet 動態資源
- FIlter 過濾器
- Listener 監聽器 - Servlet就是一個接口. 接口中定義了一些方法. 這些方法分爲兩部分。一部分是生命週期方法。 一部分沒啥用。
實現servlet接口的方式?
*實現接口
*繼承GenericServlet
*繼承HTTPServlet
創建Servlet類–實現Servlet類
/**
* 實現Servlet接口,重寫5個方法
* 在web.xml進行配置
* @author Administrator
*
*/
public class ServletDemo1 implements Servlet{
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.getWriter().write("hello demo1...");
}
public void init(ServletConfig config) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
Servlet的生命週期
*Servlet對象創建時機? 第一次訪問servlet時.
*Servlet對象創建的特點? 通過只在第一次訪問時調用init的現象, 一個servlet實例在服務器中只有一個.
*當請求訪問servlet時,service方法會處理請求.
*當服務器將要關閉,服務器會銷燬服務器中的Servlet對象,在真正銷燬之前調用destory方法.
/**
* 生命週期
* @author Administrator
*
*/
public class ServletDemo2 implements Servlet {
/**
* Servlet實例被創建後,調用init方法進行初始化
* Servlet什麼時候被創建呢?
* * 不是服務器一啓動時,實例被創建,第一次訪問的時候,實例才被創建。
* init方法調用幾次呢?
* * 只被調用一次。
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("init...");
}
/**
* service調用幾次呢?
* * 有一次請求,調用一次service方法
*/
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
System.out.println("service...");
}
/**
* Servlet實例什麼時候被銷燬呢?
* * 服務器關閉,手動移除。
* destroy調用幾次呢?
* * 一次
*/
public void destroy() {
System.out.println("destroy...");
}
public ServletConfig getServletConfig() {
return null;
}
public String getServletInfo() {
return null;
}
}
通過繼承HttpServlet創建Servlet
/**
* 配置servlet啓動時加載
* @author Administrator
*
*/
public class ServletDemo5 extends HttpServlet {
/**
* 默認的情況下第一次訪問的時候init被調用。
*
*/
public void init() throws ServletException {
System.out.println("init...");
// 初始化數據庫的鏈接
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 寫的內容
// 獲取表單輸入的內容
// 自己邏輯,通過名稱查詢數據庫,把張三的姓名查到了
// 把張三返回瀏覽器
System.out.println("doGet...");
// 向頁面輸出內容
response.getWriter().write("hello demo5...");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
關於ServletConfig對象
/**
* ServletConfig對象
* @author Administrator
*
*/
public class ServletDemo6 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 測試ServletConfig對象的api
// 先獲取ServletConfig對象
ServletConfig config = getServletConfig();
// 獲取配置文件中serlvet的名稱
System.out.println("servlet的名稱:"+config.getServletName());
// 獲取初始化的參數
String username = config.getInitParameter("username");
String password = config.getInitParameter("password");
System.out.println(username+" : "+password);
Enumeration<String> e = config.getInitParameterNames();
while(e.hasMoreElements()){
String name = e.nextElement();
String value = config.getInitParameter(name);
System.out.println(name+" : "+value);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
利用response完成重定向
/**
* 和location和302一起完成重定向
* @author Administrator
*
*/
public class ServletDmo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 向頁面輸出內容
response.setContentType("text/html;charset=UTF-8");
// response.getWriter().write("向班長借錢...");
// 我沒錢
response.setStatus(302);
// 告訴我富班長的地址
response.setHeader("location", "/day09/1.html");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
利用request完成刷新操作
/**
* 頁面定時跳轉
* @author Administrator
*
*/
public class RefreshServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("訪問到了...");
// 頁面5秒會跳轉
response.setHeader("refresh", "5;url=/day09/1.html");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
一個小的Demo,獲得某網站被訪問的次數
CountServlet
/**
* 統計網站的訪問次數
* @author Administrator
*
*/
public class CountServlet extends HttpServlet {
/**
* 實例被創建,調用init方法進行初始化
* 在域對象存入一個變量,賦值爲0
*/
public void init() throws ServletException {
// 獲取ServletContext對象
getServletContext().setAttribute("count", 0);
}
/**
* 每一次訪問,都會執行該方法。
* 拿出count的變量,值自增,存入到域對象中
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 先獲取ServletContext對象
ServletContext context = getServletContext();
// 獲取count的值,自增
Integer count = (Integer) context.getAttribute("count");
// 存入到域對象中
context.setAttribute("count", ++count);
// 向頁面輸出內容
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<h3>大爺,歡迎再來哦!!</h3>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
ShowServlet
/**
* 顯示網站的訪問次數
* @author Administrator
*
*/
public class ShowServlet extends HttpServlet {
/**
* 獲取網站的訪問次數,輸出到客戶端
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Integer count = (Integer) getServletContext().getAttribute("count");
// 向頁面輸出
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<h3>該網站一共被訪問了"+count+"次</h3>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
關於ServletContext對象
ServletContext 對象可以看做是web項目的法人.
我們一個WEB項目 有 且只有一個ServletContext .
創建: 隨着項目的啓動而創建
銷燬:隨着項目的關閉而銷燬
獲得:通過ServletConfig對象的 getServletContext方法獲得.
功能:
1.可以獲得項目參數
2.是Servlet技術中的3個域對象之一
3.獲得項目內的資源
//———————————————————————————–
功能詳解:
1>獲得項目參數
String getInitParameter(String name)
Enumeration getInitParameterNames()
//—————————————————–
2>域功能
Servlet三大域
application
request
session
jsp技術中的域
page
域用於服務器組件之間的通訊(例如:兩個servlet之間通訊).
域的實質就是map.
application域 就是在整個項目內共享數據的map.
*操作域的方法:
void setAttribute(String key,Object value);
Object getAttribute(String key);
Enumeration<String> getAttributeNames();
void removeAttribute(String key);
//————————————————————————————–
3>獲得項目內資源
// 該方法使用相對路徑獲得 資源的流 其中 "/" ==> 項目根下 WebRoot
InputStream sc.getResourceAsStream();
// 使用相對路徑獲得絕對路徑
String sc.getRealPath("/student.xml");
獲取項目/磁盤下的資源
/**
* 讀取資源文件
* @author Administrator
*
*/
public class ReadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
read5();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
* 通過ServletContext對象獲取文件的絕對磁盤路徑
* 獲取src目錄下文件
* @throws IOException
*/
public void read5() throws IOException{
// 獲取對象
String path = getServletContext().getRealPath("/WEB-INF/classes/db.properties");
// System.out.println(path);
// C:\apache-tomcat-6.0.14\webapps\day09\WEB-INF\classes\db.properties
// 獲取輸入流
InputStream in = new FileInputStream(path);
print(in);
}
/**
* 獲取WebRoot目錄目錄下db.properties文件
* @throws IOException
*/
public void read4() throws IOException{
// ServletContext讀取文件
InputStream in = getServletContext().getResourceAsStream("/db.properties");
// 打印方式
print(in);
}
/**
* 獲取包目錄下db.properties文件
* @throws IOException
*/
public void read3() throws IOException{
// ServletContext讀取文件
InputStream in = getServletContext().getResourceAsStream("/WEB-INF/classes/cn/itcast/context/db.properties");
// 打印方式
print(in);
}
/**
* 獲取src目錄下db.properties文件
* @throws IOException
*/
public void read2() throws IOException{
// ServletContext讀取文件
InputStream in = getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
// 打印方式
print(in);
}
/**
* 傳統方式讀取資源文件
* 交給服務器處理,相對的位置tomcat/bin
* @throws IOException
*/
public void read1() throws IOException{
// 獲取輸入流
InputStream in = new FileInputStream("src/db.properties");
print(in);
}
/**
* 在控制檯打印內容
* @param in
* @throws IOException
*/
public void print(InputStream in) throws IOException{
Properties pro = new Properties();
// 加載
pro.load(in);
// 獲取文件中的內容
String username = pro.getProperty("username");
String password = pro.getProperty("password");
String desc = pro.getProperty("desc");
System.out.println("用戶名:"+username);
System.out.println("密碼:"+password);
System.out.println("描述:"+desc);
}
}
關於路徑配置的問題:
默認情況: 第一次訪問該servlet時候.
讓servlet實例隨着服務器的啓動而創建:
添加一個配置即可:<load-on-startup></load-on-startup>
在該配置中填入一個整數即可實現.
數字的數值,在有多個servlet需要隨着服務器啓動而啓動時,決定啓動順序.
數字越小優先級越高. 最小就是0. 一般0~5. 3.
如果數字一樣,誰先配置誰先創建.
*servlet的路徑配置
<url-pattern></url-pattern>
該配置,配置方式有兩種
路徑匹配: 一定以"/"開頭
/AServlet
/ABC/AServlet
/ABC/BCD/AServlet
/ABC/*
/*
/
後綴名匹配: 以*開頭
*.do
*.action
*.html
注意:
匹配範圍越大,優先級越低.
後綴名匹配和路徑匹配不能同一配置中混合使用. 例如: /*.do
一個servlet可以配置多個路徑. 直接在<servlet-mapping>元素中添加多個<url-pattern>配置即可.
優先級: /AServlet > /abc/* > *.do > /*