Java-Servlet知識總結


Servlet概述

爲什麼要學習Servlet

Java Web的演變過程大概可以分爲4個階段:

  • Servlet + jdbc + jsp
  • Spring + Struts2+ Hibernate(SSH)
  • Spring + SpringMVC + Mybatis(SSM)
  • 微服務階段

前兩個階段基本上可以說是歷史了,當今Spring家族一統天下。

現在實際開發中很少直接使用Servlet了,但是各個框架的底層還是大量使用了Servlet,學習Servlet對後續各個框架的理解和學習都很有幫助。

什麼是 Servlet

Servlet 是運行在 Web 服務器或應用服務器上的程序,它是作爲來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務器上的數據庫或應用程序之間的中間層。

Servlet其實就是一個遵循Servlet開發的java類。Serlvet是由服務器調用的,運行在服務器端。

Servlet帶給我們最大的作用就是能夠處理瀏覽器帶來HTTP請求,並返回一個響應給瀏覽器,從而實現瀏覽器和服務器的交互

工作流程

  • Tomcat將瀏覽器提交的請求封裝成HttpServletRequest對象,同時將輸出流封裝成HttpServletResponse對象

  • Tomcat把request、response作爲參數,調用Servlet的相應方法,例如doGet(request, response)等

  • Servlet中主要處理業務邏輯


生命週期

在 Web 容器中,Servlet 主要經歷 4 個階段,如下圖:
Servlet 生命週期

  1. 加載Servlet。當Tomcat第一次訪問Servlet的時候,Tomcat會負責創建Servlet的實例
  2. 初始化。當Servlet被實例化後,Tomcat會調用init()方法初始化這個對象
  3. 處理服務。當瀏覽器訪問Servlet的時候,Servlet 會調用service()方法處理請求
  4. 銷燬。當Tomcat關閉時或者檢測到Servlet要從Tomcat刪除的時候會自動調用destroy()方法讓該實例釋放掉所佔的資源。一個Servlet如果長時間不被使用的話,也會被Tomcat自動銷燬
  5. 卸載。當Servlet調用完destroy()方法後,等待垃圾回收。

如果有需要再次使用這個Servlet,會重新調用init()方法進行初始化操作

只要訪問Servlet,service()就會被調用。init()只有第一次訪問Servlet的時候纔會被調用。

destroy()只有在Tomcat關閉的時候纔會被調用。


處理請求的方法

Servlet 即實現了 Servlet 接口 的類,實現 Servlet 接口 的時候,需要實現5個方法

public interface Servlet {
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

    void destroy();
}

爲了方便使用可以直接繼承 HttpServlet 類,該類已經默認實現了 Servlet 接口中的所有方法。

在編寫 Servlet 的時候,只需要重寫你需要的方法就好了。

並且該類還在原有 Servlet 接口上添加了一些與 HTTP 協議處理相關的方法。

  • Servlet 處理請求的方法一共有三種:
    • 實現 service() 方法
    • 重寫 doGet()
    • 重寫 doPost()

HttpServletRequest 和 HttpServletResponse

對於每次訪問請求,Servlet引擎都會創建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,即 request 和 response 對象。

HttpServletRequest 常用方法

  • String getContextPath()
    獲取上下文路徑
  • String getHeader(String headName)
    根據指定的請求頭獲取對應的請求頭的值.
  • String getRequestURI()
    返回當期請求的資源名稱. 上下文路徑/資源名
  • StringBuffer getRequestURL()
    返回瀏覽器地址欄的內容
  • String getRemoteAddr()
    返回請求服務器的客戶端的IP

獲取請求參數的方法:

  • String getParameter(String name)
    根據參數名稱,獲取對應參數的值.
  • String[] getParameterValues(String name)
    根據參數名稱,獲取該參數的多個值.
  • Enumeration getParameterNames()
    獲取所有請求參數的名字
  • Map<String,String[]> getParameterMap()
    返回請求參數組成的Map集合.

HttpServletResponse 常用方法

  • OutputStream getOutputStream():
    獲取字節輸出流:文件下載

  • Writer getWriter()
    獲取字符輸出流:輸出內容

  • resp.setContentType("text/html;charset=utf-8")

    設置文件輸出的編碼格式和內容類型

  • resp.sendRedirect()

    302重定向,臨時跳轉

    301要使用另外的手段

Servlet 是單例的

解釋

瀏覽器多次對Servlet的請求,一般情況下,服務器只創建一個Servlet對象,也就是說,Servlet對象一旦創建了,就會駐留在內存中,爲後續的請求做服務,直到服務器關閉。

每次訪問請求對象和響應對象都是新的

對於每次訪問請求,Servlet引擎都會創建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,然後將這兩個對象作爲參數傳遞給它調用的Servlet的service()方法,service()方法再根據請求方式分別調用其他方法。

線程安全問題

當多個用戶訪問Servlet的時候,服務器會爲每個用戶創建一個線程。當多個用戶併發訪問Servlet共享資源的時候就會出現線程安全問題。

原則

  1. 如果一個變量需要多個用戶共享,則應當在訪問該變量的時候,需要加鎖
  2. 如果一個變量不需要共享,直接在 doGet() 或者 doPost()定義,這樣不會存在線程安全問題

通過註解配置 Servlet

在之前的開發工作中,每次編寫一個Servlet都需要在web.xml文件中進行配置

<servlet>
    <servlet-name>ActionServlet</servlet-name>
    <servlet-class>com.web.controller.ActionServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>ActionServlet</servlet-name>
    <url-pattern>/servlet/ActionServlet</url-pattern>
</servlet-mapping>

而當一個項目中存在很多 Servlet,那麼配置文件就會變得很亂很大,在 Servlet 3.0 推出之後,我們可以使用註解來配置 Servlet

@WebServlet(name = "ActionServlet", urlPatterns = "/servlet/ActionServlet")

Web 組件之間的跳轉方式

請求轉發(forward)

又叫做直接轉發方式,客戶端和瀏覽器只發出一次請求,Servlet、HTML、JSP或其它信息資源,由第二個信息資源響應該請求,在請求對象request中,保存的對象對於每個信息資源是共享的。

比如:從 AServlet 請求轉發到 BServlet

img

  • 語法:
request.getRequestDispatcher(path).forward(request, response);

參數:path,要跳轉到的資源路徑:上下文路徑 / 資源路徑

  • 特點:
    • 地址欄中的地址不變
    • 只有一個請求
    • 資源是共享的
    • 可以訪問 WEB-INF 中的資源
    • 請求轉發不能跨域訪問

URl 重定向(redirect)

又叫做間接轉發方式(Redirect)實際是兩次HTTP請求,服務器端在響應第一次請求的時候,讓瀏覽器再向另外一個URL發出請求,從而達到轉發的目的。

比如:從AServlet重定向到BServlet

img

  • 語法:
response.sendRedirect(String location);

參數:location,轉發到的資源路徑

  • 特點:
    • 地址欄中的地址【會】發生改變
    • 有兩個請求
    • 在兩個 Servlet 中不可以共享請求中的數據
    • 最終的響應由BServlet來決定,和 AServlet 沒有關係
    • 不可以訪問 WEB-INF 中的資源
    • 請求轉發可以跨域訪問

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章