コンテンツのインクルード

次のメソッドを使用して、サーブレットにコンテンツをインクルードできます。

RequestDispatcher オブジェクトの使用方法の詳細については、 「制御の受け渡し」 を参照してください。

include メソッドの使用

RequestDispatcher オブジェクトの include メソッドを使用すると、サーブレットに複数のタイプのコンテンツをインクルードできます。

include メソッドを使用すると、呼び出し側サーブレットは include メソッドの呼び出し前後に ServletOutputStream オブジェクトや PrintWriter オブジェクトに書き込むことができます。必要な場合は、 「制御の受け渡し」 で説明されているように、ServletRequest オブジェクトの setAttribute メソッドを使用して、ターゲットのサーブレットや JSP に情報を渡すことができます。また、 「セッションの操作」 で説明されているように、session オブジェクトを使用しても情報を渡すことができます。

次の例では、サーブレットをインクルードします。

...
PrintWriter out = resp.getWriter();
ServletContext sc = this.getServletContext();
RequestDispatcher rd = sc.getRequestDispatcher("/servlet/includeMe");
if (rd !=null) {
  try {
    // インクルードされたサーブレットは、それ自体のバッファーだけを制御します。
    rd.include(req, resp);
  }
  catch (Exception e) {
    sc.log("Problem invoking servlet.", e);
  }
}
...

サンプルサーブレットを表示するには、samples JRun サーバを起動し、ブラウザで http://localhost:8200/techniques を開きます。

getResource メソッドの使用

ServletContext オブジェクトの getResource メソッドを使用すると、サーブレットにコンテンツをインクルードできます。getResource メソッドは URL オブジェクトを返します。その後は、この URL オブジェクトを使用してこのコンテンツにアクセスできます。URL オブジェクトを使用する利点は、そのオブジェクトをブラウザに返す前にコンテンツを解析できることです。このテクニックを使用すると、/WEB-INF ディレクトリ内のファイルなど、他の方法ではユーザーが直接アクセスできないコンテンツもインクルードできます。

次の例では、getResource メソッドを使用してコンテンツをインクルードします。

...
resp.setContentType("text/html");
ServletOutputStream out = resp.getOutputStream();
ServletContext sc = this.getServletContext();
try {
  URL u = sc.getResource("/includedText.htm");
  if (u !=null) {
    // コンテンツにアクセスし、InputStream にキャストします。
    InputStream in = (InputStream)u.getContent();
    byte[] buf = new byte[255];
    int numRead = in.read(buf);
    while(numRead != -1){
      out.write(buf, 0, numRead);
      numRead = in.read(buf);
    }
  }else {
    out.println("<p>u was null");
  }
} catch (Exception e) {}
...

他の HTML ページからのコンテンツ取得

J2EE を使用すると、インターネットから Web ページを簡単に取得でき、それらのページを解析してそのコンテンツを独自のページにインクルードできます。このテクニックの一般的な応用には、野球などのボックススコアや株価表示を独自のページに追加してダイナミックデータを提供することがあります。

ターゲットの Web サイトから、既知の文字列を使用して解析できる規則正しいデータが出力される必要があります。規則正しいデータとは、各部分が一連の区切り文字列で区切られていることを意味します。たとえば、価格情報を取得するには、データ取得に必要な呼び出しがすべて成功するように、ターゲットのページでは製品価格が同じ HTML タグで囲まれ、同じように表示されている必要があります。

たとえば、Web サイト Funagain (www.funagain.com) では、ゲーム ID を使用してダイナミックページを生成します。Funagain は、各ゲームの価格、デザイナー、メーカーなどの多くの属性をリストするページを生成します。次の例に示すように、これらの属性は、Funagain Web ページの HTML では、Hidden フォームフィールドとして現れます。

<INPUT TYPE="HIDDEN" NAME="manufacturer" VALUE="Amigo">

この例では、Funagain でゲームの詳細を示す HTML ページは、メーカーを定義する Hidden フォームフィールドが含まれています。Funagain は、すべてのゲームについて同じ規則性でページを生成します。同様に、Yahoo! Finance (finance.yahoo.com) では、同じデータフォーマットを使用して株式相場のページを生成しています。

このセクションのテクニックを使用すると、メーカーの Hidden フォームフィールドの値を抽出できます。

Web アプリケーションの他のページからダイナミックコンテンツをインクルードする方法

  1. URL を構築します。この例は、Funagain のベース URL から成る URL に、フォームフィールドに入力したゲーム ID を追加します。次の例は、ターゲットの URL を構築する方法を示しています。
    ...
    String gameID = request.getParameter("gameID");
    String urlString = "http://kumquat.com/cgi-kumquat/funagain/" + 
    gameID;
    ...
    funagainURL = new URL(urlString);
    ...
    
  2. 次の行に示すように、ターゲットの Web サイトへの URL 接続を開きます。
    funagainConnection = funagainURL.openConnection();
    
  3. 次の例に示すように、新規の接続から InputStream を取得します。
    webPageInputStream = funagainConnection.getInputStream();
    
  4. 次の例に示すように、ターゲットの InputStream をバッファーに読み込みます。
    ...
    StringBuffer webPageDataBuffer = new StringBuffer(32000);
    int totalBytesRead = 0;
    boolean moreToRead = true;
    byte[] readBuf = new byte[4096]; // Web ページを 4K のチャンクで読み込みま
    す。
    while (moreToRead) {
      int numBytesRead = 0;
      try {
        numBytesRead = webPageInputStream.read(readBuf);
      } catch (IOException e) {
        moreToRead = false;
        numBytesRead = -1;
      }
      if (numBytesRead > 0) {
        totalBytesRead += numBytesRead;
        webPageDataBuffer.append(new String(readBuf, 0, 
    numBytesRead));
      } else {
        moreToRead = false;
      }
    }
    ...
    webpageDataBuffer.setLength(totalBytesRead);
    ...
    
  5. 次の行に示すように、Web ページのバッファーを String に変換します。
    String webPageData = webPageDataBuffer.toString();
    
  6. 次の例に示すように、抽出するターゲットデータ用に区切り文字列を定義します。
    label[3] = "Year: ";
    predetails[3] = "year¥" VALUE=¥"";
    postdetails[3] = "¥">";
    

    この例では、次の String の出現を開始区切り文字列として検索します。

    year" VALUE="

    この例では、¥"> を検索し、それを終了区切り文字列に設定します。

    ターゲット Web サイトの次の行が検索に一致します。

    <INPUT TYPE="HIDDEN" NAME="year" VALUE="1999">

    1999predetails 区切り文字列と postdetails 区切り文字列で区切られます。

  7. 次の例に示すように、区切り文字列に一致する String を検索して、Web ページの String 表現を解析します。
    ...
    int preStringLoc;
    int postStringLoc;
    preStringLoc = WebPageData.indexOf(predetails[i]);
    postStringLoc = WebPageData.indexOf(postdetails[i], preStringLoc);
    if (preStringLoc == -1 || postStringLoc == -1) {
      details[i] = "該当なし";
    } else {
      details[i] = WebPageData.substring(preStringLoc + 
    predetails[i].length(), postStringLoc);
    }
    ...
    
  8. 次の例に示すように、区切り文字列に一致する目的のデータをプリントします。
    ...
    for (int i = 0; i < details.length; i++) {
      out.println(label[i] + details[i]);
      out.println("<BR>");
    }
    ...
    

サンプルサーブレットを表示するには、samples JRun サーバを起動し、ブラウザで http://localhost:8200/techniques を開きます。