JSP フィルタ

JSP と Servlet のフィルタはどちらも Java クラスです。

フィルタはリクエストとレスポンスを動的にインターセプトし、リクエストまたはレスポンスに含まれる情報を変換または使用できます。

1つまたは複数のフィルタを1つの Servlet または一連の Servlet にアタッチできます。フィルタは JavaServer Pages (JSP) ファイルや HTML ページにもアタッチできます。

フィルタは Servlet プログラミングで使用できる Java クラスであり、次の目的を達成できます:

  • クライアントのリクエストがバックエンドリソースにアクセスする前に、それらのリクエストをインターセプトします。
  • サーバーのレスポンスがクライアントに送り返される前に、それらのレスポンスを処理します。

仕様で推奨されるさまざまなタイプのフィルタ:

  • 認証フィルタ(Authentication Filters)。
  • データ圧縮フィルタ(Data compression Filters)。
  • 暗号化フィルタ(Encryption Filters)。
  • リソースアクセスイベントをトリガーするフィルタ。
  • 画像変換フィルタ(Image Conversion Filters)。
  • ロギングおよび監査フィルタ(Logging and Auditing Filters)。
  • MIME-TYPE チェーンフィルタ(MIME-TYPE Chain Filters)。
  • トークン化フィルタ(Tokenizing Filters)。
  • XSL/T フィルタ(XSL/T Filters)。XML コンテンツを変換します。

フィルタは Web デプロイメント記述子(web.xml)内の XML タグで宣言され、アプリケーションのデプロイメント記述子内の Servlet 名または URL パターンにマッピングされます。

Web コンテナが Web アプリケーションを起動すると、デプロイメント記述子で宣言した各フィルタのインスタンスを作成します。

Filter の実行順序は web.xml 設定ファイルでの設定順序と一致します。通常、Filter はすべての Servlet の前に設定します。

Servlet フィルタのメソッド

フィルタは javax.servlet.Filter インターフェースを実装した Java クラスです。javax.servlet.Filter インターフェースは3つのメソッドを定義しています:

番号メソッド & 説明
1public void doFilter (ServletRequest, ServletResponse, FilterChain)
このメソッドは実際のフィルタ操作を実行します。クライアントのリクエストがフィルタで設定された URL と一致する場合、Servlet コンテナは最初にフィルタの doFilter メソッドを呼び出します。FilterChain は後続のフィルタにアクセスするために使用されます。
2public void init(FilterConfig filterConfig)
Web アプリケーションの起動時に、Web サーバーは Filter のインスタンスオブジェクトを作成し、その init メソッドを呼び出して web.xml の設定を読み取り、オブジェクトの初期化機能を完了することで、その後のユーザーリクエストに対するインターセプトの準備を整えます(filter オブジェクトは一度だけ作成され、init メソッドも一度だけ実行されます)。開発者は init メソッドのパラメータを介して、現在のフィルタ設定情報を表す FilterConfig オブジェクトを取得できます。
3public void destroy()
Servlet コンテナはフィルタインスタンスを破棄する前にこのメソッドを呼び出し、このメソッド内で Servlet フィルタが占有していたリソースを解放します。

FilterConfig の使用

Filter の init メソッドには FilterConfig オブジェクトが提供されます。

web.xml ファイルの設定が次のようになっている場合:

<filter>
    <filter-name>LogFilter</filter-name>
    <filter-class>com.サンプル.test.LogFilter</filter-class>
    <init-param>
        <param-name>Site</param-name>
        <param-value>サンプル</param-value>
    </init-param>
    </filter>

init メソッドで FilterConfig オブジェクトを使用してパラメータを取得します:

public void  init(FilterConfig config) throws ServletException {
    // 获取初始化参数
    String site = config.getInitParameter("Site"); 
    // 输出初始化参数
    System.out.println("网站名称: " + site); 
}

JSP フィルタの例

以下は Servlet フィルタの例で、Web サイトの名前とアドレスを出力します。この例で Servlet フィルタの基本的な理解が得られます。同じ概念を使用して、より複雑なフィルタアプリケーションを作成できます:

//导入必需的 java 库
import javax.servlet.*;
import java.util.*;

//实现 Filter 类
public class LogFilter implements Filter  {
    public void  init(FilterConfig config) throws ServletException {
        // 获取初始化参数
        String site = config.getInitParameter("Site"); 

        // 输出初始化参数
        System.out.println("网站名称: " + site); 
    }
    public void  doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {

        // 输出站点名称
        System.out.println("站点网址:http://www.example.com");

        // 把请求传回过滤链
        chain.doFilter(request,response);
    }
    public void destroy( ){
        /* 在 Filter 实例被 Web 容器从服务移除之前调用 */
    }
}

DisplayHeader.java ファイルのコードは次のとおりです:

//导入必需的 java 库
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/DisplayHeader")

//扩展 HttpServlet 类
public class DisplayHeader extends HttpServlet {

    // 处理 GET 方法请求的方法
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        // 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");

        PrintWriter out = response.getWriter();
        String title = "HTTP Header 请求实例 - サンプル实例";
        String docType =
            "<!DOCTYPE html> \n";
            out.println(docType +
            "<html>\n" +
            "<head><meta charset=\"utf-8\"><title>" + title + "</title></head>\n"+
            "<body bgcolor=\"#F0F0F0\">\n" +
            "<h1 align=\"center\">" + title + "</h1>\n" +
            "<table width=\"100%\" border=\"1\" align=\"center\">\n" +
            "<tr bgcolor=\"#949494\">\n" +
            "<th>Header 名称</th><th>Header 值</th>\n"+
            "</tr>\n");

