天天看點

JavaWeb-過濾器過濾器Filter鍊Filter接口Filter映射編寫過濾器過濾器執行個體

過濾器

什麼是過濾器

過濾器(Filter):在Web伺服器與Web資源之間加一層過濾機制,現實的是

javax.servlet.Filter

接口,可以處理request與response,用來攔截垃圾請求、過濾字元編碼等。

過濾器的作用過程

  1. 使用者送出表單資訊,請求新的資源
  2. 請求進入到過濾器
  3. 過濾器進行過濾處理
  4. 處理完畢後将請求放行,請求到達Servlet
  5. Servlet處理完畢後,傳回response
  6. response回到過濾器,處理後放行
  7. 響應使用者新的資源

Filter鍊

在一個 Web 應用程式中可以注冊多個 Filter 程式,每個 Filter 程式都可以對一個或一組 Servlet 程式進行攔截。如果有多個 Filter 程式都可以對某個 Servlet 程式的通路過程進行攔截,當針對該 Servlet 的通路請求到達時,Web 容器将把這多個 Filter 程式組合成一個 Filter 鍊(也叫過濾器鍊)。

Filter 鍊中的各個 Filter 的攔截順序與它們在 web.xml 檔案中的映射順序一緻,上一個 Filter.doFilter 方法中調用 FilterChain.doFilter 方法将激活下一個 Filter的doFilter 方法,最後一個 Filter.doFilter 方法中調用的 FilterChain.doFilter 方法将激活目标 Servlet的service 方法。

隻要 Filter 鍊中任意一個 Filter 沒有調用 FilterChain.doFilter 方法,則目标 Servlet 的 service 方法都不會被執行。

引自:Filter、FilterChain、FilterConfig 介紹

Filter接口

當需要用到過濾器時需要實作Filter接口,并重寫裡面的三個抽象方法:

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException;

    default void destroy() {
    }
}
           

init

:

伺服器啟動時,進行初始化。伺服器執行個體化Filter對象,讀取web.xml中的相關配置資訊,調用該方法,完成對象的初始化加載。filterConfig中儲存了相關的配置資訊和運作環境資訊。

doFilter

當送出請求後,伺服器先調用該方法,完成過濾處理。

destroy

web伺服器關閉的時候自動調用該方法,過濾會銷毀,釋放資源

Filter映射

配置映射的方法與Servlet相同:

<filter>
    <filter-name>CharacterFilter</filter-name>
    <filter-class>Filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
           

注:這是一個處理亂碼的過濾器,可作用于所有請求與應答,則url-pattern中是所有内容。

編寫過濾器

過濾器說明:利用過濾器實作亂碼處理

public class CharacterFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterFilter初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=utf-8");

        System.out.println("過濾器執行前...");
        //自己調自己,讓程式繼續運作,如果不寫,程式到這裡停止。
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("過濾器執行後...");
    }

    @Override
    public void destroy() {
        System.out.println("CharacterFilter銷毀");
    }
}
           

過濾器執行個體

執行個體說明:實作Vip使用者登入,登入成功進入成功頁面,登入失敗進入失敗頁面,若使用者直接通路成功頁面則重定向到失敗頁面。

檔案:登入頁面、

LoginServlet.java

Success.jsp

VipFilter

(過濾器)、

LogoutServlet

(登出)、

ID.java

登入頁面

<form method="post" action="/LoginServlet">
  使用者名:<input type="text" name="name">
  <input type="submit" value="登入">
</form>
           

ID

将後面用到的session對象ID存在一個公共類中,友善修改。

public class ID {
    public final static String SessionID = "ID";
}
           

LoginServlet

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String name = request.getParameter("name");
    //判斷登入的使用者名是否為admin,即為VIP使用者
    if(name.equals("admin")){
        //擷取到Session的ID
        request.getSession().setAttribute(ID.SessionID,request.getSession().getId());
        response.sendRedirect("/Success/Success.jsp");
    }else {
        response.sendRedirect("Error.jsp");
    }
}
           

過濾器

該過濾器作用在成功頁面之前

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;

    //若擷取不到Session的ID,則證明不是由登入頁面将來的,重定向至失敗頁面。
    if(request.getSession().getAttribute(ID.SessionID) == null){
        response.sendRedirect("Error.jsp");
    }
    filterChain.doFilter(request, response);
}
           

過濾器配置

web.xml

檔案中給成功頁面配置該過濾器。

<filter>
    <filter-name>VipFilter</filter-name>
    <filter-class>Filter.VipFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>VipFilter</filter-name>
    <url-pattern>/Success/Success.jsp</url-pattern>
</filter-mapping>
           

Success.jsp

隻有登入成功才能進入到該頁面,當點選登出後跳轉到

LogoutServlet

<h1>成功頁面</h1>
<p><a href="/LogoutServlet" target="_blank" rel="external nofollow" >點我登出</a></p>
           

登出

當當使用者點選登出後,相當于登出,則

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Object ID = request.getSession().getAttribute(SessionID.ID.SessionID);
    //若擷取到的Session的ID不為空,則去除該Session對象,将頁面重定向至登入頁面
    if (ID != null){
        request.getSession().removeAttribute(SessionID.ID.SessionID);
        response.sendRedirect("Login.jsp");
    }
}
           

❤️ END ❤️