Servlet 入門

Servlet: server applet

運行在服務(wù)器端的小程序

  • Servlet就是一個接口,定義了Java類被瀏覽器訪問到(tomcat識別)的規(guī)則。
  • 自定義一個類,實現(xiàn)Servlet接口,復(fù)寫方法。

快速入門

  1. 創(chuàng)建JavaEE項目
    image
  2. 定義一個類,實現(xiàn)Servlet接口
    package cn.web;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class ServletDemo1 implements Servlet {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
    
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
        @Override
        public void destroy() {
    
        }
    }
    
  3. 實現(xiàn)接口中的抽象方法
  4. 配置Servlet
    web.xml中配置, 寫在</web-app>標(biāo)簽里面
    <!--配置Servlet -->
        <servlet>
            <servlet-name>demo1</servlet-name>
            <servlet-class>cn.web.ServletDemo1</servlet-class>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>demo1</servlet-name>
            <url-pattern>/demo1</url-pattern>
        </servlet-mapping>
    

執(zhí)行原理

  1. 當(dāng)服務(wù)器接受到客戶端瀏覽器的請求后,會解析請求URL路徑,獲取訪問的Servlet的資源路徑
  2. 查找web.xml文件,是否有對應(yīng)的<url-pattern>標(biāo)簽體內(nèi)容。
  3. 如果有,則在找到對應(yīng)的<servlet-class>全類名
  4. tomcat會將字節(jié)碼文件加載進內(nèi)存,并且創(chuàng)建其對象
  5. 調(diào)用service方法

生命周期

  1. 被創(chuàng)建:執(zhí)行·方法,只執(zhí)行一次
    • Servlet什么時候被創(chuàng)建?

      • 默認情況下,第一次被訪問時,Servlet被創(chuàng)建
      • 可以配置執(zhí)行Servlet的創(chuàng)建時機。
        • 在<servlet>標(biāo)簽下配置
          1. 第一次被訪問時,創(chuàng)建
            • <load-on-startup>的值為負數(shù)
          2. 在服務(wù)器啟動時,創(chuàng)建
            • <load-on-startup>的值為0或正整數(shù)
    • Servlet的init方法,只執(zhí)行一次,說明一個Servlet在內(nèi)存中只存在一個對象,Servlet是單例的

      • 多個用戶同時訪問時,可能存在線程安全問題。
      • 解決:盡量不要在Servlet中定義成員變量。即使定義了成員變量,也不要對修改值
  2. 提供服務(wù):執(zhí)行service方法,執(zhí)行多次
    • 每次訪問Servlet時,Service方法都會被調(diào)用一次。
  3. 被銷毀:執(zhí)行destroy方法,只執(zhí)行一次
    • Servlet被銷毀時執(zhí)行。服務(wù)器關(guān)閉時,Servlet被銷毀
    • 只有服務(wù)器正常關(guān)閉時,才會執(zhí)行destroy方法。
    • destroy方法在Servlet被銷毀之前執(zhí)行,一般用于釋放資源

Servlet3.0

  • 好處:

    • 支持注解配置??梢圆恍枰?code>web.xml了。
  • 步驟:

    1. 創(chuàng)建JavaEE項目,選擇Servlet的版本3.0以上,可以不創(chuàng)建web.xml
    2. 定義一個類,實現(xiàn)Servlet接口
    3. 復(fù)寫方法
    4. 在類上使用@WebServlet注解,進行配置
      @WebServlet("資源路徑")
          @Target({ElementType.TYPE})
          @Retention(RetentionPolicy.RUNTIME)
          @Documented
          public @interface WebServlet {
              String name() default "";//相當(dāng)于<Servlet-name>
          
              String[] value() default {};//代表urlPatterns()屬性配置
          
              String[] urlPatterns() default {};//相當(dāng)于<url-pattern>
          
              int loadOnStartup() default -1;//相當(dāng)于<load-on-startup>
          
              WebInitParam[] initParams() default {};
          
              boolean asyncSupported() default false;
          
              String smallIcon() default "";
          
              String largeIcon() default "";
          
              String description() default "";
          
              String displayName() default "";
          }
      

