13 フィルタ

WebLogic WebアプリケーションでのJavaクラス(フィルタとも呼ばれる)の使用方法を学習します。

この章の内容は以下のとおりです。

フィルタの概要

フィルタは、Webアプリケーションのリソースに対するリクエストに応えて呼び出されるJavaクラスです。リソースには、Javaサーブレット、JavaServer Pages (JSP)および静的リソース(HTMLページや画像など)があります。フィルタを使用すると、リクエストをインターセプトして、レスポンス・オブジェクトおよびリクエスト・オブジェクトの検証や変更などを実行できます。

フィルタは、開発者が既存のリソースのコーディングを変更できず、そのリソースの動作を変更する必要がある状況を主に想定した、高度なJava EE機能です。一般に、フィルタを使ってリソースを変更するよりは、コードを変更してリソースの動作自体を変更した方が効率的です。状況によっては、フィルタを使用することによって、アプリケーションが不必要に複雑になり、パフォーマンスが低下することがあります。

フィルタの動作と仕組み

フィルタは、Webアプリケーションのコンテキストで定義します。フィルタは特定の名前のリソースまたはリソースのグループ(URLパターンに基づく)に対するリクエストをインターセプトして、フィルタ内でコードを実行します。それぞれのリソースまたはリソースのグループに対して、単一のフィルタ、またはチェーンと呼ばれる特定の順序で起動される複数のフィルタを指定できます。

フィルタは、リクエストをインターセプトするとき、HTTPリクエストとレスポンスへのアクセスを提供するjavax.servlet.ServletRequestオブジェクトとjavax.servlet.ServletResponseオブジェクト、およびjavax.servlet.FilterChainオブジェクトにアクセスできます。FilterChainオブジェクトには、順番に起動できるフィルタのリストが含まれています。フィルタは、作業を終了すると、チェーン内の次のフィルタを起動する、リクエストをブロックする、例外をスローする、本来リクエストされていたリソースを起動する、のうちのいずれかの処理を行うことができます。

本来のリソースが起動されると、制御は、チェーン内のリストの最後にあるフィルタに返されます。その後で、このフィルタは、レスポンス・ヘッダーとデータの検査および変更、リクエストのブロック、例外のスロー、チェーンの最後より1つ手前にあるフィルタの起動のいずれかを行うことができます。このプロセスはフィルタのチェーン内において逆順で続行されます。

ノート:

フィルタでヘッダーを変更できるのは、レスポンスがまだコミットされていない場合のみです。

フィルタの用途

フィルタは次の機能を行うときに便利です。

  • ロギング機能の実装

  • ユーザーが作成したセキュリティ機能の実装

  • デバッグ

  • 暗号化

  • データの圧縮

  • クライアントに送信されるレスポンスの変更(ただし、レスポンスの後処理を行うと、アプリケーションのパフォーマンスが低下するおそれがあります。)

フィルタ・クラスの作成

フィルタ・クラスを記述するには、javax.servlet.Filterインタフェースを実装します。

http://docs.oracle.com/javaee/7/api/javax/servlet/Filter.htmlを参照してください。このインタフェースの次のメソッドを実装する必要があります。

  • init()

  • destroy()

  • doFilter()

doFilter()メソッドは、リクエスト・オブジェクトとレスポンス・オブジェクトの検査と変更、ロギングなど他のタスクの実行、チェーン内の次のフィルタの起動、または、それ以上の処理のブロックのために使います。

