欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Servlet Filter過濾器執(zhí)行順序

 更新時間:2020年12月01日 14:23:26   作者:DayRain  
這篇文章主要介紹了Servlet Filter過濾器執(zhí)行順序的相關資料,幫助大家更好的理解為什么要用過濾器,感興趣的朋友可以了解下

Servlet中的過濾器相當于守護后臺資源的一道關卡,我們可以在過濾器中進行身份校驗、權限認證、請求過濾等。

過濾器本身并不難,我們只需要知道他的定義方法、作用范圍、執(zhí)行順序即可。

網(wǎng)上對于過濾器執(zhí)行順序的描述可能會讓人產(chǎn)生誤解。

圖片來源于網(wǎng)絡

客戶端請求到達的時候,經(jīng)過一次過濾器。

服務器處理完請求的時候,經(jīng)過一次過濾器。

雖然經(jīng)過兩次過濾器,但不代表同樣的代碼執(zhí)行了兩次。

下面做了個簡單的測試,看下執(zhí)行結果就應該知道真正的執(zhí)行流程了。

測試環(huán)境

tomcat9(servlet4.0)

jdk1.8

新版servlet可以通過注解注冊servlet組件以及過濾器,無需再到web.xml下注冊了。

測試過程

測試之間要先知道filterChain(過濾鏈)是干嘛的。

一個過濾器處理完后,會把request和response對象通過filterchain傳遞給下一個過濾器,如果沒有下一個過濾器,則會直接開始執(zhí)行業(yè)務代碼,

單個過濾器

定義一個過濾器A

@WebFilter(value = "/*", filterName="A")
public class FilterA implements Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(format.format(new Date()));
    System.out.println("A:攔截1");
    chain.doFilter(request, response);
    System.out.println(format.format(new Date()));
    System.out.println("A:攔截2");
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void destroy() {

  }

}

定義一個servlet,sleep5秒

@WebServlet("/mainUrl")
public class MainController extends HttpServlet {
  private static final long serialVersionUID = 1L;
    
  /**
   * @see HttpServlet#HttpServlet()
   */
  public MainController() {
    super();
    // TODO Auto-generated constructor stub
  }

  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }

}

運行結果

2020-12-01 10:46:50
A:攔截1
2020-12-01 10:46:55
A:攔截2

執(zhí)行順序:

filterChain之前的代碼 ——>業(yè)務處理——>filterChain之后的代碼。

多個過濾器

servlet的注解在多個過濾器的情況下,是按照過濾器的名稱來排序的,例如A開頭的過濾器,在B開頭的后面。

A過濾器

@WebFilter(value = "/*", filterName="A")
public class FilterA implements Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(format.format(new Date()));
    System.out.println("A:攔截1");
    chain.doFilter(request, response);
    System.out.println(format.format(new Date()));
    System.out.println("A:攔截2");
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void destroy() {

  }

}

B過濾器

@WebFilter(value = "/*", filterName="B")
public class FilterB implements Filter{

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    // TODO Auto-generated method stub
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(format.format(new Date()));
    System.out.println("B:攔截1");
    chain.doFilter(request, response);
    System.out.println(format.format(new Date()));
    response.setContentType("normal content");
    System.out.println("B:攔截2");
    
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void destroy() {

  }
}

運行結果:

2020-12-01 10:53:00
A:攔截1
2020-12-01 10:53:00
B:攔截1
2020-12-01 10:53:05
B:攔截2
2020-12-01 10:53:05
A:攔截2

執(zhí)行順序:

B:攔截1和B:攔截2之間,停頓了5秒處理業(yè)務。所以先執(zhí)行了  chain.doFilter前的 A、B過濾器代碼,處理完業(yè)務返回的時候正好相反,先返回執(zhí)行B的代碼,再執(zhí)行的A的代碼。

總結

再來看這個圖,可以略微改一下了。

 分界線是filterChain過濾鏈,請求進來的時候,執(zhí)行filterchain之前的代碼,返回response的時候,執(zhí)行filterchain之后的代碼。

多個過濾器之間的執(zhí)行順序,滿足“先進后出” (棧結構)的原則。

其他

如果在測試過程中,發(fā)現(xiàn)過濾器執(zhí)行了很多次,那么也可能是因為測試環(huán)境中包含了某些靜態(tài)資源。

過濾器A

@WebFilter(value = "/*", filterName="A")
public class FilterA implements Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(format.format(new Date()));
    System.out.println("A:攔截1");
    chain.doFilter(request, response);
    System.out.println(format.format(new Date()));
    System.out.println("A:攔截2");
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void destroy() {

  }

}

過濾器B

@WebFilter(value = "/*", filterName="B")
public class FilterB implements Filter{

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    // TODO Auto-generated method stub
    HttpServletRequest req = (HttpServletRequest) request;
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(req.getRequestURL());
    System.out.println(format.format(new Date()));
    System.out.println("B:攔截1");
    chain.doFilter(request, response);
    System.out.println(format.format(new Date()));
    response.setContentType("normal content");
    System.out.println("B:攔截2");
    
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void destroy() {

  }
}

主程序

@WebServlet("/mainUrl")
public class MainController extends HttpServlet {
  private static final long serialVersionUID = 1L;
    