urlpartten:Servlet訪問路徑

  1. 一個Servlet可以定義多個訪問路徑 : @WebServlet({"/d4","/dd4","/ddd4"})
  2. 路徑定義規(guī)則:
    1. /xxx:路徑匹配
    2. /xxx/xxx:多層路徑,目錄結(jié)構(gòu)
    3. *.do:擴展名匹配

HttpServlet

Servlet的體系結(jié)構(gòu)

image
  • GenericServlet:將Servlet接口中其他的方法做了默認空實現(xiàn),只將service()方法作為抽象, 將來定義Servlet類時, 可以繼承GenericServlet,實現(xiàn)service()方法即可
  • HttpServlet:對http協(xié)議的一種封裝,簡化操作
    1. 定義類繼承HttpServlet
    2. 復(fù)寫doGet/doPost方法

Request

request對象和response對象的原理

1. `request`和`response`對象是由服務(wù)器創(chuàng)建的。我們來使用它們
2. `request`對象是來獲取請求消息,`response`對象是來設(shè)置響應(yīng)消息

request對象繼承體系結(jié)構(gòu)

    ServletRequest  -- 接口
        |   繼承
    HttpServletRequest  -- 接口
        |   實現(xiàn)
    org.apache.catalina.connector.RequestFacade 類(tomcat)
image

request功能

獲取請求消息數(shù)據(jù)

    @WebServlet("/demo2")
    public class ServletDemo2 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        }

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String contextPath = request.getContextPath();
            System.out.println("contextPath = " + contextPath);

            String servletPath = request.getServletPath();
            System.out.println("servletPath = " + servletPath);

            String method = request.getMethod();
            System.out.println("method = " + method);

            String queryString = request.getQueryString();
            System.out.println("queryString = " + queryString);

            String requestURI = request.getRequestURI();
            System.out.println("requestURI = " + requestURI);

            StringBuffer requestURL = request.getRequestURL();
            System.out.println("requestURL = " + requestURL);

            String remoteAddr = request.getRemoteAddr();
            System.out.println("remoteAddr = " + remoteAddr);
        }
    }

    contextPath = /UserDemo_war_exploded
    servletPath = /demo2
    method = GET
    queryString = name=IIce
    requestURI = /UserDemo_war_exploded/demo2
    requestURL = http://localhost:8080/UserDemo_war_exploded/demo2
    remoteAddr = 0:0:0:0:0:0:0:1

其他功能

  1. 獲取請求參數(shù)通用方式:不論get還是post請求方式都可以使用下列方法來獲取請求參數(shù)

    1. String getParameter(String name):根據(jù)參數(shù)名稱獲取參數(shù)值 username=zs&password=123
    2. String[] getParameterValues(String name):根據(jù)參數(shù)名稱獲取參數(shù)值的數(shù)組 hobby=xx&hobby=game
    3. Enumeration<String> getParameterNames():獲取所有請求的參數(shù)名稱
    4. Map<String,String[]> getParameterMap():獲取所有參數(shù)的map集合
    5. 中文亂碼問題
      • 解決:在獲取參數(shù)前,設(shè)置request的編碼request.setCharacterEncoding("utf-8");
  2. 請求轉(zhuǎn)發(fā):一種在服務(wù)器內(nèi)部的資源跳轉(zhuǎn)方式

    1. 步驟:

      1. 通過request對象獲取請求轉(zhuǎn)發(fā)器對象:RequestDispatcher getRequestDispatcher(String path)
      2. 使用RequestDispatcher對象來進行轉(zhuǎn)發(fā):forward(ServletRequest request, ServletResponse response)
    2. 特點:

      1. 瀏覽器地址欄路徑不發(fā)生變化
      2. 只能轉(zhuǎn)發(fā)到當(dāng)前服務(wù)器內(nèi)部資源中。
      3. 轉(zhuǎn)發(fā)是一次請求
  3. 共享數(shù)據(jù):

    • 域?qū)ο螅阂粋€有作用范圍的對象,可以在范圍內(nèi)共享數(shù)據(jù)
    • request域:代表一次請求的范圍,一般用于請求轉(zhuǎn)發(fā)的多個資源中共享數(shù)據(jù)
    • 方法:
      1. void setAttribute(String name,Object obj):存儲數(shù)據(jù)
      2. Object getAttitude(String name):通過鍵獲取值
      3. void removeAttribute(String name):通過鍵移除鍵值對
  4. 獲取ServletContext

    • ServletContext getServletContext()