フィルタの名前、ServletContext、およびフィルタの初期化属性にアクセスするために、FilterConfigオブジェクトに対して利用できるメソッドが他にいくつかあります。詳細は、javax.servlet.FilterConfigのJava EE javadoc(http://docs.oracle.com/javaee/7/api/javax/servlet/FilterConfig.html)を参照してください。

チェーン内の次の項目(別のフィルタや元のリソースなどの場合があります)にアクセスするには、FilterChain.doFilter()メソッドを呼び出します。

フィルタの構成

Webアプリケーションのweb.xmlデプロイメント記述子を使って、フィルタをアプリケーションの一部として構成します。デプロイメント記述子では、フィルタを指定してから、そのフィルタをWebアプリケーションのURLパターンまたは特定のサーブレットにマップします。指定できるフィルタの数に制限はありません。

フィルタの構成

フィルタを構成するには:

  1. テキスト・エディタでweb.xmlデプロイメント記述子を開くか、WebLogic Server管理コンソールを使用します。「Webアプリケーション開発者向けツール」を参照してください。web.xmlファイルは、WebアプリケーションのWEB-INFディレクトリにあります。
  2. フィルタ宣言を追加します。filter要素では、フィルタの宣言、フィルタの名前の定義、およびフィルタを実行するJavaクラスの指定を行います。filter要素は、context-param要素のすぐ後で、listenerおよびservlet要素のすぐ前に指定します。たとえば:
    <context-param>Param</context-param>
    <filter>
      <icon>
        <small-icon>MySmallIcon.gif</small-icon>
        <large-icon>MyLargeIcon.gif</large-icon>
      </icon>
      <filter-name>myFilter</filter-name>
      <display-name>My Filter</display-name>
      <description>This is my filter</description>
      <filter-class>examples.myFilterClass</filter-class>
    </filter>
    <listener>Listener</listener>
    <servlet>Servlet</servlet>
    

    icondescriptiondisplay-nameの各要素は省略可能です。

  3. filter要素の内部に1つまたは複数の初期化属性を指定します。たとえば:
    <filter>
      <icon>
        <small-icon>MySmallIcon.gif</small-icon>
        <large-icon>MyLargeIcon.gif</large-icon>
      </icon>
      <filter-name>myFilter</filter-name>
      <display-name>My Filter</display-name>
      <description>This is my filter</description>
      <filter-class>examples.myFilterClass</filter-class>
      <init-param>
        <param-name>myInitParam</param-name>
        <param-value>myInitParamValue</param-value>
      </init-param>
    </filter>
    

    FilterクラスはFilterConfig.getInitParameter()メソッドまたはFilterConfig.getInitParameters()メソッドを使って初期化属性を読み取ることができます。

  4. フィルタ・マッピングを追加します。filter-mapping要素は、URLパターンまたはサーブレット名を基にしてどのフィルタを実行するかを指定します。filter-mapping要素は、filter要素(群)のすぐ後ろに指定します。
    • URLパターンを使ったフィルタ・マッピングを作成するには、フィルタの名前とURLパターンを指定します。URLパターン・マッチングは、サーブレット3.1仕様(http://jcp.org/en/jsr/detail?id=340)で規定されているルールに従って実行されます。たとえば、次のfilter-mapping/myPattern/を含むリクエストにmyFilterをマップします。

      <filter-mapping>
        <filter-name>myFilter</filter-name>
        <url-pattern>/myPattern/*</url-pattern>
      </filter-mapping>
      
    • 特定のサーブレットに対するフィルタ・マッピングを作成するには、Webアプリケーションに登録されたサーブレットの名前にフィルタをマップします。たとえば、次のコードはmyServletというサーブレットにmyFilterフィルタをマップします。

      <filter-mapping>
        <filter-name>myFilter</filter-name>
        <servlet-hame>myServlet</servlet-name>
      </filter-mapping>
      
  5. フィルタのチェーンを作成するには、複数のフィルタ・マッピングを指定します。「フィルタのチェーンの構成」を参照してください。

フィルタのチェーンの構成

WebLogic Serverは、送られてくるHTTPリクエストに一致するすべてのフィルタ・マッピングのリストを作成することで、フィルタのチェーンを作成します。リストの順序は次の順番で決定します。

  1. リクエストに一致するurl-patternを含むfilter-mapping要素のあるフィルタは、web.xmlデプロイメント記述子に記述された順序でチェーンに追加されます。

  2. リクエストに一致するservlet-nameを含むfilter-mapping要素のあるフィルタは、URLパターンに一致するフィルタのでチェーンに追加されます。

  3. チェーン内の最後の項目は常に、最初にリクエストされたリソースです。

フィルタ・クラスでは、FilterChain.doFilter()メソッドを使ってチェーン内の次の項目を起動します。

サーブレット・レスポンス・オブジェクトでのフィルタ処理

サーブレットによって生成された出力にデータを追加することで、フィルタをサーブレットの出力の後処理に使用できます。ただし、サーブレットの出力を取り込むには、レスポンスにラッパーを作成する必要があります(サーブレットが実行を完了し、制御がチェーン内の最後のフィルタに戻されるに、サーブレットの出力バッファは自動的にフラッシュされ、クライアントに送信されるので、元のレスポンス・オブジェクトは使用できません。)そのようなラッパーを作成すると、WebLogic Serverはメモリーで出力の追加コピーを処理する必要が生じ、パフォーマンスが低下することがあります。

レスポンス・オブジェクトやリクエスト・オブジェクトのラッピングの詳細は、javax.servlet.http.HttpServletResponseWrapperおよびjavax.servlet.http.HttpServletRequestWrapper(http://docs.oracle.com/javaee/7/api/javax/servlet/http/package-summary.html)を参照してください。

追加のリソース