1. 程式人生 > >Java Web筆記 – Servlet中的Filter過濾器的介紹和使用 編寫過濾器

Java Web筆記 – Servlet中的Filter過濾器的介紹和使用 編寫過濾器

1、過濾器介紹:

在Servlet規範2.3中定義了過濾器,它能夠對Servlet容器的請求和響應物件進行檢查和修改。

Servlet過濾器本身並不生成請求和響應物件,只是提供過濾功能。

Servlet過濾器能夠在Servlet被呼叫之前檢查Request物件,並修改Request Header和Request內容;

Servlet被呼叫之後檢查Response物件,修改Response Header和Response的內容。

Servlet過濾器可以過濾的Web元件包括Servlet,JSP和HTML等檔案。

Filter類似於IO中的過濾流,實現也類似於Servlet。

2、Filter介面:

所有的Servlet過濾器都必須實現javax.servlet.Filter介面,並實現該介面中的三個方法:

init(FilterConfig filterConfig)

Servlet過濾器的初始化方法,Servlet容器建立Servlet過濾器例項後將呼叫該方法。該方法將讀取web.xml檔案中Servlet過濾器的初始化引數。

doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

該方法完成實際的過濾操作,當客戶端請求方法與過濾器設定匹配的URL時,Servlet容器將先呼叫過濾器的doFilter方法。FilterChain使用者訪問後續過濾器。

這裡的ServletRequest和ServletResponse一般需要轉換成具體的Servlet實現對於的物件

,如:HttpServletRequest和HttpServletResponse。

destroy()

Servlet容器在銷燬過濾器例項前呼叫該方法,在該方法中釋放Servlet過濾器佔用的資源。

public interface Filter
A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both. 

Filters perform filtering in the doFilter method. Every Filter has access to a FilterConfig object from which it can obtain its initialization parameters
, a reference to the ServletContext which it can use, for example, to load resources needed for filtering tasks.
Filters are configured in the deployment descriptor of a web application
Examples that have been identified for this design are
1) Authentication Filters
2) Logging and Auditing Filters
3) Image conversion Filters
4) Data compression Filters
5) Encryption Filters
6) Tokenizing Filters
7) Filters that trigger resource access events
8) XSL/T filters
9) Mime-type chain Filter
public interface FilterChain
A FilterChain is an object provided by the servlet container to the developer giving a view into the invocation chain of a filtered request for a resource. Filters use the FilterChain to invoke the next filter in the chain, or if the calling filter is the last filter in the chain, to invoke the resource at the end of the chain.
2.1、FilterConfig的使用:

Filter的init方法中提供了一個FilterConfig物件,提供相關的操作:

如獲取Filter中配置的初始化引數:
<filter>
      <filter-name>LoginFilter</filter-name>
      <filter-class>com.itzhai.login.LoginFilter</filter-class>
      <init-param>
          <param-name>username</param-name>
          <param-value>arthinking</param-value>
      </init-param>
  </filter>

在init方法中獲取:

@Override
public void init(FilterConfig filterConfig) throws ServletException {
    //獲取Filter初始化引數
    String username = filterConfig.getInitParameter("username");
}
2.2、在Filter中訪問application:
ServletContext context = filterConfig.getServletContext();

也可以在doFilter方法中根據轉換好的request獲取:

HttpServletRequest req = (HttpServletRequest)request;
ServletContext context = req.getSession().getServletContext();
3、一個簡單過濾器的實現:

編寫Filter過濾器:

public class LoginFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init LoginFilter");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        //把ServletRequest和ServletResponse轉換成真正的型別
        HttpServletRequest req = (HttpServletRequest)request;
        HttpSession session = req.getSession();

        //由於web.xml中設定Filter過濾全部請求,可以排除不需要過濾的url
        String requestURI = req.getRequestURI();
        if(requestURI.endsWith("login.jsp")){
            chain.doFilter(request, response);
            return;
        }

        //判斷使用者是否登入,進行頁面的處理
        if(null == session.getAttribute("user")){
            //未登入使用者,重定向到登入頁面
            ((HttpServletResponse)response).sendRedirect("login.jsp");
            return;
        } else {
            //已登入使用者,允許訪問
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        System.out.println("destroy!!!");
    }
}

在web.xml中配置Filter:

<filter>
      <filter-name>LoginFilter</filter-name>
      <filter-class>com.itzhai.login.LoginFilter</filter-class>
  </filter>

  <filter-mapping>
      <filter-name>LoginFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

注意:一般Filter配置在所有的Servlet之前。

4、過濾敏感詞彙的Filter簡單實現:
@Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        //轉換成例項的請求和響應物件
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse)response;
        //獲取評論並遮蔽關鍵字
        String comment = req.getParameter("comment");
        comment = comment.replace("A", "***");
        //重新設定引數
        req.setAttribute("comment", comment);
        //繼續執行
        chain.doFilter(request, response);
    }
5、Filter的執行順序

Filter的執行順序與在web.xml配置檔案中的配置順序一致,一般把Filter配置在所有的Servlet之前。