JavaBean

用于封裝JavaBean的

  1. JavaBean:標(biāo)準(zhǔn)的Java類

    1. 要求:
      1. 類必須被public修飾
      2. 必須提供空參的構(gòu)造器
      3. 成員變量必須使用private修飾
      4. 提供公共settergetter方法
    2. 功能:封裝數(shù)據(jù)
  2. 概念:
    成員變量:
    屬性:settergetter方法截取后的產(chǎn)物, 例如:getUsername() --> Username--> username

  3. 方法:

    1. setProperty()
    2. getProperty()
    3. populate(Object obj , Map map):將map集合的鍵值對信息,封裝到對應(yīng)的JavaBean對象中

HTTP

響應(yīng)頭

常見的響應(yīng)頭:

  1. Content-Type:服務(wù)器告訴客戶端本次響應(yīng)體數(shù)據(jù)格式以及編碼格式
  2. Content-disposition:服務(wù)器告訴客戶端以什么格式打開響應(yīng)體數(shù)據(jù)
    • 值:
      • in-line:默認值,在當(dāng)前頁面內(nèi)打開
      • attachment;filename=xxx:以附件形式打開響應(yīng)體。文件下載

Response對象

設(shè)置響應(yīng)消息

設(shè)置響應(yīng)行

  1. 格式:HTTP/1.1 200 ok
  2. 設(shè)置狀態(tài)碼:setStatus(int sc)

設(shè)置響應(yīng)頭

setHeader(String name, String value)

設(shè)置響應(yīng)體

  1. 獲取輸出流
    • 字符輸出流:PrintWriter getWriter()
    • 字節(jié)輸出流:ServletOutputStream getOutputStream()
  2. 使用輸出流,將數(shù)據(jù)輸出到客戶端瀏覽器

重定向

    //簡單的重定向方法
    response.sendRedirect("/responseDemo2");
  • 重定向的特點:redirect
    1. 地址欄發(fā)生變化
    2. 重定向可以訪問其他站點(服務(wù)器)的資源
    3. 重定向是兩次請求。不能使用request對象來共享數(shù)據(jù)
  • 轉(zhuǎn)發(fā)的特點:forward
    1. 轉(zhuǎn)發(fā)地址欄路徑不變
    2. 轉(zhuǎn)發(fā)只能訪問當(dāng)前服務(wù)器下的資源
    3. 轉(zhuǎn)發(fā)是一次請求,可以使用request對象來共享數(shù)據(jù)

路徑問題

  1. 相對路徑:通過相對路徑不可以確定唯一資源
    • 如:./index.html

    • 不以/開頭,以.開頭路徑

    • 規(guī)則:找到當(dāng)前資源和目標(biāo)資源之間的相對位置關(guān)系

      • ./:當(dāng)前目錄
      • ../:后退一級目錄
  2. 絕對路徑:通過絕對路徑可以確定唯一資源
    • 如:http://localhost/responseDemo2 /responseDemo2
    • /開頭的路徑
    • 規(guī)則:判斷定義的路徑是給誰用的?判斷請求將來從哪兒發(fā)出
      • 給客戶端瀏覽器使用:需要加虛擬目錄(項目的訪問路徑)
        • 建議虛擬目錄動態(tài)獲?。?code>request.getContextPath()
        • <a> , <form> 重定向...
      • 給服務(wù)器使用:不需要加虛擬目錄
        • 轉(zhuǎn)發(fā)路徑

服務(wù)器輸出字符數(shù)據(jù)到瀏覽器

  • 步驟:

    1. 獲取字符輸出流
    2. 輸出數(shù)據(jù)
  • 亂碼問題:

    1. PrintWriter pw = response.getWriter();獲取的流的默認編碼是ISO-8859-1
    2. 設(shè)置該流的默認編碼
    3. 告訴瀏覽器響應(yīng)體使用的編碼
        //簡單的形式,設(shè)置編碼,是在獲取流之前設(shè)置
        response.setContentType("text/html;charset=utf-8");
    

ServletContext對象

概念

代表整個web應(yīng)用,可以和程序的容器(服務(wù)器)來通信

