Web 服務器過濾器

開放

過濾器介紹

但這還不是全部。您真的不認為 servlet 有那麼簡單,是嗎?

除了我們已經分析過的 servlet 之外,還有所謂的“實用 servlet”——過濾器。它們與 servlet 非常相似,但它們的主要工作是幫助 servlet 處理請求。

過濾器就像秘書,而 servlet 就像導演。在文件到達主任辦公桌之前,它會通過秘書的手。主管簽字後,它會再次交給秘書,例如,已經作為外發信件。

這樣的秘書可以拒絕對主管的某些請求(例如,垃圾郵件)。或者對他已知的問題給出標準答案(“導演不在位”)。等等。而且,可以有多個這樣的秘書:一個可以一次性為所有董事過濾垃圾郵件,另一個可以在不同董事之間傳遞請求,等等。

過濾器的工作方式相同。

實用程序 servlet”

類 Filter、FilterChain、FilterConfig

過濾器與 servlet 非常相似,但有一些細微差別。要編寫自己的過濾器,您需要繼承自javax.servlet.Filter.

過濾器也有方法init()destroy()service()過濾器沒有方法,而是有一個doFilter(). 甚至有自己的類 FilterConfig。過濾器也被添加到 web.xml 文件中的 servlet 或通過 @WebFilter 註釋。

方法列表:

方法 描述
1個 init(FilterConfig config) 過濾器初始化
2個 destroy() 過濾卸料
3個 doFilter(ServletRequest , ServletResponse, FilterChain) 請求處理(過濾)

servlet 和過濾器有什麼區別?

可以有多個過濾器,它們按順序處理請求(和響應)。它們被組合成一個所謂的鏈 - 甚至有一個特殊的類FilterChain

在方法中處理完請求後,doFilter()需要調用doFilter()鏈中下一個過濾器的方法。例子:

public class MyFilter implements Filter {

  public void init(FilterConfig arg0) throws ServletException {
  }

  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws Exception {

      PrintWriter out = resp.getWriter();
      out.print("Adding something before the body of the response");

      chain.doFilter(req, resp); // call the next filter in the chain

      out.print("Adding something after the body of the response");
    }

  public void destroy() {
  }
}

實際上,您不能那樣添加響應主體。形式上,過濾器和 servlet 是相互獨立的,可以獨立更改。它們可以由不同的開發人員在不同的時間編寫。過濾器功能只是一個服務功能,例如:

  • 記錄所有傳入的請求(和響應)
  • 數據壓縮
  • 數據的加密(和解密)
  • 請求數據驗證
  • 添加/刪除所需的標題
  • 重定向請求
  • 訪問控制(檢查用戶是否登錄)

RequestDispatcher類

doFilter() 有時可能需要在方法中運行過濾器時調用另一個 servlet 。為此,容器有一個特殊的對象RequestDispatcher

您可以通過兩種方式獲得它:

  • 在對象HttpServletRequest
  • 在對象ServletContext

該對象可用於將現有請求重定向到另一個 servlet。例如,原來用戶沒有被授權,我們想給他看一個有授權的頁面。好吧,或者服務器出現錯誤,我們想向用戶顯示一個錯誤頁面:)

public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)  throws Exception {
           String path = "/error.html";
           ServletContext servletContext = this.getServletContext();
           RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path);
           requestDispatcher.forward(request, response);
    }
}

您也可以RequestDispatcher從過濾器調用。

public class MyFilter implements Filter {

  public void init(FilterConfig arg0) throws ServletException {
  }

  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws Exception {
           String path = "/error.html";
           ServletContext servletContext = req.getServletContext();
           RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path);
           requestDispatcher.forward(req, resp);
    }

  public void destroy() {
  }
}

注意請求會在方法中處理,使用後forward()不需要再調用。doFilter()RequestDispatcher

重定向和轉發的比較

還有一點很重要。如果你想將用戶重定向到你的 servlet 中的另一個 URI,那麼你可以通過兩種方式做到這一點:

  • redirect
  • forward

我們已經對它們進行了分析,但是為了方便我再說一遍。

當您通過調用重定向response.sendRedirect("link")時,服務器會向瀏覽器(客戶端)發迴響應302和您指定的鏈接。瀏覽器在分析服務器響應後,會下載您傳遞的鏈接。即,瀏覽器中的鏈接更改為新鏈接。

如果您通過 call轉發requestDispatcher.forward(),則會在容器內發出一個新請求,並且您的 servlet 會將其響應發送給瀏覽器(客戶端)作為您的 servlet 的響應。在這種情況下,瀏覽器收到來自新 servlet 的響應,但瀏覽器中的鏈接沒有改變。

留言
  • 受歡迎
你必須登入才能留言
此頁面尚無留言