前へ     目次     索引     DocHome     次へ     
iPlanet Web Server, Enterprise Edition サーブレットに関するプログラマーズガイド



第 7 章   API に関するヒント


この章では、Servlet 2.2 API 仕様が iPlanet Web Server 6.0 で実装される方法を説明します。また、以下の節から構成されています。



HttpSession スコープについて

Servlet 2.2 API 仕様は、HttpSession オブジェクトのスコープに関して流動的です。

デフォルトでは、iPlanet Web Server は、コンテキストパスまたはアプリケーションの contextPath への cookie のパスを追跡して、セッションにマークを付けます。 これにより、ブラウザで、関係のないアプリケーションに対してセッション cookie が再実行されることがなくなります。 したがって、HttpSession オブジェクトが適切にスコープ指定されます。

しかし、あるコンテキスト内の サーブレット A が異なるコンテキスト内の サーブレット B に要求をディスパッチすると、仕様は流動的になります。 デフォルトでは、iPlanet Web Server ではこのディスパッチが許可されているため、HttpSession オブジェクトの属性は、関連アプリケーションに共通するクラスローダーによって読み込まれるようにしてください。 通常はお勧めできませんが、仮想サーバレベルのクラスローダーやシステムクラスローダーを使用することもできます。

異なるアプリケーションでセッションおよびセッション属性を共有するには次の項目に従います。

  • 仮想サーバレベルで共通のセッションマネージャを使用する

    <vs>
           <session-manager class="..." />
    </vs>

  • セッション属性が仮想サーバレベルのクラスローダーによって読み込まれるようにし、クラスパスにセッション属性として使用する共通 Bean などを追加する

    <vs>
           <class-loader classpath="/myapps/sessionattrs.jar" />
    </vs>

この設定により、仮想サーバ内のすべてのアプリケーションでセッションを共有できるようになります。この設定を行わない場合は、すべてのアプリケーションでセッションは共有されません。 iPlanet Web Server 6.0 では、一部のアプリケーションでのみ同じセッションデータを共有するような設定はサポートされていません。



メソッドの使用方法について



この節では、iPlanet Web Server 6.0 で以下の Servlet 2.2 API メソッドを使用する方法について説明します。

ここで説明されているメソッドおよびすべての Servlet API メソッドに関する公式マニュアルは、以下の Web サイトにある Sun Microsystems の Servlets API Javadoc を参照してください。

http://java.sun.com/products/servlet/2.2/javadoc/index.html


HttpServlet.service

public void service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException

このメソッドは、限定公開の service メソッドにクライアント要求をディスパッチします。


ヒント

サーブレットは、サービスロジックを処理するための、追加スレッドを作成することがあります。 ただし、これらのオブジェクトによって呼び出された API 関数は、要求を処理するスレッドか、サーブレットが作成したスレッドのどちらか 1 つによってアクセスされている必要があります。これら両方のスレッドが同時にその関数にアクセスすることはできません。


ServletContext.getAttribute

public java.lang.Object getAttribute(java.lang.String name)

指定した名前のサーブレット コンテナ属性を返します。その名前の属性がない場合は、null を返します。


ヒント

コンテキストクラスローダー (java.lang.ClassLoader オブジェクト) を取得するには、com.iplanet.server.http.servlet.classloader 属性を使用します。 コンテキストクラスローダーのクラスパス (java.lang.String オブジェクト) を取得するには、com.iplanet.server.http.servlet.classpath 属性を使用します。コンテキストクラスローダーの再読み込み間隔 (java.lang.Integer オブジェクト) を取得するには、com.iplanet.server.http.servlet.reload-interval 属性を使用します。


ServletRequest.setAttribute

public void setAttribute(java.lang.String name, java.lang.Object o)

現在の要求に属性を格納します。 属性は、要求間で設定し直されます。 このメソッドは、多くの場合、RequestDispatcher と共に使用されます。