獲取

  1. 通過request對象獲取
    request.getServletContext();
  2. 通過HttpServlet獲取
    this.getServletContext();

功能

獲取MIME類型

  • MIME類型:在互聯(lián)網(wǎng)通信過程中定義的一種文件數(shù)據(jù)類型

    格式: 大類型/小類型 text/html image/jpeg

  • 獲?。?code>String getMimeType(String file)

域?qū)ο? 共享數(shù)據(jù)

  1. setAttribute(String name,Object value)
  2. getAttribute(String name)
  3. removeAttribute(String name)

ServletContext對象范圍:所有用戶所有請求的數(shù)據(jù)

獲取文件的真實(服務(wù)器)路徑

    String getRealPath(String path)  


    String b = context.getRealPath("/b.txt");//web目錄下資源訪問
    System.out.println(b);

    String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目錄下的資源訪問
    System.out.println(c);

    String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目錄下的資源訪問
    System.out.println(a);

文件下載

文件下載需求

  1. 頁面顯示超鏈接
  2. 點擊超鏈接后彈出下載提示框
  3. 完成圖片文件下載

分析

  1. 超鏈接指向的資源如果能夠被瀏覽器解析,則在瀏覽器中展示,如果不能解析,則彈出下載提示框。不滿足需求
  2. 任何資源都必須彈出下載提示框
  3. 使用響應(yīng)頭設(shè)置資源的打開方式
    • content-disposition:attachment;filename=xxx

步驟

  1. 定義頁面,編輯超鏈接href屬性,指向Servlet,傳遞資源名稱filename
  2. 定義Servlet
    1. 獲取文件名稱
    2. 使用字節(jié)輸入流加載文件進內(nèi)存
    3. 指定response的響應(yīng)頭: content-disposition:attachment;filename=xxx
    4. 將數(shù)據(jù)寫出到response輸出流

Cookie

保存在客戶端

  1. 創(chuàng)建Cookie對象,綁定數(shù)據(jù)
    new Cookie(String name, String value)
  2. 發(fā)送Cookie對象
    response.addCookie(Cookie cookie)
  3. 獲取Cookie,拿到數(shù)據(jù)
    Cookie[] request.getCookies()

cookie的細節(jié)

  1. 一次可不可以發(fā)送多個cookie?

    • 可以
    • 可以創(chuàng)建多個Cookie對象,使用response調(diào)用多次addCookie方法發(fā)送cookie即可。
  2. cookie在瀏覽器中保存多長時間?

    1. 默認情況下,當(dāng)瀏覽器關(guān)閉后,Cookie數(shù)據(jù)被銷毀
    2. 持久化存儲:
      • setMaxAge(int seconds)
        1. 正數(shù):將Cookie數(shù)據(jù)寫到硬盤的文件中。持久化存儲。并指定cookie存活時間,時間到后,cookie文件自動失效
        2. 負數(shù):默認值
        3. 零:刪除cookie信息
  3. cookie能不能存中文?

    • 在tomcat 8 之前 cookie中不能直接存儲中文數(shù)據(jù)。
      • 需要將中文數(shù)據(jù)轉(zhuǎn)碼---一般采用URL編碼(%E3)
    • 在tomcat 8 之后,cookie支持中文數(shù)據(jù)。特殊字符還是不支持,建議使用URL編碼存儲,URL解碼解析
  4. cookie共享問題?

    1. 假設(shè)在一個tomcat服務(wù)器中,部署了多個web項目,那么在這些web項目中cookie能不能共享?

      • 默認情況下cookie不能共享
      • setPath(String path):設(shè)置cookie的獲取范圍。默認情況下,設(shè)置當(dāng)前的虛擬目錄
        • 如果要共享,則可以將path設(shè)置為"/"
    2. 不同的tomcat服務(wù)器間cookie共享問題?

      • setDomain(String path):如果設(shè)置一級域名相同,那么多個服務(wù)器之間cookie可以共享
        • setDomain(".baidu.com"),那么tieba.baidu.comnews.baidu.com中cookie可以共享

Cookie的特點和作用

  1. cookie存儲數(shù)據(jù)在客戶端瀏覽器
  2. 瀏覽器對于單個cookie 的大小有限制(4kb) 以及 對同一個域名下的總cookie數(shù)量也有限制(20個)
  • 作用:
    1. cookie一般用于存出少量的不太敏感的數(shù)據(jù)
    2. 在不登錄的情況下,完成服務(wù)器對客戶端的身份識別

