Servlet 2.x 規範

Servlet 2.x 規範

sun 公司制訂的一種基於 Java 技術的 WEB 服務器功能的組件規範。1997 年六月,Servlet 1.0 版本發行,最新版本 Servlet 4.0 處於研發狀態。css

所謂的 Servlet 容器,有時候也稱做爲 Servlet 引擎,做爲 Web 服務器或應用服務器的一部分。經過請求和響應對話,提供 Web 客戶端與 Servlets 交互的能力。容器管理 Servlets 實例以及它們的生命週期。html

1、Servlet 組件

Servlet 容器的組件大體能夠分爲如下幾類:java

Servlet 組件
  ├── 服務組件
  |    ├── javax.servlet.Servlet
  |    └── javax.servlet.Filter(since Servlet 2.3)
  |
  ├── 上下文組件
  |    ├── javax.servlet.ServletContext
  |    ├── javax.servlet.http.HttpSession
  |    ├── javax.servlet.http.HttpServletRequest
  |    ├── javax.servlet.http.HttpServletResponse
  |    └── javax.servlet.http.Cookie(客戶端)
  |
  ├── 配置
  |    ├── javax.servlet.ServletConfig
  |    └── javax.servlet.FilterConfig(since Servlet 2.3 )
  |
  ├── 輸入輸出
  |    ├── javax.servlet.ServletInputStream
  |    └── javax.servlet.ServletOutputStream
  |
  ├── 異常
  |    └── javax.servlet.ServletException
  |
  ├── 事件(since Servlet 2.3 )
  |    ├── 生命週期類型
  |    |      ├── javax.servlet.ServletContextEvent
  |    |      ├── javax.servlet.http.HttpSessionEvent
  |    |      └── java.servlet.ServletRequestEvent
  |    ├── 屬性上下文類型
  |    |      ├── javax.servlet.ServletContextAttributeEvent
  |    |      ├── javax.servlet.http.HttpSessionBindingEvent
  |    |      └── javax.servlet.ServletRequestAttributeEvent
  |    |
  ├── 監聽器(since Servlet 2.3)
  |    ├── 生命週期類型
  |    |      ├── javax.servlet.ServletContextListener
  |    |      ├── javax.servlet.http.HttpSessionListener
  |    |      ├── javax.servlet.http.HttpSessionActivationListener
  |    |      └── javax.servlet.ServletRequestListener
  |    |
  └────└── 屬性上下文類型
              ├── javax.servlet.ServletContextAttributeListener
              ├── javax.servlet.http.HttpSessionAttributeListener
              ├── javax.servlet.http.HttpSessionBindingListener
              └── javax.servlet.ServletRequestAttributeListener

Servlet 2.x 組件關係

  1. Servlet 接口:init(ServletConfig config)、service(ServletRequest req, ServletResponse res)、destroy()
  2. GenericServlet 抽象類:實現了 Servlet 接口中的 init, destroy 方法
  3. HttpServlet 抽象類:繼承了 GenericServlet 抽象類,實現了 service()
  4. ServletConfig 接口:String getInitParameter(String paraName)
  5. ServletRequest 接口:HttpServletRequest 的父接口
  6. ServletResponse 接口:HttpServletResponse 的父接口

1、Servlet

1.1 Servlet 的生命週期

Servlet 的生命週期指 Servlet 容器如何去建立 Servlet 對象、如何調用 Servlet 對象的方法來處理請求、以及如何銷燬 Servlet 對象的整個過程。web

Servlet 生命週期的三個階段:瀏覽器

(1) 初始化服務器

當容器啓動或者第一次執行時,Servlet#init(ServletConfig) 方法被執行,初始化當前 Servlet 。併發

(2) 處理請求app

當 HTTP 請求到達容器時,Servlet#service(ServletRequest, ServletResponse) 方法被執行,來處理請求。編碼

(3) 銷燬url

當容器關閉時,容器將會調用 Servlet#destroy() 方法被執行,銷燬當前 Servlet。

