13 フィルタ
この章の内容は以下のとおりです。
フィルタの概要
フィルタは、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パターンまたは特定のサーブレットにマップします。指定できるフィルタの数に制限はありません。
フィルタのチェーンの構成
WebLogic Serverは、送られてくるHTTPリクエストに一致するすべてのフィルタ・マッピングのリストを作成することで、フィルタのチェーンを作成します。リストの順序は次の順番で決定します。
-
リクエストに一致する
url-pattern
を含むfilter-mapping
要素のあるフィルタは、web.xml
デプロイメント記述子に記述された順序でチェーンに追加されます。 -
リクエストに一致する
servlet-name
を含むfilter-mapping
要素のあるフィルタは、URLパターンに一致するフィルタの後でチェーンに追加されます。 -
チェーン内の最後の項目は常に、最初にリクエストされたリソースです。
フィルタ・クラスでは、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
)を参照してください。
追加のリソース
-
サーブレット3.1仕様(
http://jcp.org/en/jsr/detail?id=340
) -
Java EE 7 APIリファレンス(Javadocs)(
http://docs.oracle.com/javaee/7/api/index.html
) -
Java EEチュートリアル(
http://docs.oracle.com/javaee/7/tutorial/index.html
)