Session

依賴于Cookie, 保存在服務(wù)器端

  1. 獲取HttpSession對象:
    HttpSession session = request.getSession();
  2. 使用HttpSession對象:
        Object getAttribute(String name)  
        void setAttribute(String name, Object value)
        void removeAttribute(String name)  
    

細節(jié)

  1. 當(dāng)客戶端關(guān)閉后,服務(wù)器不關(guān)閉,兩次獲取session是否為同一個?

    • 默認情況下。不是。
    • 如果需要相同,則可以創(chuàng)建Cookie,鍵為JSESSIONID,設(shè)置最大存活時間,讓cookie持久化保存。
        Cookie c = new Cookie("JSESSIONID",session.getId());
        c.setMaxAge(60*60);
        response.addCookie(c);
    
  2. 客戶端不關(guān)閉,服務(wù)器關(guān)閉后,兩次獲取的session是同一個嗎?

    • 不是同一個,但是要確保數(shù)據(jù)不丟失。tomcat自動完成以下工作
      • session的鈍化: 在服務(wù)器正常關(guān)閉之前, 將session對象系列化到硬盤上
      • session的活化: 在服務(wù)器啟動后, 將session文件轉(zhuǎn)化為內(nèi)存中的session對象即可。
  3. session什么時候被銷毀?

    1. 服務(wù)器關(guān)閉
    2. session對象調(diào)用invalidate() 。
    3. session默認失效時間 30分鐘
      選擇性配置修改
          <session-config>
              <session-timeout>30</session-timeout>
          </session-config>
      
  4. session的特點

    1. session用于存儲一次會話的多次請求的數(shù)據(jù),存在服務(wù)器端
    2. session可以存儲任意類型,任意大小的數(shù)據(jù)

session與Cookie的區(qū)別

  1. session存儲數(shù)據(jù)在服務(wù)器端,Cookie在客戶端
  2. session沒有數(shù)據(jù)大小限制,Cookie有
  3. session數(shù)據(jù)安全,Cookie相對于不安全

JSP(Java Server Pages)

JSP本質(zhì)上就是一個Servlet

JSP的腳本: JSP定義Java代碼的方式

  1. <% 代碼 %>: 定義的java代碼,在service方法中。service方法中可以定義什么,該腳本中就可以定義什么。
  2. <%! 代碼 %>: 定義的java代碼,在jsp轉(zhuǎn)換后的java類的成員位置。
  3. <%= 代碼 %>: 定義的java代碼,會輸出到頁面上。輸出語句中可以定義什么,該腳本中就可以定義什么。

JSP的內(nèi)置對象

  • 在jsp頁面中不需要獲取和創(chuàng)建,可以直接使用的對象
  • jsp一共有9個內(nèi)置對象。
變量名 真實類型 作用
pageContext PageContext 當(dāng)前頁面共享數(shù)據(jù),還可以獲取其他八個內(nèi)置對象
request HttpServletRequest 一次請求訪問的多個資源(轉(zhuǎn)發(fā))
session HttpSession 一次會話的多個請求間
application ServletContext 所有用戶間共享數(shù)據(jù)
response HttpServletResponse 響應(yīng)對象
page Object 當(dāng)前頁面(Servlet)的對象,this
out JspWriter 輸出對象,數(shù)據(jù)輸出到頁面上
config ServletConfig Servlet的配置對象
exception Throwable 異常對象

response.getWriter()out.write()的區(qū)別:

  • 在tomcat服務(wù)器真正給客戶端做出響應(yīng)之前,會先找response緩沖區(qū)數(shù)據(jù),再找out緩沖區(qū)數(shù)據(jù)。
  • response.getWriter()數(shù)據(jù)輸出永遠在out.write()之前

El表達式

  1. 概念:Expression Language 表達式語言
  2. 作用:替換和簡化jsp頁面中java代碼的編寫
  3. 語法:${表達式}
  4. 注意:
    • jsp默認支持el表達式的。如果要忽略el表達式
      1. 設(shè)置jsp中page指令中:isELIgnored="true" 忽略當(dāng)前jsp頁面中所有的el表達式
      2. \${表達式} :忽略當(dāng)前這個el表達式

