Oracle Containers for J2EE サーブレット開発者ガイド 10g(10.1.3.1.0) B31859-01 |
|
サーブレット・コンテナが、クライアントにかわってサーブレット内のメソッドをコールすると、クライアントが送信したHTTPリクエストは、デフォルトで、サーブレットに直接渡されます。サーブレットが生成するレスポンスは、コンテナによる内容の修正なしに、デフォルトでクライアントに直接返されます。
これに対して、サーブレット・フィルタを使用して、Webアプリケーション・リクエストの前処理やサーバー・レスポンスの後処理を実行できます。 フィルタについては、「前処理および後処理のためにフィルタを使用する場面」で簡単に説明しましたが、次の項で詳しく説明します。
この項では、次の項目について簡単に説明します。
図4-1は、左側が、リクエスト対象のサーブレットに対してフィルタが構成されていない例を示しています。右側の例では、複数のフィルタ(1、2、...、N)が構成されています。
各フィルタは、javax.servlet.Filter
インタフェースを実装します。このインタフェースには、リクエストとレスポンスのペアをフィルタ・チェーンとともに入力として取得するdoFilter()
メソッドが含まれます。フィルタ・チェーンは、javax.servlet.FilterChain
インタフェースを実装するクラス(サーブレット・コンテナによって提供されます)のインスタンスです。フィルタ・チェーンは、フィルタの順序を反映します。サーブレット・コンテナは、web.xml
ファイルにおける構成順序に基づいて、マップされるフィルタを持つすべてのサーブレットまたはその他のリソースのフィルタ・チェーンを構成します。フィルタ・チェーンに含まれる各フィルタについては、フィルタに渡されるフィルタ・チェーン・オブジェクトが、順番にコールされる残りのフィルタを表します(これらのフィルタの後にターゲット・サーブレットが起動されます)。
FilterChain
インタフェースも、doFilter()
メソッドを指定します。このメソッドは、リクエストとレスポンスのペアを入力として取得し、各フィルタによってフィルタ・チェーンの次のエンティティを起動するために使用されます。
「標準Filterインタフェース」も参照してください。
たとえば、2つのフィルタがある場合、このメカニズムの主要な手順は、次のとおりです。
doFilter()
メソッドによって起動されます。
doFilter()
メソッドをコールします。これにより、2番目のフィルタがdoFilter()
メソッドによって起動されます。
doFilter()
メソッドをコールします。これにより、ターゲット・サーブレットがservice()
メソッドによって起動されます。
doFilter()
コールが返され、2番目のフィルタがすべての後処理を実行できます。
doFilter()
コールが返され、最初のフィルタがすべての後処理を実行できます。
どのフィルタも、順序を認識していません。順序は、web.xml
でフィルタが構成された順序に基づいて、フィルタ・チェーン全体によって処理されます。
フィルタのdoFilter()
メソッドの処理には、次のものが含まれます。
doFilter()
メソッドを使用して、リクエストとレスポンスのペア(またはラッパー)をチェーンの次のエンティティに渡します。または、リクエスト処理をブロックするために、チェーンdoFilter()
メソッドをコールしません。
ターゲット・リソースが起動する前に実行するすべての処理は、チェーンdoFilter()
コールの前にある必要があります。ターゲット・リソースが完了した後に実行するすべての処理は、チェーンdoFilter()
コールの後にある必要があります。これには、レスポンスのヘッダーの直接設定も含めることができます。
リクエスト・オブジェクトの前処理やレスポンス・オブジェクトの後処理では、元のリクエストまたはレスポンス・オブジェクトを直接操作できないことに注意してください。ラッパーを使用する必要があります。たとえば、レスポンスを後処理する場合、ターゲット・サーブレットはすでに動作を完了しており、フィルタがレスポンスになんらかの処理を実行できる時点ではレスポンスがすでにコミットされている可能性があります。元のレスポンスのかわりにレスポンス・ラッパーをチェーンdoFilter()
コールに渡す必要があります。 「フィルタを使用したリクエストまたはレスポンスのラップおよび変更」を参照してください。
サーブレット・フィルタは、javax.servlet.Filter
インタフェースを実装します。このインタフェースの主要なメソッドであるdoFilter()
は、フィルタ・チェーン全体を表すためにサーブレット・コンテナによって作成されるjavax.servlet.FilterChain
インスタンスを入力として取得します。Filter
インタフェースの初期化メソッドであるinit()
は、javax.servlet.FilterConfig
のインスタンスであるフィルタ構成オブジェクトを入力として取得します。この項では、これらのインタフェースで指定されるメソッドについて簡単に説明します。
この項で説明するインタフェースやメソッドに関する追加情報は、次のサイトでSun社のjavax.servlet
パッケージのJavadocを参照してください。
http://java.sun.com/j2ee/1.4/docs/api/index.html
Filter
インタフェースは、次のメソッドを指定して、フィルタに実装します。
void init(FilterConfig filterConfig)
サーブレット・コンテナは、フィルタが初めてインスタンス化されてサービスに組み込まれる際に、init()
をコールします。このメソッドは、javax.servlet.FilterConfig
インスタンスを入力として取得します。このインスタンスは、サーブレット・コンテナによって、初期化時に情報をフィルタに渡すために使用されます。すべての特別な初期化要件を実装にインクルードします。 「FilterConfigインタフェースのメソッド」も参照してください。
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
ここで、フィルタ処理が実行されます。ターゲット・リソース(サーブレット、JSPページなど)がリクエストされる(ここで、ターゲット・リソースが1つ以上のフィルタのチェーンにマップされる)たびに、サーブレット・コンテナは、web.xml
フィルタ構成に基づく順序で、チェーンの各フィルタのdoFilter()
メソッドをコールします。 (詳細は、「フィルタ・チェーンの構造」を参照してください。)フィルタのdoFilter()
処理内において、フィルタのdoFilter()
メソッドに渡されるフィルタ・チェーン・オブジェクトでdoFilter()
メソッドを起動します。(リクエスト処理をブロックする場合は例外です。)これにより、フィルタの動作が完了した後に、チェーン内の次のエンティティ(次のフィルタか、これがチェーン内の最後のフィルタである場合はターゲット・サーブレット)が起動します。
destroy()
サーブレット・コンテナは、フィルタのすべての動作が完了(doFilter()
メソッドのすべてのスレッドが完了した場合またはタイムアウトが発生した場合)して、サービスからのフィルタの削除が開始される際、destroy()
をコールします。すべての特別なクリーンアップ要件を実装にインクルードします。
FilterChain
インタフェースは、次の1つのメソッドを指定します。
void doFilter(ServletRequest request, ServletResponse response)
このメソッドを起動する(フィルタのdoFilter()
メソッドから実行)と、チェーン内の次のエンティティ(次のフィルタか、このメソッドがチェーン内の最後のフィルタからコールされている場合はサーブレットやJSPページなどのターゲット・リソース)が起動します。
FilterConfig
インタフェースは、オプションで使用できる次のメソッドを指定します。
java.util.Enumeration getInitParameterNames()
web.xml
ファイルの<filter>
要素の下の<init-param>
要素を使用してフィルタの初期化パラメータを設定できます。 (詳細は、「フィルタの構成」を参照してください。)その後、フィルタで、FilterConfig
オブジェクト(init()
によって渡される)のgetInitParameterNames()
メソッドを使用して、初期化パラメータ名を含むJava文字列のEnumeration
オブジェクトを取得できます。(フィルタの初期化パラメータがない場合、Enumeration
オブジェクトは空です。)
String getInitParameter(String paramname)
初期化パラメータ名の取得の後に、getInitParameter()
を使用して、指定されたパラメータの値を取得します。
ServletContext getServletContext()
このメソッドを使用すると、リクエストされた(フィルタがフィルタリングする)サーブレットに関連付けられたサーブレット・コンテキストを取得できます。
String getFilterName()
このメソッドを使用すると、web.xml
ファイルの<filter-name>
要素に基づいて、フィルタの名前を取得できます。
この項では、フィルタの実装および構成の基本手順を示します。 これらの手順は、「単純なフィルタの例」に示されている例の全体に含まれています。
また、web.xml
でのフィルタ構成順序に基づくフィルタ・チェーンの構造を説明する項もあります。
この項では、サーブレット・フィルタのコードを実装する手順を示します。
javax.servlet.Filter
インタフェースを実装するクラスを作成します。 次に例を示します。
public class TimerFilter implements javax.servlet.Filter { }
Filter
インタフェースで指定されるinit()
メソッドを実装します。最初に、init()
が入力として取得するjavax.servlet.FilterConfig
オブジェクトを作成または取得します。 次に例を示します。
private FilterConfig filterConfig; ... public void init(final FilterConfig filterConfig) { this.filterConfig = filterConfig; }
特別な初期化処理が必要な場合は、「FilterConfigインタフェースのメソッド」を参照してください。
Filter
インタフェースで指定されるdoFilter()
メソッドを実装します。このメソッドは、リクエスト・オブジェクト、レスポンス・オブジェクトおよびjavax.servlet.FilterChain
オブジェクト(サーブレット・コンテナで作成される)を取得します。必要なすべての処理を実装し、(通常)フィルタ・チェーン・オブジェクトのdoFilter()
をコールしてチェーン内の次のエンティティを起動します。 次に例を示します。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, javax.servlet.ServletException { long start = System.currentTimeMillis(); System.out.println("Milliseconds in: " + start); chain.doFilter(request, response); long end = System.currentTimeMillis(); System.out.println("Milliseconds out: " + end); }
最初のprintln()
コールはチェーンの他の部分が起動される前に実行され、2番目のprintln()
コールは後でchain.doFilter()
が返されたときに実行されます。
Filter
インタフェースで指定されるdestroy()
メソッドを実行します。 次に例を示します。
public void destroy() { filterConfig = null; }
この項では、サーブレット・フィルタを構成する手順を示します。フィルタごとに、web.xml
で次の手順を実行してください。
<filter>
要素およびそのサブ要素を使用してフィルタを宣言します。 次に例を示します。
<filter> <filter-name>timer</filter-name> <filter-class>filter.TimerFilter</filter-class> </filter>
オプションで、サーブレットの場合と同様に、ここで初期化パラメータを指定できます。
<filter> <filter-name>timer</filter-name> <filter-class>filter.TimerFilter</filter-class> <init-param> <param-name>name</param-name> <param-value>value</param-value> <init-param> </filter>
<filter-mapping>
要素およびそのサブ要素を使用して、フィルタ名をサーブレット名またはURLパターンにマップし、フィルタを対応するリソース(サーブレット、JSPページなど)に関連付けます。たとえば、myservlet
という名前のサーブレットが起動されると必ずフィルタが起動されるようにするには、次のようにします。
<filter-mapping> <filter-name>timer</filter-name> <servlet-name>myservlet</servlet-name> </filter-mapping>
また、URLパターンに基づいて、sleepy.jsp
がリクエストされると必ずフィルタが起動されるようにするには、次のようにします。
<filter-mapping> <filter-name>timer</filter-name> <url-pattern>/sleepy.jsp</url-pattern> </filter-mapping>
<url-pattern>
要素で特定のリソースを指定するかわりに、(例のように)ワイルド・カード文字を使用して複数のリソースを適合させることもできます。
<url-pattern>/mypath/*</url-pattern>
任意のフィルタ名を使用できますが、意味のある名前を使用することをお薦めします。このフィルタ名は、単に、フィルタ・クラスをサーブレット名またはURLパターンにマップする際のリンケージとして使用されます。
リソースに適用する複数のフィルタを構成する場合、それらのフィルタは、web.xml
での宣言順序に基づいてサーブレット・チェーンに入れられ、ターゲット・サーブレットがリクエストされたときにその順序で起動されます。次項の「フィルタ・チェーンの構造」を参照してください。
web.xml
でフィルタを宣言してマップすると、Webアプリケーションの各サーブレットまたはその他のリソース(JSPページ、静的ページなど)に適用されるフィルタがサーブレット・コンテナによって決定されます。その後、サーブレットまたはリソースごとに、サーブレット・コンテナが、次のように、web.xml
構成順序に基づいて、適切なフィルタのチェーンを構築します。
<url-pattern>
要素に基づいてサーブレットまたはリソースに適合するすべてのフィルタが、web.xml
でのフィルタの宣言順に、チェーンに入れられます。
<servlet-name>
要素に基づいてサーブレットまたはリソースに適合するすべてのフィルタが、<url-pattern>
に合致する最後のフィルタに続いて<servlet-name>
に合致する最初のフィルタが入る順序で、チェーンに入れられます。
<servlet-name>
に合致する最後のフィルタの次に、ターゲット・サーブレットまたはその他のリソースがチェーンの最後に入れられます。
次の例は、JSPページがリクエストされたときに起動するフィルタを示しています。JSPページは、ブラウザにメッセージを書き込みます。フィルタは、OC4Jコンソールに、JSPページの実行の前後に1行ずつ、2行のメッセージを書き込みます。
次に、単純なフィルタのコードのTimerFilter
を示します。 doFilter()
メソッドは、OC4Jコンソールに、ターゲットJSPの実行の前後に1行ずつ、2行のメッセージを書き込みます。
package filter; import javax.servlet.*; public class TimerFilter implements javax.servlet.Filter { private FilterConfig filterConfig; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, javax.servlet.ServletException { long start = System.currentTimeMillis(); System.out.println("Milliseconds in: " + start); chain.doFilter(request, response); long end = System.currentTimeMillis(); System.out.println("Milliseconds out: " + end); } public void init(final FilterConfig filterConfig) { this.filterConfig = filterConfig; } public void destroy() { filterConfig = null; } }
次に、待機してから待機時間をブラウザに出力するターゲットJSPページのsleepy.jsp
を示します。
<% int sleeptime = 1000; Thread.sleep(sleeptime); %> <HTML> <HEAD> <TITLE>Sleepy JSP</TITLE> </HEAD> <BODY> <HR> <P><CENTER>Sleepy JSP slept for <%= sleeptime %> milliseconds!</CENTER></P> <HR> </BODY> </HTML>
次に、単純なフィルタを宣言してそのフィルタをsleepy.jsp
のリクエストにマップするweb.xml
での構成を示します。
<?xml version="1.0" ?> <!DOCTYPE web-app (doctype...)> <web-app> <filter> <filter-name>timer</filter-name> <filter-class>filter.TimerFilter</filter-class> </filter> <filter-mapping> <filter-name>timer</filter-name> <url-pattern>/sleepy.jsp</url-pattern> </filter-mapping> </web-app>
この例のWARファイル(filter.war
)は、次のコンテンツと構造を持ちます。
sleepy.jsp META-INF/Manifest.mf WEB-INF/web.xml WEB-INF/classes/filter/TimerFilter.class WEB-INF/classes/filter/TimerFilter.java
また、EARファイルは、次のとおりです。
filter.war META-INF/Manifest.mf META-INF/application.xml
(Manifest.mf
ファイルは、JARユーティリティにより自動的に作成されます。)
この例では、application.xml
がコンテンツ・パスの/myfilter
をfilter.war
にマップするものとします。この場合、デプロイ後、次のように、sleepy.jsp
を起動します。その結果、フィルタが実行されます。
http://host:port/myfilter/sleepy.jsp
次のメッセージがブラウザに書き込まれます。
Sleepy JSP slept for 1000 milliseconds!
例を実行すると、次のメッセージがOC4Jコンソール(たとえば、スタンドアロン環境でOC4Jを実行している場合は、OC4Jを起動した場所)に書き込まれます。
04/04/30 13:01:19 Milliseconds in: 1083355279136 04/04/30 13:01:20 Milliseconds out: 1083355280152
Milliseconds in行は、JSPページの起動前に書き込まれます。Milliseconds out行は、JSPページが実行され、実行がフィルタに返された後に書き込まれます。この例では、1016ミリ秒の差がありますが、そのほとんどは、JSPページの1000ミリ秒間の待機によるものです。
直接リクエスト・ターゲットに対する動作に加えて(またはそのかわりに)転送ターゲットまたはインクルード・ターゲットに対して動作するようにフィルタを構成することができます。これについて、次の項で説明します。
転送ターゲットまたはインクルード・ターゲットに対するフィルタを構成するには、web.xml
の<filter-mapping>
の<dispatcher>
サブ要素を使用します。この要素については、次の4つの値がサポートされています。
INCLUDE
: この値は、指定されたサーブレット名に合致するインクルード・ターゲットまたは指定されたパターンに合致するURLを持つインクルード・ターゲットのすべてに適用されるフィルタに対して使用します。
FORWARD
: この値は、指定されたサーブレット名に合致する転送ターゲットまたは指定されたパターンに合致するURLを持つ転送ターゲットのすべてに適用されるフィルタに対して使用します。
REQUEST
: この値は、指定されたサーブレット名に合致する直接リクエスト・ターゲットまたは指定されたパターンに合致するURLを持つ直接リクエスト・ターゲットにも適用されるフィルタに対して、INCLUDE
またはFORWARD
設定(設定ごとに1つの<dispatcher>
要素)に加えて使用します。(REQUEST
値のみを使用することは無意味です。直接リクエストのみにフィルタを適用する場合は、<dispatcher>
要素を使用する必要はありません。)
ERROR
: この値は、エラー・ページ・メカニズムで適用されるフィルタに対して使用します。
例は、次項の「転送またはインクルード・ターゲットのフィルタの構成」を参照してください。
この項では、転送ターゲットまたはインクルード・ターゲットに対して動作するようにフィルタを構成する場合のいくつかの例を示します。まずフィルタ宣言を示し、その後で代替フィルタ・マッピング構成を示します。
<filter> <filter-name>myfilter</filter-name> <filter-class>mypackage.MyFilter</filter-class> </filter>
MyFilter
を実行してincludedservlet
というインクルード・ターゲットをフィルタリングするには、次のようにします。
<filter-mapping> <filter-name>myfilter</filter-name> <servlet-name>includedservlet</servlet-name> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
include()
コールはアプリケーションの任意のサーブレット(またはその他のリソース)から発生していることに注意してください。また、値としてREQUEST
を持つ別の<dispatcher>
要素がないかぎり、MyFilter
がincludedservlet
の直接リクエストに対して実行されないことに注意してください。
MyFilter
を実行して、/mypath/
というURLパターンによって直接リクエストされるすべてのサーブレットや、/mypath/
というURLパターン文字列によって起動するすべての転送ターゲットをフィルタリングするには、次のようにします。
<filter-mapping> <filter-name>myfilter</filter-name> <url-pattern>/mypath/*</url-pattern> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping>
特に役立つフィルタの機能は、リクエストまたはリクエストに対するレスポンスを操作できることです。リクエストまたはレスポンスを操作するには、ラッパーを作成する必要があります。次の一般的な手順を使用できます。
javax.servlet.http.HttpServletRequestWrapper
クラスを拡張するクラスを作成します。このクラスは、必要に応じてリクエストに変更を加えることを可能にするリクエスト・ラッパーになります。
javax.servlet.http.HttpServletResponseWrapper
クラスを拡張するクラスを作成します。このクラスは、ターゲット・サーブレットまたはその他のリソースがレスポンスを提供し、多くの場合にそれをコミットした後に、レスポンスに変更を加えることを可能にするレスポンス・ラッパーになります。
javax.servlet.ServletOutputStream
クラスを拡張するクラスを作成します。
次項の「レスポンス・フィルタの例」で、レスポンスに変更を加えるフィルタの例を提供します。
この例では、カスタムのサーブレット出力ストリームを使用するHTTPサーブレット・レスポンス・ラッパーを使用します。この機能により、ラッパーは、ターゲットHTMLページがレスポンスを作成して送信した後でも、レスポンス・データを操作することができます。ラッパーを使用しないと、サーブレット出力ストリームがクローズした後(基本的には、サーブレットがレスポンスをコミットした後)では、レスポンス・データを変更できません。この例にあるServletOutputStream
クラスに対してフィルタ固有の拡張機能を実装するのはこのためです。
この例では、次のカスタム・クラスを使用します。
GenericResponseWrapper
: HTTPレスポンスの操作でカスタム機能を使用できるようにHttpServletResponseWrapper
を拡張します。
FilterServletOutputStream
: レスポンス・ラッパーで使用できるカスタム機能を提供するためにServletOutputStream
を拡張します。
MyGenericFilter
: このクラスは、ベース・クラスとして使用される汎用の空(パススルー)フィルタです。
PrePostFilter
: MyGenericFilter
を拡張し、HTTPレスポンスに変更を加えてHTMLページ出力の前後に1行ずつメッセージを挿入するdoFilter()
コードを実装します。
このFilterServletOutputStream
というクラスは、標準ServletOutputStream
クラスを拡張して、レスポンス・ラッパーが使用する特別な機能を実装します。
package mypkg; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class FilterServletOutputStream extends ServletOutputStream { private DataOutputStream stream; public FilterServletOutputStream(OutputStream output) { stream = new DataOutputStream(output); } public void write(int b) throws IOException { stream.write(b); } public void write(byte[] b) throws IOException { stream.write(b); } public void write(byte[] b, int off, int len) throws IOException { stream.write(b,off,len); } }
このGenericResponseWrapper
というクラスは、標準HttpServletResponseWrapper
クラスを拡張して、HTTPレスポンスを操作するためのカスタム機能を実装します。
package mypkg; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class GenericResponseWrapper extends HttpServletResponseWrapper { private ByteArrayOutputStream output; private int contentLength; private String contentType; public GenericResponseWrapper(HttpServletResponse response) { super(response); output=new ByteArrayOutputStream(); } public byte[] getData() { return output.toByteArray(); } public ServletOutputStream getOutputStream() { return new FilterServletOutputStream(output); } public PrintWriter getWriter() { return new PrintWriter(getOutputStream(),true); } public void setContentLength(int length) { this.contentLength = length; super.setContentLength(length); } public int getContentLength() { return contentLength; } public void setContentType(String type) { this.contentType = type; super.setContentType(type); } public String getContentType() { return contentType; } }
このMyGenericFilter
というクラスは、空フィルタで、この例のレスポンス・フィルタによって拡張されるテンプレートを提供します。
package mypkg; import javax.servlet.*; public class MyGenericFilter implements javax.servlet.Filter { public FilterConfig filterConfig; public void doFilter(final ServletRequest request, final ServletResponse response, FilterChain chain) throws java.io.IOException, javax.servlet.ServletException { chain.doFilter(request,response); } public void init(final FilterConfig filterConfig) { this.filterConfig = filterConfig; } public void destroy() { } }
MyGenericFilter
クラスを拡張するこのPrePostFilter
というクラスは、ターゲットHTMLページのレスポンスに変更を加え、HTMLページ出力の前後にそれぞれ出力行を追加します。
package mypkg; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class PrePostFilter extends MyGenericFilter { public void doFilter(final ServletRequest request, final ServletResponse response, FilterChain chain) throws IOException, ServletException { OutputStream out = response.getOutputStream(); out.write(new String("<HR>PRE<HR>").getBytes()); GenericResponseWrapper wrapper = new GenericResponseWrapper((HttpServletResponse) response); chain.doFilter(request,wrapper); out.write(wrapper.getData()); out.write(new String("<HR>POST<HR>").getBytes()); out.close(); } }
このprepostfilter.html
というHTMLページは、この例でユーザーによってリクエストされます。フィルタは、このページの出力の前後に出力を挿入します。
<HTML> <HEAD> <TITLE>PrePostFilter Example</TITLE> </HEAD> <BODY> This is a testpage. You should see<br> this text when you invoke prepostfilter.html, <br> as well as the additional material added<br> by the PrePostFilter class. <br> </BODY> </HTML>
次に、レスポンス・フィルタを宣言してそのフィルタをprepostfilter.html
のリクエストにマップするweb.xml
での構成を示します。
<?xml version="1.0" ?> <!DOCTYPE web-app (doctype...)> <web-app> <filter> <filter-name>prepost</filter-name> <filter-class>mypkg.PrePostFilter</filter-class> </filter> <filter-mapping> <filter-name>prepost</filter-name> <url-pattern>/prepostfilter.html</url-pattern> </filter-mapping> </web-app>
この例のWARファイル(myresponsewrapper.war
)は、次のコンテンツと構造を持ちます。
prepostfilter.html META-INF/Manifest.mf WEB-INF/web.xml WEB-INF/classes/mypkg/FilterServletOutputStream.class WEB-INF/classes/mypkg/FilterServletOutputStream.java WEB-INF/classes/mypkg/GenericResponseWrapper.class WEB-INF/classes/mypkg/GenericResponseWrapper.java WEB-INF/classes/mypkg/MyGenericFilter.class WEB-INF/classes/mypkg/MyGenericFilter.java WEB-INF/classes/mypkg/PrePostFilter.class WEB-INF/classes/mypkg/PrePostFilter.java
また、EARファイルは、次のとおりです。
myresponsewrapper.war META-INF/application.xml META-INF/Manifest.mf
(Manifest.mf
ファイルは、JARユーティリティにより自動的に作成されます。)
この例では、application.xml
がコンテンツ・パスの/mywrapper
をmyresponsewrapper.war
にマップするものとします。この場合、デプロイ後、次のように、prepostfilter.html
を起動します。その結果、フィルタが実行されます。
http://host:port/mywrapper/prepostfilter.html
次に、ブラウザへの出力を示します。フィルタによって、PRE
、POST
および横の罫線が追加されています。
10.1.3で導入されたOC4J固有フィルタ・ディスパッチャにより、フィルタはフォーム認証を介してOC4Jに渡されるユーザー名/パスワード資格証明にアクセスできます。 たとえば、外部リソースの認証を追加して実行する場合にこの機能を使用します。
この機能を使用可能にするには、FORMAUTH
値をorion-web.xml
ファイル内のフィルタの<dispatcher>
要素で指定します。
次の例では、フィルタを宣言するコードおよびFORMAUTH
機能を指定するコードを示します。
orion-web.xml
またはweb.xml
の場合は次のとおりです。
<filter> <filter-name>MyFilter</filter-name> <filter-class>myFilterClass</filter-class> </filter>
orion-web.xmlの場合は次のとおりです。
<orion-web-app> ... <web-app> ... <filter-mapping> <filter-name>MyFilter</filter-name> <dispatcher>FORMAUTH</dispatcher> </filter-mapping> </web-app> </orion-web-app>
この方法で宣言したフィルタはいずれも、認証フォームの発行後、OC4Jでの認証の実行前に実行されます。
フィルタはrequest.getParameters()
をコールして、j_username
およびj_password
パラメータをリクエスト・オブジェクトから取得します。
次に、コール側コードの例を示します。
import javax.servlet.*; import javax.servlet.http.*; public class MyFilter implements Filter { public MyFilter() { super(); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletExxception { HttpServletRequest req = (HttpServletRequest) request; String username = req.getParameter("j_username"); String password = req.getParameter("j_password"); // use these credentials to access a remote DB .... filterChain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { } public void destroy() { } }
|
![]() Copyright © 2006 Oracle Corporation. All Rights Reserved. |
|