ヒント

要求オブジェクトに com.iplanet.server.http.servlet.parameterEncoding 属性を設定すると、getParameter メソッドに、取り出すパラメータの符号化を認識させることができます。


ServletRequest.getParameter

public java.lang.String getParameter(java.lang.String name)

パラメータ名に関連付けられている値を取得します。


ヒント

フォームフィールドに UTF-8 以外の文字がある場合は、以下のいずれかの操作を行う必要があります。そうしない場合、getParameter メソッドで取得される値はゼロまたは未定義になります。

  • web-apps.xml ファイルで、parameter-encoding 要素の enc 属性を auto (デフォルト) に設定する。 詳しくは、「parameter-encoding」を参照してください。

  • iPlanet Web Server 4.x のときと同様、contexts.properties ファイルで、
    parameterEncoding プロパティを auto (デフォルト) または responseCT に設定する。 詳しくは、「parameterEncoding」を参照してください。

フォームフィールドにデータを入力するときに使用される元の符号化は、そのデータが URL に符号化されると失われるため、以下の操作を行う必要があります。

  • クライアントにフォームを送信するときには、必ず応答コンテンツの種類を設定する。 これにより、フォーム全体がクライントに正常に送信されます。

  • フォームフィールドと異なるロケールを使用するサーバにフォームデータを送信するときには、getParameter メソッドを呼び出す前に、以下のように charset を指定する

    • フォームを生成するサーブレットまたは JSP と、フォームを処理するサーブレットまたは JSP が異なる場合は、フォームの隠しフィールド (デフォルトでは j_encoding と呼ばれる) を使用します。以下に例を示します。

      <input type="hidden" name="j_encoding" value="US_ASCII">

    • 要求オブジェクトに com.iplanet.server.http.servlet.parameterEncoding 属性を設定します (「ServletRequest.setAttribute」を参照)。 この属性は、パラメータを復号化するために getParameter メソッドによって使用されます。

    • contexts.propertiesparameterEncoding=responseCT に設定されていて、同じサーブレットまたは JSP がフォームの生成および処理を両方行なっている場合は、応答コンテンツの種類を設定することができます。 サーブレットの場合は、以下の例のように、応答コンテンツの種類を明示的に設定します。

      res.setContentType("text/plain; charset=Shift_JIS");

      JSP の場合は、以下の例のように、page 指令を使用して応答コンテンツの種類を設定します。

      <%@ page contentType="text/html; charset=gb2312"%>


ServletResponse.getOutputStream および getWriter

public ServletOutputStream getOutputStream() throws java.io.IOException

バイナリデータを応答に書き込むために適している ServletOutputStream を返します。 サーブレット コンテナは、バイナリデータを符号化しません。 本文を書く際には、このメソッドまたは getWriter のどちらか一方を呼び出します。両方を呼び出す必要はありません。

public java.io.PrintWriter getWriter() throws java.io.IOException

文字テキストをクライアントに送信するための PrintWriter オブジェクトを返します。文字の符号化方式は、setContentType(java.lang.String) メソッドの charset= プロパティで指定したものが使用されます。上記のメソッドを呼び出す前にこのメソッドを呼び出さないと、Charset が有効になりません。

本文を書く際には、このメソッドまたは getOutputStream のどちらか一方を呼び出します。両方を呼び出す必要はありません。


ヒント

仕様では、getOutputStream メソッドがすでに呼び出されている場合にサーブレットが応答で getWriter メソッドを呼び出すとき (またはその逆) は、サーブレット コンテナが IllegalStateException をスローすることが推奨されています。