使用

運算符

  1. 算數(shù)運算符: + - * /(div) %(mod)
  2. 比較運算符: > < >= <= == !=
  3. 邏輯運算符: &&(and) ||(or) !(not)
  4. 空運算符: empty
    • 功能:用于判斷字符串、集合、數(shù)組對象是否為null或者長度是否為0
    • ${empty list}:判斷字符串、集合、數(shù)組對象是否為null或者長度為0
    • ${not empty str}:表示判斷字符串、集合、數(shù)組對象是否不為null 并且 長度>0

獲取值

  1. el表達式只能從域?qū)ο笾蝎@取值
  2. 語法:
    1. ${域名稱.鍵名}:從指定域中獲取指定鍵的值

      • 域名稱:
        1. pageScope --> pageContext
        2. requestScope --> request
        3. sessionScope --> session
        4. applicationScope --> application(ServletContext)
      • 舉例:在request域中存儲了name=張三
      • 獲?。?code>${requestScope.name}
    2. ${鍵名}:表示依次從最小的域中查找是否有該鍵對應(yīng)的值,直到找到為止。

    3. 獲取對象、List集合、Map集合的值

      1. 對象:${域名稱.鍵名.屬性名}

        • 本質(zhì)上會去調(diào)用對象的getter方法
      2. List集合:${域名稱.鍵名[索引]}

      3. Map集合:

        • ${域名稱.鍵名.key名稱}
        • ${域名稱.鍵名["key名稱"]}

隱式對象

  • el表達式中有11個隱式對象
  • pageContext
    • 獲取jsp其他八個內(nèi)置對象
      • ${pageContext.request.contextPath}:動態(tài)獲取虛擬目錄

JSTL

概念:JavaServer Pages Tag Library JSP標(biāo)準(zhǔn)標(biāo)簽庫

是由Apache組織提供的開源的免費的jsp標(biāo)簽 <標(biāo)簽>

作用:用于簡化和替換jsp頁面上的java代碼

使用步驟:

  1. 導(dǎo)入jstl相關(guān)jar包
  2. 引入標(biāo)簽庫:taglib指令: <%@ taglib %> 放在jsp頭部
  3. 使用標(biāo)簽

常用的JSTL標(biāo)簽

  1. if:相當(dāng)于java代碼的if語句

    1. 屬性:
      • test 必須屬性,接受boolean表達式
        • 如果表達式為true,則顯示if標(biāo)簽體內(nèi)容,如果為false,則不顯示標(biāo)簽體內(nèi)容
        • 一般情況下,test屬性值會結(jié)合el表達式一起使用
      1. 注意:
        • c:if標(biāo)簽沒有else情況,想要else情況,則可以在定義一個c:if標(biāo)簽
  2. choose:相當(dāng)于java代碼的switch語句

    1. 使用choose標(biāo)簽聲明 相當(dāng)于switch聲明
    2. 使用when標(biāo)簽做判斷 相當(dāng)于case
    3. 使用otherwise標(biāo)簽做其他情況的聲明 相當(dāng)于default
  3. foreach:相當(dāng)于java代碼的for語句

三層架構(gòu):軟件設(shè)計架構(gòu)

  1. 界面層(表示層):用戶看的得界面。用戶可以通過界面上的組件和服務(wù)器進行交互
  2. 業(yè)務(wù)邏輯層:處理業(yè)務(wù)邏輯的。
  3. 數(shù)據(jù)訪問層:操作數(shù)據(jù)存儲文件。

MVC
model: dao(data access object) 操作數(shù)據(jù)庫 包名xx.xx.dao
view: jsp 包名xx.xx.web, 接受用戶參數(shù), 封裝數(shù)據(jù)完成顯示
controller: service 包名xx.xx.service 業(yè)務(wù)邏輯操作

Filter: 過濾器

概念

  • 生活中的過濾器:凈水器,空氣凈化器,土匪、
  • web中的過濾器:當(dāng)訪問服務(wù)器的資源時,過濾器可以將請求攔截下來,完成一些特殊的功能。
  • 過濾器的作用:
    • 一般用于完成通用的操作。如:登錄驗證、統(tǒng)一編碼處理、敏感字符過濾...

