1. 程式人生 > >JavaWeb開發之詳解Servlet及Servlet容器

JavaWeb開發之詳解Servlet及Servlet容器

由於 servlet開發 遊戲 metadata 移動互 -o 每一個 web開發 port

自JavaEE誕生伊始,Servlet容器和Servlet技術,就構成了JavaEE應用的核心,配合其它組件,它們完善了Java企業級開發的全套解決方案。小到一個靜態博客網站,大到分布式的集群應用,都離不開Servlet底層的支持。大約從Java 5開始,Java企業級開發就分為了兩個不同的方向,一個是基於EJB、JSF、JPA等為主的傳統Java企業級系統開發方案,另一套則是基於Struts、Hibernate、Spring、Spring MVC、MyBatis等為主JavaWeb開發模式。時至今日,移動互聯網的蓬勃發展下,產生了一大批的電商、新零售、在線遊戲、社交網站等各式應用。JavaWeb在時代洪流中反而得到越來越大的發展:分布式、集群、中間件、大數據……給Java帶來了蓬勃生機。

而這些互聯網應用的基礎,都有Servlet的影子。那麽Servlet到底是什麽???

在StackOverflow上就有這麽個問題,題主搞了很久都搞不明白Servlet到底是什麽,希望有人能用淺顯直白的語言一語中的地回答他。排名第一的高票答案是這麽說的:

A servlet is simply a class which responds to a particular type of network request - most commonly an HTTP request. Basically servlets are usually used to implement web applications - but there are also various frameworks which operate on top of servlets (e.g. Struts) to give a higher-level abstraction than the "here‘s an HTTP request, write to this HTTP response" level which servlets provide.

Servlets run in a servlet container which handles the networking side (e.g. parsing an HTTP request, connection handling etc). One of the best-known open source servlet containers is Tomcat.

粗魯翻譯一下就是:Servlet說白了就是一個處理網絡請求(很多時候是Http請求)的類,用於實現Web應用的。另外也有很多的框架比如Struts是以它為底子,搭建了一個更高抽象(的解決方案),而不是讓你挽起袖子直接幹“HTTP請求來了,快給回復”這種層級的粗活。Servlet是運行在處理網絡請求的Servlet容器中的,比如最知名的Tomcat。

Web應用概述

JavaWeb規範

JavaWeb應用因為是容器式開發,因此會有一個模板規範,一個基本Web應用的架勢是:

<WebDemo>   //這是Web應用的名稱

|---WEB-INF  //此文件夾對外不可見

|    |---web.xml  //web應用配置文件(Servlet3.0可不要,但建議保留)

|    |---classes   //保存*.class文件

|    |---lib     //保存jar包

|---<a. jsp> 保存jsp文件等  

web.xml

1. 配置和管理Servlet、Listener、Filter、JSP、JSP屬性、標簽庫

2. Web應用首頁、資源引用、JAAS授權引用、metadata-complete(選true表示不加載註解資源)

Servlet

Servlet開發

Servlet,說白了就是個Java的類。曾幾何時,Servlet甚至被用來寫Web界面,所有的HTML標簽,都采用類似out.write("<head>\r\n")這種形式,繁瑣可想而知。自MVC架構規範以後,Servlet就專註於做控制層了。

Servlet的作用就是處理網絡請求。開發Servlet需繼承HttpServlet,並通過以下方法處理請求:

doGet:響應Get請求

doPOST:響應POST請求

doPut:響應Put請求

doDelete:響應delete請求

init:創建Servlet實例時,初始化Servlet資源(一般不使用,需要初始化的時候,第一行調用super.init())

destory:銷毀Servlet實例時,自動回收資源(一般不使用,除非需要手動回收資源如數據庫連接)

開發步驟

1. 編寫Servlet類

2. 配置

2.1 Servlet3.0新增的@WebServlet配置

2.2 web.xml文件配置

Servlet/JSP生命周期

1. 創建:單例模式,只創建並初始化一個Servlet實例

  • 客戶端第一次請求某個Servlet時,Web容器創建該Servlet實例。
  • Web應用啟動時立即創建,即load-on-startup Servlet。這種Servlet一般是提供基礎服務的後臺Servlet。

2. 初始化:Web容器調用Servlet的init方法初始化

3. 響應請求:初始化後,將一直在容器中,響應客戶請求

4. 銷毀:Web容器決定銷毀Servlet,會調用destroy方法。通常是關閉Web應用時銷毀

註意:Servlet容器中對同一個Servlet類,只會創建和初始化其實例一次,為單例。容器會維護一個線程池,對每一個請求提供一個工作線程去處理。如果請求過多達到線程池峰值,則請求會被放入一個隊列,等待可用線程。

Servlet本身是線程不安全的,因此不建議設置成員變量或類變量,而使用局部變量避免線程問題。

Servlet參數配置