iPlanet Web Server 6.0 では、例外はスローされません。ただし、writer および出力ストリームへの書き込みの順序付けが、必ず行われます。 このような実装条件は厳しくありませんが、正確さは保持されるため、以下のようなシナリオが可能です。

  • サーブレットが getOutputStream を呼び出して例外をスローし、JSP が例外ページを表示するために使用される。 仕様に厳密に準拠すれば、このシナリオは失敗します。なぜなら、JSP が応答オブジェクトで getWriter を呼び出そうとするからです。

  • getWriter を呼び出す JSP に、getOutputStream を呼び出すサーブレットが指定されている


RequestDispatcher.forward および include

public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException;

このメソッドはサーブレットから、Web サーバ上の別のリソースに要求を転送するときに使用します。 このメソッドは、サーブレットが要求の事前処理を行い、別のオブジェクトに応答を生成させる場合に便利です。

ターゲットオブジェクトに受け渡された要求オブジェクトは、その要求 URL パスとほかのパスパラメータを、ターゲットオブジェクトのターゲット URL パスを反映するように調整します。

このメソッドは、応答で ServletOutputStream オブジェクトまたは PrintWriter オブジェクトが取得されている場合は使用できません。その場合、メソッドは IllegalStateException をスローします。

public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException;

別のサーバリソースによって生成されたコンテンツを応答の本体にインクルードするときに使用します。 本質的に、このメソッドは、プログラムをサーバ側でインクルードすることを可能にするものです。 ターゲットオブジェクトに受け渡された要求オブジェクトは、その要求 URL パスと要求の呼び出し元のパス情報を反映します。 応答オブジェクトは、呼び出し元のサーブレットの ServletOutputStream オブジェクトまたは PrintWriter オブジェクトにのみアクセスできます。

インクルードされているサーブレットは、ヘッダーを設定できません。 このサーブレットがヘッダー (Cookies など) を設定する必要があるメソッドを呼び出しても、うまく機能しません。サーブレット開発者は、ヘッダーに直接アクセスする必要のあるメソッドが適切に処理されるようにする必要があります。 セッションを正常に動作させるには、セッショントラッキングを行う場合であっても、インクルードされているサーブレットの外でセッションを開始するようにしてください。


ヒント

iPlanet Web Server 6.0 では、Writer または OutputStream が取得されている場合は、dispatcher.forward メソッドが IllegalStateException をスローするときとスローしないときがあります。 この動作は、ドラフト 2.2 に従っており、JSP エラーページの処理をするために必要です。 実際のデータがフラッシュされ、クライアントに送信された場合にのみ、例外がスローされます。 それ以外の場合は、バッファにある保留データがただ破棄されるだけです。

ターゲット URI が安全でない URI であると識別された場合 (つまり、URI の最後が ///.//..//.、 /..(Windows NT の場合 ./) など、セキュリティ保護されていないパス文字の場合)、forward および include メソッドは、ServletException をスローすることがあります。

magnus.confrequestDispatcherNestDepth パラメータを使用して、RequestDispatcher.forward および include メソッドの入れ子の深さを制御できます。 詳しくは、付録 Aを参照してください。



その他の関連情報



この節では、以下の項目に関する情報を説明します。


データベース接続プール

データベース接続プールによって、サーブレットまたは JSP のデータベース操作のパフォーマンスが向上します。 接続プールをサポートしている JDBC 2.0 互換ドライバには、Oracle 8i アップデート版や CloudScape 3.0 など、さまざまなものがあります。


クライアント証明書の取得

SSL を有効にしたためにクライアント証明書が必要になった場合、サーブレットは以下のようにクライアント証明書にアクセスします。

if (request.isSecure()) {
   java.security.cert.X509Certificate[] certs;
   certs = request.getAttribute("javax.servlet.request.X509Certificate");
   if (certs != null) {
      clientCert = certs[0];
      if (clientCert != null) {
         // ユーザの識別名を取得する
         java.security.Principal userDN = clientCert.getSubjectDN();
         ...
      }
   }
}

userDn は、ユーザの完全修飾識別名です。


前へ     目次     索引     DocHome     次へ     
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.

Last Updated September 17, 2001