快速入門

步驟

  1. 定義一個類,實現(xiàn)接口Filter
  2. 復(fù)寫方法
  3. 配置攔截路徑
    1. web.xml
    2. 注解

代碼

    @WebFilter("/*")//訪問所有資源之前,都會執(zhí)行該過濾器
    public class FilterDemo1 implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("filterDemo1被執(zhí)行了....");
    
            //放行
            filterChain.doFilter(servletRequest,servletResponse);
    
        }
    
        @Override
        public void destroy() {
    
        }
    }

過濾器細節(jié)

web.xml配置

    <filter>
        <filter-name>demo1</filter-name>
        <filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>demo1</filter-name>
        <!-- 攔截路徑 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

過濾器執(zhí)行流程

  1. 執(zhí)行過濾器
  2. 執(zhí)行放行后的資源
  3. 回來執(zhí)行過濾器放行代碼下邊的代碼

過濾器生命周期方法

  1. init:在服務(wù)器啟動后,會創(chuàng)建Filter對象,然后調(diào)用init方法。只執(zhí)行一次。用于加載資源
  2. doFilter:每一次請求被攔截資源時,會執(zhí)行。執(zhí)行多次
  3. destroy:在服務(wù)器關(guān)閉后, Filter對象被銷毀。如果服務(wù)器是正常關(guān)閉,則會執(zhí)行destroy方法。只執(zhí)行一次。用于釋放資源

過濾器配置詳解

  • 攔截路徑配置:

    1. 具體資源路徑: /index.jsp 只有訪問index.jsp資源時,過濾器才會被執(zhí)行
    2. 攔截目錄: /user/* 訪問/user下的所有資源時,過濾器都會被執(zhí)行
    3. 后綴名攔截: *.jsp 訪問所有后綴名為jsp資源時,過濾器都會被執(zhí)行
    4. 攔截所有資源:/* 訪問所有資源時,過濾器都會被執(zhí)行
  • 攔截方式配置:資源被訪問的方式

    • 注解配置:
      • 設(shè)置dispatcherTypes屬性
        1. REQUEST:默認值。瀏覽器直接請求資源
        2. FORWARD:轉(zhuǎn)發(fā)訪問資源
        3. INCLUDE:包含訪問資源
        4. ERROR:錯誤跳轉(zhuǎn)資源
        5. ASYNC:異步訪問資源
    • web.xml配置
      • 設(shè)置<dispatcher></dispatcher>標(biāo)簽即可

過濾器鏈(配置多個過濾器)

執(zhí)行順序:如果有兩個過濾器:過濾器1和過濾器2(入棧出棧)

  1. 過濾器1
  2. 過濾器2
  3. 資源執(zhí)行
  4. 過濾器2
  5. 過濾器1
  • 過濾器先后順序問題:
    1. 注解配置:按照類名的字符串比較規(guī)則比較,值小的先執(zhí)行
      • 如: AFilterBFilter, AFilter就先執(zhí)行了。
    2. web.xml配置: <filter-mapping>誰定義在上邊,誰先執(zhí)行

Listener:監(jiān)聽器

概念:web的三大組件之一。

  • 事件監(jiān)聽機制
    • 事件 :一件事情
    • 事件源 :事件發(fā)生的地方
    • 監(jiān)聽器 :一個對象
    • 注冊監(jiān)聽:將事件、事件源、監(jiān)聽器綁定在一起。 當(dāng)事件源上發(fā)生某個事件后,執(zhí)行監(jiān)聽器代碼

ServletContextListener:監(jiān)聽ServletContext對象的創(chuàng)建和銷毀

  • 方法:
    • void contextDestroyed(ServletContextEvent sce)ServletContext對象被銷毀之前會調(diào)用該方法
    • void contextInitialized(ServletContextEvent sce)ServletContext對象創(chuàng)建后會調(diào)用該方法
  • 步驟:
    1. 定義一個類,實現(xiàn)ServletContextListener接口
    2. 復(fù)寫方法
    3. 配置
      1. web.xml
          <listener>
              <listener-class>cn.web.listener.ContextLoaderListener</listener-class>
          </listener>
      
          * 指定初始化參數(shù)<context-param>
      
      1. 注解:
        • @WebListener
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容