1.2 Servlet 如何處理請求資源路徑

  1. Servlet 容器會先假設訪問的是一個 Servlet ,會依據應用名(appname)找到應用所在的文件夾,而後找到 web.xml 文件。

  2. 匹配

    • 精確匹配(徹底匹配)
    • 通配符匹配:使用 * 匹配任意長度的字符串。eg: /*
    • 後綴匹配:使用 . 開頭,後面能夠接任意字符。eg: .do
  3. 若是都不匹配,則容器認爲訪問的是一個靜態資源文件(html/css/js),若是找到則返回,不然返回404。

1.3 Servlet 是如何運行的?

  1. 瀏覽器依據 ip, port 創建與 Servlet 容器之間的鏈接。
  2. 瀏覽器將請求數據打包(即按照 http 協議的要求,將相關數據封閉成一個數據包,即請求數據包)併發送給 Servlet 容器。
  3. Servlet 容器解析請求數據包,並將解析後的數據放到 request 對象上。同時建立一個 response 對象。
  4. Servlet 容器依據請求資源路徑找到 Servlet 的配置,而後建立 Servlet 對象。
  5. Servlet 調用 service 方法,而且會將事先建立好的 request 對象和 response 對象做爲 service 方法的參數傳遞給 Servlet 對象。
  6. Servlet 經過 request 對象得到請求參數,進行相應的處理,而後將處理結果寫到 response 對象上。
  7. Servlet 讀取 response 對象上的數據,而後將處理結果打包(響應數據包)併發送給瀏覽器。
  8. 瀏覽器解析響應數據包,將返回的數據展示給用戶。

1.4 實例

public class HelloWorldServlet extends HttpServlet {
    public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
        //1. 讀請求參數值
        String qtyStr = req.getParameter("qty");
        int qty = Integer.parseInt(qtyStr);
        //2. 處理請求
        String rs = "";
        for (int i = 0; i < qty; i++) {
            rs += "<h1>Hello World</h1>";
        }
        //3. 設置一個消息頭 content-type,告訴瀏覽器返回的數據類型是一個 html 文檔及編碼格式
        //告訴服務器使用 out 輸出時使用指定的編碼格式進行編碼
        res.setContentType("text/html;charset=utf-8");
        //四、得到一個輸出流
        PrintWriter out = res.getWriter();
        //五、調用流的方法進行輸出,其實質是將處理結果寫到了 res 對象上
        out.println(rs);
        out.close();
    }
}

配置 WEB-INF/web.xml 配製文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>helloWord</servlet-name>
        <!--類名要完整(包名,類名都要全)-->
        <servlet-class>com.herolei.HelloWorldServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloWord</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

啓動程序,訪問 http://localhost:8080/hello?qty=30

補充:web 打包後的目錄以下

appname(應用名)
  └──WEB-INF
      ├──classes    .class文件
      ├──lib        .jar文件,lib文件夾可選
      └──web.xml    部署描述文件

2、Listener

Servlet 規範當中定義的一種特殊的組件,用來監聽容器產生的事件並進行處理。

容器會產生兩大類事件:

  1. 生命週期相關的事件:容器在建立或者銷燬 request, servletContext(Servlet 上下文)時產生的事件。對應的接口有 ServletRequestListener、ServletContextListener。
  2. 綁定相關的事件:容器調用了 request, servletContext 的 setAttribute, removeAttribute 時產生的事件。。對應的接口有 ServletContextAttributeListener、ServletRequestAttributeListener。
public interface ServletContextListener extends EventListener {
    // 容器初始化
    void contextInitialized(ServletContextEvent ctx);
    // 容器銷燬
    void contextDestroyed(ServletContextEvent ctx);
}

public interface ServletContextAttributeListener extends EventListener {
    void attributeAdded(ServletContextAttributeEvent event);
    void attributeRemoved(ServletContextAttributeEvent event);
    void attributeReplaced(ServletContextAttributeEvent event);
}

3、Filter

public interface Filter {
    // 初始化 Filter
    void init(FilterConfig filterConfig) throws ServletException;

    // 調用,若是要繼續調用下一個 Filter,須要調用 chain.doFilter(request, response)
    void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;

    // 銷燬
    public void destroy();
}

public interface FilterChain {
    void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;
}

Filter 生命週期以下:

(1) 初始化

當容器啓動時,Filter#init(FilterConfig) 方法被執行,初始化當前 Filter。

(2) 處理請求

當 HTTP 請求到達容器時,Filter#doFilter(ServletRequest,ServletResponse,FilterChain) 方法被執行,來攔截請求,在 Servlet#service(ServletRequest,ServletResponse) 方法調用前執行。

(3) 銷燬

當容器關閉時,容器將會調用 Filter#destroy() 方法被執行,銷燬當前 Filter。

參考:

  1. 《Servlet 規範》:https://www.runoob.com/servlet/servlet-life-cycle.html

天天用心記錄一點點。內容也許不重要,但習慣很重要!

相關文章
相關標籤/搜索