可以用在比如配置數據庫連接參數的場景,實現多個Servlet之間的可重用。

1. 配置

  • 通過@WebServlet的initParams屬性指定
  • 通過web.xml的<servlet>元素中添加<init-params>子元素

2. 訪問

通過ServletConfig對象的getInitParameter(String name)訪問。

註意區分ServletContext,兩者方法相同,但ServletConfig是當前Servlet的配置參數;ServletContext是獲取當前Web應用的配置參數。

ServletContext和HTTPSession由於是多個Servlet中共享信息,因此也是線程不安全的。

MVC中Servlet作為Controller的角色

JSP-Servlet-JavaBean的第一代MVC架構

在遙遠的古代,曾經使用Servlet作為頁面視圖解決方案,開發難度可想而知。因此,在第一代的MVC方案裏,使用JSP做V,JavaBean做M和Servlet作為Controller的方案應運而生。

一個充斥於各種學生管理系統的典型使用場景是:

  • 手機用戶請求參數
  • 將應用的處理結果返回

JSP

JSP的本質就是Servlet,處理用戶請時會被翻譯為Servlet被Web容器執行。Servlet與JSP區別是:

1. 沒有內置對象,JSP中的內置對象需要顯示創建、

2. 對於靜態頁面標簽,都要使用頁面輸出流逐行輸出。

JSP由靜態HTML頁面內容和動態JSP腳本兩部分組成

四種基本語法

  1. 註釋:<%-- JSP註釋 --%>
  2. 聲明:<%! 聲明部分 %>
  3. 表達式:<%=表達式%>
  4. 腳本

3個編譯指令

JSP編譯指令是通知JSP的消息,不直接輸出。包括

  1. page:針對當前頁面的指令。如聲明JSP腳本種類、繼承的父類、導包、是否開啟HTTPSession、錯誤頁面、網頁文件格式和字符編碼等。
  2. include:指定包含另一個頁面。既包括靜態文本,也包括動態JSP頁面。此指令融合被include的頁面
  3. taglib:用於定義和訪問自定義標簽。

7個動作指令

編譯指令是通知Servlet引擎的消息,在JSP編譯成Servlet時起作用;動作指令則可替換成JSP腳本,是JSP腳本的標準化寫法

  1. jsp:forward:執行頁面轉向,將請求處理轉發到下個頁面
  2. jsp:param:傳遞參數,與include、forward、plugin指令合用
  3. jsp:include:動態引入JSP頁面
  4. jsp:plugin:下載JavaBean或Applet到客戶端執行
  5. jsp:useBean:創建一個JavaBean實例
  6. jsp:setProperty:設置JavaBean實例的屬性值
  7. jsp:getProperty :輸出JavaBean實例的屬性值

9個內置對象

這9個內置對象其實都是Servlet接口的實例,在JSP的使用中被默認初始化,可以直接使用。

  • application:ServletContext的實例,代表應用本身,可用於多個JSP和Servlet之間傳遞信息。
  • config:ServletConfig的實例,代表該JSP的配置信息。JSP中比較少用,常用於Servlet
  • exception:Throwable的實例,只有本頁面是錯誤處理頁面時,才能使用。
  • out:JspWriter的實例,表示頁面輸出流。
  • page:代表頁面本身,相當於Servlet的this,沒什麽用。
  • pageContext:PageContext,代表頁面上下文,有方法getServletContext()和getServletConfig()
  • request:HttpServletRequest的實例,表示一次請求
  • response:HttpServletResponse的實例,表示一次回復。通常很少使用該對象直接響應,而是使用out。常用於重定向
  • session:HttpSession實例,代表一次會話(開始於客戶端與服務器連接,終止於關閉瀏覽器)

JSP2的自定義標簽

1. 開發自定義標簽類

  • 繼承SimpleTapSupport父類
  • 重寫doTag()方法
  • 如果有成員變量,需要getter和setter方法

2. 建立TLD文件

3. 使用標簽庫

<% taglib uri="tagliburi" prefix="tagPrefix" %>

Filter

Filter是Servlet的加強版,用於對用戶請求進行預處理或後處理。一個典型的應用場景是:Filter對用戶請求進行預處理,接著交給Servlet進行處理並響應,最後Filter再進行後處理。

預處理:攔截和檢查HttpServletRequest,可以修改請求頭和數據

後處理:攔截和檢查HttpServletResponse,可以修改響應頭和數據

Filter常用於檢查用戶請求、過濾非法請求、日誌記錄、請求解碼、處理XML等

Filter也被用於實現網站的偽靜態,以優化SEO。

開發過濾器

1. 創建Filter類:實現Filter接口,重寫init、destory和doFilter(ServletRequest request, ServeletResponse response, FilterChain chain)方法

2. 配置

Listener

使用監聽器

1. 定義Listener實現類

2. 配置

JavaWeb開發之詳解Servlet及Servlet容器