最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

Servlet中的過(guò)濾器相當(dāng)于守護(hù)后臺(tái)資源的一道關(guān)卡,我們可以在過(guò)濾器中進(jìn)行身份校驗(yàn)、權(quán)限認(rèn)證、請(qǐng)求過(guò)濾等。

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

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

圖片來(lái)源于網(wǎng)絡(luò)

客戶端請(qǐng)求到達(dá)的時(shí)候,經(jīng)過(guò)一次過(guò)濾器。

服務(wù)器處理完請(qǐng)求的時(shí)候,經(jīng)過(guò)一次過(guò)濾器。

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

下面做了個(gè)簡(jiǎn)單的測(cè)試,看下執(zhí)行結(jié)果就應(yīng)該知道真正的執(zhí)行流程了。

測(cè)試環(huán)境

tomcat9(servlet4.0)

jdk1.8

新版servlet可以通過(guò)注解注冊(cè)servlet組件以及過(guò)濾器,無(wú)需再到web.xml下注冊(cè)了。

測(cè)試過(guò)程

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

一個(gè)過(guò)濾器處理完后,會(huì)把request和response對(duì)象通過(guò)filterchain傳遞給下一個(gè)過(guò)濾器,如果沒(méi)有下一個(gè)過(guò)濾器,則會(huì)直接開(kāi)始執(zhí)行業(yè)務(wù)代碼,

單個(gè)過(guò)濾器

定義一個(gè)過(guò)濾器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() {

  }

}

定義一個(gè)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);
  }

}

運(yùn)行結(jié)果

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

執(zhí)行順序:

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

多個(gè)過(guò)濾器

servlet的注解在多個(gè)過(guò)濾器的情況下,是按照過(guò)濾器的名稱來(lái)排序的,例如A開(kāi)頭的過(guò)濾器,在B開(kāi)頭的后面。

A過(guò)濾器

@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過(guò)濾器

@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() {

  }
}

運(yùn)行結(jié)果:

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è)務(wù)。所以先執(zhí)行了  chain.doFilter前的 A、B過(guò)濾器代碼,處理完業(yè)務(wù)返回的時(shí)候正好相反,先返回執(zhí)行B的代碼,再執(zhí)行的A的代碼。

總結(jié)

再來(lái)看這個(gè)圖,可以略微改一下了。

 分界線是filterChain過(guò)濾鏈,請(qǐng)求進(jìn)來(lái)的時(shí)候,執(zhí)行filterchain之前的代碼,返回response的時(shí)候,執(zhí)行filterchain之后的代碼。

多個(gè)過(guò)濾器之間的執(zhí)行順序,滿足“先進(jìn)后出” (棧結(jié)構(gòu))的原則。

其他

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

過(guò)濾器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() {

  }

}

過(guò)濾器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í)行結(jié)果:

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

轉(zhuǎn)發(fā)(forward)的頁(yè)面中需要請(qǐng)求靜態(tài)資源,再次觸發(fā)了過(guò)濾器。

以上就是Servlet Filter過(guò)濾器執(zhí)行順序的詳細(xì)內(nèi)容,更多關(guān)于Servlet Filter過(guò)濾器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springmvc path請(qǐng)求映射到bean 方法的流程

    springmvc path請(qǐng)求映射到bean 方法的流程

    這篇文章主要介紹了springmvc path請(qǐng)求映射到bean 方法的流程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • 使用IDEA創(chuàng)建SpringBoot項(xiàng)目的方法步驟

    使用IDEA創(chuàng)建SpringBoot項(xiàng)目的方法步驟

    這篇文章主要介紹了使用IDEA創(chuàng)建SpringBoot項(xiàng)目的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • Java實(shí)現(xiàn)簡(jiǎn)單文件過(guò)濾器功能

    Java實(shí)現(xiàn)簡(jiǎn)單文件過(guò)濾器功能

    下面小編就為大家分享一篇Java實(shí)現(xiàn)簡(jiǎn)單文件過(guò)濾器功能,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • Springboot讀取templates文件html代碼實(shí)例

    Springboot讀取templates文件html代碼實(shí)例

    這篇文章主要介紹了Springboot讀取templates文件html代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java8中字符串處理庫(kù)strman-java的使用示例

    Java8中字符串處理庫(kù)strman-java的使用示例

    除了Java本身的字符串處理方式外,我們還可以使用Apache Common Langs里的StringUtils來(lái)簡(jiǎn)化String的操作。但以上兩種方式對(duì)于我們?nèi)粘>幊讨凶钊菀着龅降淖址幚韥?lái)說(shuō),仍然顯得有些不足。所以這篇文章給大家介紹Java8中字符串處理庫(kù)strman-java的使用。
    2016-09-09
  • 在SpringBoot中實(shí)現(xiàn)線程池并行處理任務(wù)的方法詳解

    在SpringBoot中實(shí)現(xiàn)線程池并行處理任務(wù)的方法詳解

    在使用Spring Boot開(kāi)發(fā)應(yīng)用程序時(shí),我們經(jīng)常需要處理一些耗時(shí)的任務(wù),例如網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫(kù)操作或者其他需要花費(fèi)一定時(shí)間的計(jì)算任務(wù),本文將介紹如何在Spring Boot中使用線程池來(lái)實(shí)現(xiàn)任務(wù)的并行處理
    2023-06-06
  • IDEA中的JFormDesigner使用小結(jié)

    IDEA中的JFormDesigner使用小結(jié)

    JFormDesigner是一款用于設(shè)計(jì)和創(chuàng)建圖形用戶界面的插件,本文主要介紹了IDEA中的JFormDesigner使用小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • java實(shí)現(xiàn)登錄案例

    java實(shí)現(xiàn)登錄案例

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)登錄案例的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • java開(kāi)發(fā)ShardingSphere的路由引擎類型示例詳解

    java開(kāi)發(fā)ShardingSphere的路由引擎類型示例詳解

    這篇文章主要為大家介紹了java開(kāi)發(fā)ShardingSphere的路由引擎類型示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • java反射獲取一個(gè)object屬性值代碼解析

    java反射獲取一個(gè)object屬性值代碼解析

    這篇文章主要介紹了java反射獲取一個(gè)object屬性值代碼解析,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12

最新評(píng)論

松滋市| 兰坪| 黎城县| 深州市| 承德县| 永仁县| 德格县| 科尔| 四平市| 色达县| 互助| 湛江市| 东海县| 永春县| 黄冈市| 宁晋县| 双鸭山市| 阳西县| 东丽区| 三门县| 扎兰屯市| 神木县| 汾阳市| 乾安县| 安阳市| 建平县| 车致| 岑溪市| 文山县| 上杭县| 遵化市| 益阳市| 五莲县| 邳州市| 临沧市| 京山县| 华池县| 昆明市| 交口县| 如东县| 石屏县|