ヘッダーをスキップ

Oracle Containers for J2EE サーブレット開発者ガイド
10g リリース3(10.1.3)

B28596-01
目次
目次
索引
索引

戻る 次へ

5 サーブレット・フィルタの理解および使用方法

サーブレット・コンテナが、クライアントにかわってサーブレット内のメソッドをコールすると、クライアントが送信したHTTPリクエストは、デフォルトで、サーブレットに直接渡されます。サーブレットが生成するレスポンスは、コンテナによる内容の修正なしに、デフォルトでクライアントに直接返されます。

これに対して、サーブレット・フィルタを使用して、Webアプリケーション・リクエストの前処理やサーバー・レスポンスの後処理を実行できます。フィルタについては、「前処理および後処理のためにフィルタを使用する場面」で簡単に説明しましたが、次の項で詳しく説明します。

フィルタ機能の概要

この項では、次の項目について簡単に説明します。

サーブレット・コンテナによるフィルタの起動

図5-1は、左側が、リクエスト対象のサーブレットに対してフィルタが構成されていない例を示しています。右側の例では、複数のフィルタ(1、2、...、N)が構成されています。

図5-1    フィルタ使用およびフィルタなしのサーブレットの起動


画像の説明

各フィルタは、javax.servlet.Filterインタフェースを実装します。このインタフェースには、リクエストとレスポンスのペアをフィルタ・チェーンとともに入力として取得するdoFilter()メソッドが含まれます。フィルタ・チェーンは、javax.servlet.FilterChainインタフェースを実装するクラス(サーブレット・コンテナによって提供されます)のインスタンスです。フィルタ・チェーンは、フィルタの順序を反映します。サーブレット・コンテナは、web.xmlファイルにおける構成順序に基づいて、マップされるフィルタを持つすべてのサーブレットまたはその他のリソースのフィルタ・チェーンを構成します。フィルタ・チェーンに含まれる各フィルタについては、フィルタに渡されるフィルタ・チェーン・オブジェクトが、順番にコールされる残りのフィルタを表します(これらのフィルタの後にターゲット・サーブレットが起動されます)。

FilterChainインタフェースも、doFilter()メソッドを指定します。このメソッドは、リクエストとレスポンスのペアを入力として取得し、各フィルタによってフィルタ・チェーンの次のエンティティを起動するために使用されます。

「標準Filterインタフェース」も参照してください。

たとえば、2つのフィルタがある場合、このメカニズムの主要な手順は、次のとおりです。

  1. ターゲット・サーブレットがリクエストされます。コンテナが、2つのフィルタが存在することを検出し、フィルタ・チェーンを作成します。

  2. チェーンの最初のフィルタがdoFilter()メソッドによって起動されます。

  3. 最初のフィルタがすべての前処理を完了し、フィルタ・チェーンのdoFilter()メソッドをコールします。これにより、2番目のフィルタがdoFilter()メソッドによって起動されます。

  4. 2番目のフィルタがすべての前処理を完了し、フィルタ・チェーンのdoFilter()メソッドをコールします。これにより、ターゲット・サーブレットがservice()メソッドによって起動されます。

  5. ターゲット・サーブレットの動作が完了すると、2番目のフィルタのチェーンdoFilter()コールが返され、2番目のフィルタがすべての後処理を実行できます。

  6. 2番目のフィルタの動作が完了すると、最初のフィルタのチェーンdoFilter()コールが返され、最初のフィルタがすべての後処理を実行できます。

  7. 最初のフィルタの動作が完了すると、実行が完了します。

どのフィルタも、順序を認識していません。順序は、web.xmlでフィルタが構成された順序に基づいて、フィルタ・チェーン全体によって処理されます。

一般的なフィルタ処理

フィルタのdoFilter()メソッドの処理には、次のものが含まれます。

ターゲット・リソースが起動する前に実行するすべての処理は、チェーンdoFilter()コールの前にある必要があります。ターゲット・リソースが完了した後に実行するすべての処理は、チェーンdoFilter()コールの後にある必要があります。これには、レスポンスのヘッダーの直接設定も含めることができます。

リクエスト・オブジェクトの前処理やレスポンス・オブジェクトの後処理では、元のリクエストまたはレスポンス・オブジェクトを直接操作できないことに注意してください。ラッパーを使用する必要があります。たとえば、レスポンスを後処理する場合、ターゲット・サーブレットはすでに動作を完了しており、フィルタがレスポンスになんらかの処理を実行できる時点ではレスポンスがすでにコミットされている可能性があります。元のレスポンスのかわりにレスポンス・ラッパーをチェーンdoFilter()コールに渡す必要があります。「フィルタを使用したリクエストまたはレスポンスのラップおよび変更」を参照してください。

標準Filterインタフェース

サーブレット・フィルタは、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インタフェースのメソッド

Filterインタフェースは、次のメソッドを指定して、フィルタに実装します。

FilterChainインタフェースのメソッド

FilterChainインタフェースは、次の1つのメソッドを指定します。

FilterConfigインタフェースのメソッド

FilterConfigインタフェースは、オプションで使用できる次のメソッドを指定します。

フィルタの実装および構成

この項では、フィルタの実装および構成の基本手順を示します。これらの手順は、「単純なフィルタの例」に示されている例の全体に含まれています。

また、web.xmlでのフィルタ構成順序に基づくフィルタ・チェーンの構造を説明する項もあります。

フィルタのコードの実装

