Servlet是JavaWeb應用開發的核心組件。Servlet運行在Servlet容器中(例如最常用的Tomcat),它可以為各種客戶請求提供相應服務。Servlet可以輕松完成以下任務:
- 動態生成HTML文檔(即服務端交互,動態頁面)
- 把請求轉發給同一個Web應用中的其他Servlet組件。
- 訪問服務器資源(如數據庫訪問)
- 讀取客戶端的Cookie。
ServletAPI有4個包,如下:
- javax.servlet :包含定義了Servlet與Servlet容器之間簽約的類和接口。
- javax.servlet.http : 包含定義了HttpServlet與與Servlet容器之間簽約的類和接口。
- javax.servlet.annotation :包含對Servlet、Filter和Listener進行標注的注解。即Servlet3.0的注解配置。
- javax.servlet.descriptor:包含為Web應用的配置信息提供編程式訪問的類型。
servlet包和servlet.tttp包之間主要接口和類的關系如下:


Servlet的重點對象
請求對象(ServletRequest和HttpServletRequest) :Servlet獲取請求頭信息。
響應對象(ServletResponse和HttpServletResponse) :Servlet生成響應結果。
Servlet配置對象(ServletConfig):Servlet容器創建Servlet實例時,傳入一個ServletConfig對象。 Servlet通過該對象來獲取初始化參數及ServletContext對象。【初始化參數僅作用該Servlet本身】
Servlet上下文對象(ServletContext):Servlet容器啟動Web應用時,創建唯一的ServletContext對象,即代表Web應用。 通過ServletContext對象可以共享web應用資源,可以用於在多個Servlet中共享數據。
【注意:Servlet容器啟動時,JavaWeb應用會被啟動,ServletContext對象隨之創建】
Servlet接口的5個方法
init() //創建servlet實例時,初始化servlet參數。 service() //根據請求方式,處理客戶端請求,並發出響應結果。 destroy() //Web應用銷毀(停止運行)時,執行該方法。通常用於回收資源。 getServletConfig() //返回一個ServletConfig對象,該對象表示Servlet配置信息。 getServletInfo() //返回關於該Servlet的說明信息。
Servlet生命周期
init()、service()和destroy()分別對應Servlet的三個階段:初始化階段、運行時階段和銷毀階段。
對應如下的Servlet執行流程:當客戶端向某個Web服務器發出請求,Tomcat(Servlet容器)接收並解析HTTP請求,然后調用匹配請求的Servlet類。
1.創建Servlet實例,執行init()完成初始化,Servlet容器傳入一個ServletConfig對象。
2.根據請求方式,調用相應的響應方法(doGet()、doPost()或service()),傳入包含請求信息的HttpServletRequest對象和用於響應的HttpServletResponse對象,生成響應結果。
3.Servlet容器將響應結果發送給客戶端,然后執行destroy()方法,銷毀和該Servlet有關的對象。例如請求對象、響應對象以及ServletConfig。至此,Servlet的生命周期結束。
額外說明: 創建Servlet實例有兩種時機:
1.客戶端發起請求,相應的Servlet實例才開始創建。
2.Web應用一啟動,就創建Servlet實例,這里方式需要配置一下:<servlet>中配置<load-on-startup>1</load-on-startup>,值越小,實例化優先級越高。注解配置Servlet,指定參數loadOnStartup = 1。
關於Servlet初始化參數和Web應用的上下文參數的配置方式,在web.xml文件中:
<!-- Web應用參數,可以被Web應用中所有Servlet所共享 --> //使用注解配置初始化參數
<context-param> @WebServlet(urlPatterns= {"/瞎寫的URL"}, name="arbitrary",
<param-name>movement</param-name> initParams= {
<param-value>10086</param-value> @WebInitParam(name="admin", value="牛批"),
</context-param> @WebInitParam(name="info", value="10086")
<context-param> }
<param-name>railway</param-name> )
<param-value>12306</param-value> public class InitParamServlet extends HttpServlet{
</context-param> //省略執行代碼.....
<servlet> }
<servlet-name>ServletConfig_Context_Test</servlet-name>
<servlet-class>com.test.ServletConfig_Context_Test</servlet-class>
<!-- Servlet的初始化參數 -->
<init-param>
<param-name>sevletConfig01</param-name>
<param-value>測試servlet配置信息</param-value>
</init-param>
</servlet>
Servlet四個對象的常用方法說明
HttpServletRequest
獲取請求參數 getParameter(),請求參數有多個值 getParameterValues()
獲取單個請求頭信息 getHeader() 獲取所有請求頭名稱:getHeaderNames(),之后選擇遍歷。
獲取和存取request范圍中的數據, getAttribute(str, object) setAttribute(str, object)
省略其他方法...
HttpServletResponse
setContentType() 設置響應內容類型
setCharacterEncoding(arg0); 設置響應正文字符集
getWriter() 獲取一個字符流,向響應正文中輸出字符數據。 getOutputStream() 向響應正文中輸出二進制數據
addCookie() 往響應正文中添加一個Cookie.
sendRedirect(url) 重定向
ServletConfig和ServletContext獲取參數都是使用getInitParameter(),只不過一個是獲取Servlet初始化參數,一個是Web應用參數。
注意:在Servlet中調用getServletConfig()和getServletContext()方法,需要在響應方法中獲取,不然會導致空指針。若在方法外調用,則需要建立一個ServletConfig變量,執行init()時進行賦值,然后再通過建立的ServletConfig變量調用getServletContext(),
這樣才不會導致NullPointerException
Servlet中四個作用域對象的范圍
ServletContext對象,通過getServletContext()。范圍在整個Web應用。 對應jsp的application對象
HttpSession對象,通過request.getSession()。范圍在會話中。 對應jsp的session對象,Session很常用,要熟悉。
request對象,響應方法的參數直接提供。 范圍在一次請求中。 對應jsp的request對象
this對象,當前Servlet類,范圍僅限於類中。 對應jsp的page對象
上述作用域從大到小,Servlet和jsp的這些對象中都有一個Map集合,由setAttribute()和getAttribute()進行管理,可以將數據放到指定范圍中。
Servlet的轉發、包含和重定向
HttpServletRequest.getRequestDispatcher("URL").forward(request, response); //跳轉到指定URL,本質上是將目標URL頁面內容替換當前頁面。
HttpServletRequest.getRequestDispatcher("URL").include(request, response); //把目標URL內容包含到當前URL頁面內容中,等同於嵌入。
HttpServletResponse.sendRedirect(“URL”); //重定向到指定URL地址,會改變URL地址,相當於打開一個新網頁。
使用說明:forward和include本質上只是對原URL地址頁面做修改,所以URL地址不會改變,請求參數也不會丟失,請求對象依然有效。 而重定向是打開一個新URL地址,即二次請求。原有請求參數和請求對象全部失效!
上面的Servlet知識比較散亂,純粹是個人總結。如需了解更多Servlet的細節知識,請自行查閱Serlvet資料。
下面使用Servlet來實現一些常用的網頁功能
建立一個Servlet類很簡單,繼承HttpServlet抽象類就行。當然,你也可以實現Servlet接口或者繼承GenericServlet抽象類,但HttpServlet抽象類已經幫我們實現了以上兩個類,並擴展了響應請求方法,所以繼承HttpServlet類是最優選擇。
1.Servlet實現一個簡單的登錄信息驗證
<!-- login.html 提交請求到指定URL--> <form action="/HandleFormServlet" method="get"> 賬號:<input type="text" name="user" value=""><br> 密碼:<input type="text" name="password" value=""><br> <input type="submit" value="提交"> <input type="reset" value="重置"><br> </form>
//處理請求的Servlet類,這里采用注解配置Servlet @WebServlet(urlPatterns= {"/HandleFormServlet"}, name="arbitrary") public class HandleFormServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String user = req.getParameter("user"); String psw = req.getParameter("password"); resp.setContentType("text/html;charset=UTF-8"); resp.setCharacterEncoding("UTF-8"); PrintWriter pw = resp.getWriter(); //設置好響應內容類型和字符編碼再獲取輸出流,避免中文亂碼 pw.println("<html><head></head><body>"); if(user!= null && user.equals("123456")) { if(psw!=null && psw.equals("tomcat")) { pw.println("輸入成功!歡迎登錄……<br>"); pw.println("用戶名:" + user + " 密碼:" + psw + "<br>"); }else { pw.println("密碼輸入錯誤"); } }else { pw.println("賬號錯誤"); } pw.println("</body></html>"); } }
輸出結果:
為了簡潔,這里沒有涉及到數據庫,數據是死的。如有需求,可自行加入數據庫訪問,讀取數據庫中相關用戶表信息,進行匹配。
2.Servlet實現一個簡單的文件下載
3.Servlet實現一個簡單的文件上傳
