BodyContent クラス  
 
 
クラス名 :

javax.servlet.jsp.tagext.BodyContent

 
拡張するクラス :

javax.servlet.jsp.JspWriter

 
実装するクラス :

なし

 
実装先クラス :

内部コンテナ固有のクラス

 
説明

対応するタグハンドラが BodyTag インターフェイスを実装する場合、このコンテナは BodyContent クラスのインスタンスを作成し、要素の body 要素の評価結果を保持します。また、setBodyContent() メソッドを呼び出し、タグハンドラに対して BodyContent インスタンスを利用可能にして、タグハンドラが body 要素を処理できるようにします。

BodyTagSupport クラスを拡張するタグハンドラクラスについて説明します。EncodeHTMLTag クラスは、<ora:encodeHTML> と呼ばれるカスタムアクションのタグハンドラクラスです。このアクションは本文を読み取り、すべての文字を HTML で特殊な意味を持つ文字に置き換えます。たとえば、一重引用符、二重引用符、小なり記号、大なり記号、アンパサンドなどを、該当する HTML 文字 (&#39;&#34;&lt;&gt;&amp;) に置き換え、結果を応答本文に挿入します。次の例は、JSP ページでこのアクションを使用する方法を示します。

<%@ page language="java" %>
<%@ taglib uri="/orataglib" prefix="ora" %>
<html>
  <head>
    <title>Encoded HTML Example</title>
  </head>
  <body>
    <h1>Encoded HTML Example</h1>
    The following text is encoded by the 
    &lt;ora:encodeHTML&gt; custom action:
    <pre>
      <ora:encodeHTML>
        HTML 3.2 Documents start with a <!DOCTYPE> 
        declaration followed by an HTML element containing 
        a HEAD and then a BODY element: 

        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
        <HTML>
        <HEAD>
        <TITLE>A study of population dynamics</TITLE>
        ... other head elements
        </HEAD>
        <BODY>
        ... document body
        </BODY>
        </HTML>      
      </ora:encodeHTML>
    </pre>
  </body>
</html>

JSP ページの例にある <ora:encodeHTML> アクションの本文には、HTML 要素が含まれています。特殊文字が HTML 文字エンティティに変換されない場合、ブラウザは HTML を解釈し、要素そのものではなく解釈の結果を表示します。ただし、カスタムアクションを実行して変換を行うことで、ページは正しく処理されます。

アクション本文には、静的なテキストに加えて、任意の JSP 要素を含めることができます。このアクションのより現実的な使用として、たとえば、テキストの特殊文字がブラウザでどのように解釈されるかについて心配することなく、データベースからテキストを JSP ページに挿入できます。タグハンドラクラスは、次の例で示すように、非常にささいなものです。

package com.ora.jsp.tags.generic;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import com.ora.jsp.util.*;

public class EncodeHTMLTag extends BodyTagSupport {
    
    public int doAfterBody() throws JspException {
        BodyContent bc = getBodyContent();
        JspWriter out = getPreviousOut();
        try {
            out.write(toHTMLString(bc.getString()));
        }
        catch (IOException e) {} // Ignore
        return SKIP_BODY;
    }

    private String toHTMLString(String in) {
        StringBuffer out = new StringBuffer();
        for (int i = 0; in != null & i < in.length(); 
          i++) {
            char c = in.charAt(i);
            if (c == '\'') {
                out.append("&#39;");
            }
            else if (c == '\"') {
                out.append("&#34;");
            }
            else if (c == '<') {
                out.append("&lt;");
            }
            else if (c == '>') {
                out.append("&gt;");
            }
            else if (c == '&') {
                out.append("&amp;");
            }
            else {
                out.append(c);
            }
        }
        return out.toString();
    }
}

このアクションには属性がないので、タグハンドラはインスタンス変数やプロパティのアクセスメソッドを必要としません。タグハンドラは、doAfterBody() メソッドを除く、BodyTagSupport クラスで実装されるすべての BodyTag メソッドを再利用できます。

BodyTagSupport クラスに用意されている 2 つのユーティリティメソッドは、doAfterBody() メソッドで使用されます。getBodyContent() メソッドは、アクション本文の処理結果が含まれる BodyContent オブジェクトへの参照を返します。getPreviousOut() メソッドは、囲むアクションの BodyContent を返します。アクションが最上位レベルにある場合は、ページの主要な JspWriter を返します。

メソッドの名前が getOut() ではなく、getPreviousOut() であることを不思議に思うかもしれません。この名前には、囲む要素への出力として割り当てられるオブジェクトを、ネストされたアクション要素の階層で使用することを強調する意図があります。ページで次のアクション要素があるとします。

  <xmp:foo>
    <xmp:bar>
      Some template text
    </xmp:bar>
</xmp:foo>

Web コンテナは最初に JspWriter を作成し、それをページの out 変数に割り当てます。<xmp:foo> アクションが発生すると、BodyContent オブジェクトを作成し、一時的にそのオブジェクトを out 変数に割り当てます。次に、<xmp:bar> アクション用の別の BodyContent を作成し、再びそれを out に割り当てます。Web コンテナは、出力オブジェクトのこの階層を追跡します。標準の JSP 要素によって作成されたテンプレートテキストと出力は、現在の出力オブジェクトになります。各要素は、getBodyContent() メソッドを呼び出し、次にそのコンテンツを読み取って、その独自の BodyContent オブジェクトにアクセスできます。<xmp:bar> 要素については、コンテンツはテンプレートテキストです。コンテンツの処理後に、getPreviousOut() メソッドを通じてこの要素の BodyContent を取得して、そのコンテンツを <xmp:foo> 本文に書き込むことができます。最後に、<xmp:foo> 要素は <xmp:bar> 要素によって提供されるコンテンツを処理し、それを最上位レベルの出力オブジェクトに追加できます。これは、getPreviousOut() メソッドを呼び出して取得する JspWriter オブジェクトです。

この例のタグハンドラは、toHTMLString() メソッドを使用して、BodyContent オブジェクトで見つかったすべての特殊文字を変換します。getString() メソッドを使用して、BodyContent オブジェクトのコンテンツを取得し、toHTMLString() メソッドのパラメータとして使用します。その結果は、getPreviousOut() を呼び出して取得される JspWriter に書き込まれます。

この例の doAfterBody() メソッドは SKIP_BODY を返し、doEndTag() を呼び出して継続するようにコンテナに指示します。繰り返すカスタムアクションを実装するタグハンドラに対しては、doAfterBody() は代わりに EVAL_BODY_TAG を返すことができます。コンテナは、次に要素の本文をもう一度評価し、その結果を要素の BodyContent に書き込んで、doAfterBody() を呼び出します。この処理は、doAfterBody()SKIP_BODY を返すまで繰り返されます。

 
clearBody()  
public void clearBody()

このインスタンスに対してバッファリングされたすべてのコンテンツを削除します。

flush()  
public void flush() throws java.io.IOException

JspWriter から継承された動作を上書きし、常に IOException をスローします。これは、BodyContent インスタンスをフラッシュするのは無効であるためです。

getEnclosingWriter()  
public JspWriter getEnclosingWriter()

外側の JspWriter を返します。つまり、親タグハンドラの最上位レベルの JspWriter または JspWriter (BodyContent サブクラス) を返します。

getReader()  
public abstract java.io.Reader getReader()

この BodyContent オブジェクトの値を、要素の本文の評価によって作成されたコンテンツと共に Reader として返します。

getString()  
public abstract String getString()

この BodyContent オブジェクトの値を、要素の本文の評価によって作成されたコンテンツと共に String として返します。

writeOut()  
public abstract void writeOut(java.io.Writer out)
  throws java.io.IOException

この BodyContent オブジェクトのコンテンツを Writer に書き込みます。

BodyContent()  
protected BodyContent(JspWriter e)

指定された JspWriter を外側のライターとして使用して、新しいインスタンスを作成します。