この項では、サーブレット・フィルタのコードを実装する手順を示します。

  1. javax.servlet.Filterインタフェースを実装するクラスを作成します。次に例を示します。

    public class TimerFilter implements javax.servlet.Filter { }
    
  2. フィルタの初期化のために、Filterインタフェースで指定されるinit()メソッドを実装します。最初に、init()が入力として取得するjavax.servlet.FilterConfigオブジェクトを作成または取得します。次に例を示します。

    private FilterConfig filterConfig;
    ...
    public void init(final FilterConfig filterConfig)
    {
        this.filterConfig = filterConfig;
    }
    

    特別な初期化処理が必要な場合は、「FilterConfigインタフェースのメソッド」を参照してください。

  3. フィルタ処理のために、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()が返されたときに実行されます。

  4. リソースをクリーンアップしたり、フィルタがサービスから削除される前に必要なすべての特別な処理を実行したりするために、Filterインタフェースで指定されるdestroy()メソッドを実行します。次に例を示します。

    public void destroy()
    {
        filterConfig = null;
    }
    


    注意

    HTTPリクエストまたはレスポンスに変更を加えるフィルタの実装においては、追加の考慮事項があります。「フィルタを使用したリクエストまたはレスポンスのラップおよび変更」を参照してください。 


フィルタの構成

この項では、サーブレット・フィルタを構成する手順を示します。フィルタごとに、web.xmlで次の手順を実行してください。

  1. フィルタ・クラス(パッケージを含む)をフィルタ名にマップする<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>
    
  2. <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構成順序に基づいて、適切なフィルタのチェーンを構築します。

  1. 最初に、<url-pattern>要素に基づいてサーブレットまたはリソースに適合するすべてのフィルタが、web.xmlでのフィルタの宣言順に、チェーンに入れられます。

  2. 次に、<servlet-name>要素に基づいてサーブレットまたはリソースに適合するすべてのフィルタが、<url-pattern>に合致する最後のフィルタに続いて<servlet-name>に合致する最初のフィルタが入る順序で、チェーンに入れられます。

  3. 最後に、<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ページの作成

次に、待機してから待機時間をブラウザに出力するターゲット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がコンテンツ・パスの/myfilterfilter.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の<dispatcher>要素

転送ターゲットまたはインクルード・ターゲットに対するフィルタを構成するには、web.xml<filter-mapping><dispatcher>サブ要素を使用します。この要素については、次の4つの値がサポートされています。

例は、次項の「転送またはインクルード・ターゲットのフィルタの構成」を参照してください。

転送またはインクルード・ターゲットのフィルタの構成

この項では、転送ターゲットまたはインクルード・ターゲットに対して動作するようにフィルタを構成する場合のいくつかの例を示します。まずフィルタ宣言を示し、その後で代替フィルタ・マッピング構成を示します。

<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>要素がないかぎり、MyFilterincludedservletの直接リクエストに対して実行されないことに注意してください。

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>

フィルタを使用したリクエストまたはレスポンスのラップおよび変更

特に役立つフィルタの機能は、リクエストまたはリクエストに対するレスポンスを操作できることです。リクエストまたはレスポンスを操作するには、ラッパーを作成する必要があります。次の一般的な手順を使用できます。

  1. リクエストを操作するには、標準javax.servlet.http.HttpServletRequestWrapperクラスを拡張するクラスを作成します。このクラスは、必要に応じてリクエストに変更を加えることを可能にするリクエスト・ラッパーになります。

  2. レスポンスを操作するには、標準javax.servlet.http.HttpServletResponseWrapperクラスを拡張するクラスを作成します。このクラスは、ターゲット・サーブレットまたはその他のリソースがレスポンスを提供し、多くの場合にそれをコミットした後に、レスポンスに変更を加えることを可能にするレスポンス・ラッパーになります。

  3. オプションで、レスポンスの出力ストリームにカスタム機能を追加する場合は、標準javax.servlet.ServletOutputStreamクラスを拡張するクラスを作成します。

  4. カスタム・クラスのインスタンスを使用するフィルタを作成し、必要に応じて、リクエストまたはレスポンスに変更を加えます。

次項の「レスポンス・フィルタの例」で、レスポンスに変更を加えるフィルタの例を提供します。

レスポンス・フィルタの例

この例では、カスタムのサーブレット出力ストリームを使用するHTTPサーブレット・レスポンス・ラッパーを使用します。この機能により、ラッパーは、ターゲットHTMLページがレスポンスを作成して送信した後でも、レスポンス・データを操作することができます。ラッパーを使用しないと、サーブレット出力ストリームがクローズした後(基本的には、サーブレットがレスポンスをコミットした後)では、レスポンス・データを変更できません。この例にあるServletOutputStreamクラスに対してフィルタ固有の拡張機能を実装するのはこのためです。

この例では、次のカスタム・クラスを使用します。

カスタム出力ストリーム・コードの作成

この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(); 
  } 
} 

ターゲットHTMLページの作成

この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がコンテンツ・パスの/mywrappermyresponsewrapper.warにマップするものとします。この場合、デプロイ後、次のように、prepostfilter.htmlを起動します。その結果、フィルタが実行されます。

http://host:port/mywrapper/prepostfilter.html

次に、ブラウザへの出力を示します。フィルタによって、PREPOSTおよび横の罫線が追加されています。


画像の説明


戻る 次へ
Oracle
Copyright © 2006 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引