  /**
   * @see HttpServlet#HttpServlet()
   */
  public MainController() {
    super();
    // TODO Auto-generated constructor stub
  }

  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    request.getRequestDispatcher("/WEB-INF/pages/main.jsp").forward(request, response);
//    response.sendRedirect("/WEB-INF/pages/main.jsp");
  }

  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }

}

執(zhí)行結果:

2020-12-01 11:09:38
A:攔截1
http://localhost:8080/StudentManage/mainUrl
2020-12-01 11:09:38
B:攔截1
2020-12-01 11:09:43
B:攔截2
2020-12-01 11:09:43
A:攔截2
2020-12-01 11:09:44
A:攔截1
http://localhost:8080/StudentManage/css/bootstrap.css.map
2020-12-01 11:09:44
B:攔截1
2020-12-01 11:09:44
B:攔截2
2020-12-01 11:09:44
A:攔截2

轉發(fā)(forward)的頁面中需要請求靜態(tài)資源,再次觸發(fā)了過濾器。

以上就是Servlet Filter過濾器執(zhí)行順序的詳細內容,更多關于Servlet Filter過濾器的資料請關注腳本之家其它相關文章!

相關文章

  • 解析Spring Mvc Long類型精度丟失問題

    解析Spring Mvc Long類型精度丟失問題

    在平時開發(fā)過程中,經(jīng)常會使用long類型作為id的類型,但是在使用過程中會導致long類型數(shù)據(jù)轉換為number類型時的后兩位變?yōu)?,今天小編給大家分享Spring Mvc Long類型精度丟失問題,需要的朋友參考下吧
    2021-06-06
  • 詳解如何通過Java實現(xiàn)類似Nginx代理

    詳解如何通過Java實現(xiàn)類似Nginx代理

    最近遇到一個問題,在內網(wǎng)環(huán)境中部署的項目需要調用外網(wǎng)完成一些應用,一般情況我們可以通過增加一臺機器,部署到可以訪問外網(wǎng)的服務器上,然后內網(wǎng)直接連接該機器通過Nginx進行代理即可,所以本文介紹了如何通過Java實現(xiàn)類似Nginx代理,需要的朋友可以參考下
    2024-08-08
  • Spring Boot 中的 @PutMapping 注解原理及使用小結

    Spring Boot 中的 @PutMapping 注解原理及使用小結

    在本文中,我們介紹了 Spring Boot 中的 @PutMapping 注解,它可以將 HTTP PUT 請求映射到指定的處理方法上,我們還介紹了 @PutMapping 注解的原理以及如何在 Spring Boot 中使用它,感興趣的朋友跟隨小編一起看看吧
    2023-12-12
  • JavaWeb實現(xiàn)用戶登錄與注冊功能

    JavaWeb實現(xiàn)用戶登錄與注冊功能

    這篇文章主要為大家詳細介紹了JavaWeb實現(xiàn)用戶登錄與注冊功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Java中三種簡單注解介紹和代碼實例

    Java中三種簡單注解介紹和代碼實例

    這篇文章主要介紹了Java中三種簡單注解介紹和代碼實例,本文講解了Override注解、Deprecated注解、Suppresswarnings注解、元注解等內容,需要的朋友可以參考下
    2014-09-09
  • Java Socket+mysql實現(xiàn)簡易文件上傳器的代碼

    Java Socket+mysql實現(xiàn)簡易文件上傳器的代碼

    最近在做一個小項目,項目主要需求是實現(xiàn)一個文件上傳器,通過客戶端的登陸,把本地文件上傳到服務器的數(shù)據(jù)庫(本地的)。下面通過本文給大家分享下實現(xiàn)代碼,感興趣的朋友一起看看吧
    2016-10-10
  • java解析任意層數(shù)json字符串的方法

    java解析任意層數(shù)json字符串的方法

    一個方法解析任意層數(shù)的json字符竄:使用正則表達式,遞歸算法,將jsonArray解析出后添加到List, JsonObject添加至Map
    2014-02-02
  • Eclipse+Java+Swing實現(xiàn)圖書管理系統(tǒng)(詳細代碼)

    Eclipse+Java+Swing實現(xiàn)圖書管理系統(tǒng)(詳細代碼)

    這篇文章主要介紹了Eclipse+Java+Swing實現(xiàn)圖書管理系統(tǒng)并附上詳細代碼,需要的小伙伴可以參考一下,希望對你有所幫助
    2022-01-01
  • Spring Security動態(tài)權限的實現(xiàn)方法詳解

    Spring Security動態(tài)權限的實現(xiàn)方法詳解

    這篇文章主要和小伙伴們簡單介紹下 Spring Security 中的動態(tài)權限方案,以便于小伙伴們更好的理解 TienChin 項目中的權限方案,感興趣的可以了解一下
    2022-06-06
  • Java ScheduledExecutorService的具體使用

    Java ScheduledExecutorService的具體使用

    ScheduledExecutorService有線程池的特性,也可以實現(xiàn)任務循環(huán)執(zhí)行,本文主要介紹了Java ScheduledExecutorService的具體使用,具有一定的參考價值,感興趣的可以了解一下
    2023-05-05

最新評論