        Enumeration headerNames = request.getHeaderNames();

        while(headerNames.hasMoreElements()) {
            String paramName = (String)headerNames.nextElement();
            out.print("<tr><td>" + paramName + "</td>\n");
            String paramValue = request.getHeader(paramName);
            out.println("<td> " + paramValue + "</td></tr>\n");
        }
        out.println("</table>\n</body></html>");
    }
    // 处理 POST 方法请求的方法
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

Web.xml での Servlet フィルタマッピング(Servlet Filter Mapping)

フィルタを定義してから URL または Servlet にマッピングすることは、Servlet を定義してから URL パターンにマッピングすることとほぼ同じです。デプロイメント記述子ファイルweb.xml内の filter タグに次のエントリを作成します:

<?xml version="1.0" encoding="UTF-8"?>  
<web-app>  
<filter>
  <filter-name>LogFilter</filter-name>
  <filter-class>com.サンプル.test.LogFilter</filter-class>
  <init-param>
    <param-name>Site</param-name>
    <param-value>サンプル</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>LogFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>  
  <!-- 类名 -->  
  <servlet-name>DisplayHeader</servlet-name>  
  <!-- 所在的包 -->  
  <servlet-class>com.サンプル.test.DisplayHeader</servlet-class>  
</servlet>  
<servlet-mapping>  
  <servlet-name>DisplayHeader</servlet-name>  
  <!-- 访问的网址 -->  
  <url-pattern>/TomcatTest/DisplayHeader</url-pattern>  
</servlet-mapping>  
</web-app>  

上記のフィルタはすべての Servlet に適用されます。設定で指定したためです。/*一部の Servlet にのみフィルタを適用したい場合は、特定の Servlet パスを指定できます。

ここで、通常の方法で任意の Servlet を呼び出してみてください。Web サーバー内で生成されたログが表示されます。また、Log4J ロガーを使用して、上記のログを別のファイルに記録することもできます。

次に、この例のアドレスにアクセスしますhttp://localhost:8080/TomcatTest/DisplayHeaderその後コンソールで出力内容を確認します。次のようになります:

複数のフィルタを使用する

Web アプリケーションは、特定の目的に応じて複数の異なるフィルタを定義できます。2つのフィルタを定義したとします。AuthenFilterとLogFilter次に説明するように異なるマッピングを作成する必要があります。その他の処理は前述の説明とほぼ同じです:

<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>com.サンプル.test.LogFilter</filter-class>
   <init-param>
      <param-name>test-param</param-name>
      <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>

<filter>
   <filter-name>AuthenFilter</filter-name>
   <filter-class>com.サンプル.test.AuthenFilter</filter-class>
   <init-param>
      <param-name>test-param</param-name>
      <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>

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

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

フィルタの適用順序

web.xml 内の filter-mapping 要素の順序によって、Web コンテナがフィルタを Servlet に適用する順序が決まります。フィルタの順序を逆にするには、web.xml ファイル内で filter-mapping 要素を逆にするだけです。

例えば、上記の例では最初に LogFilter が適用され、次に AuthenFilter が適用されますが、下記の例ではこの順序が逆になります:

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

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

web.xml 設定の各ノードの説明

  • <filter>1つのフィルタを指定します。
    • <filter-name>フィルタに名前を指定するために使用します。この要素の内容は空にできません。
    • <filter-class>要素はフィルタの完全修飾クラス名を指定するために使用します。
    • <init-param>要素はフィルタの初期化パラメータを指定するために使用します。その子要素は<param-name>パラメータの名前を指定し、<param-value>パラメータの値を指定します。
    • フィルタ内では、FilterConfigFilterConfig インターフェースオブジェクトを使用して初期化パラメータにアクセスします。
  • <filter-mapping>要素は、Filter がインターセプトするリソースを設定するために使用します。Filter がインターセプトするリソースは、Servlet 名とリソースアクセスのリクエストパスの2つの方法で指定できます。
    • <filter-name>子要素はフィルタの登録名を設定するために使用します。この値は、<filter>要素内で宣言されたフィルタの名前でなければなりません。
    • <url-pattern>filter がインターセプトするリクエストパスを設定します(フィルタに関連付けられた URL パターン)。
  • <servlet-name>フィルタがインターセプトする Servlet 名を指定します。
  • <dispatcher>フィルタがインターセプトするリソースが Servlet コンテナによって呼び出される方法を指定します。指定できるのは、REQUEST,INCLUDE,FORWARDとERRORのいずれかで、デフォルトはREQUEST。ユーザーは複数設定できます<dispatcher>子要素を使用して、Filter によるリソースへの複数の呼び出し方法でのインターセプトを指定できます。
  • <dispatcher>子要素が設定できる値とその意味
    • REQUEST:ユーザーがページに直接アクセスした場合、Web コンテナはフィルタを呼び出します。ターゲットリソースが RequestDispatcher の include() または forward() メソッドを介してアクセスされた場合、このフィルタは呼び出されません。
    • INCLUDE:ターゲットリソースが RequestDispatcher の include() メソッドを介してアクセスされた場合、このフィルタが呼び出されます。それ以外の場合、このフィルタは呼び出されません。
    • FORWARD:ターゲットリソースが RequestDispatcher の forward() メソッドを介してアクセスされた場合、このフィルタが呼び出されます。それ以外の場合、このフィルタは呼び出されません。
    • ERROR:ターゲットリソースが宣言的な例外処理メカニズムを介して呼び出された場合、このフィルタが呼び出されます。それ以外の場合、フィルタは呼び出されません。
その他の拡張