Classe BodyContent  
 
 
Nom de la classe :

javax.servlet.jsp.tagext.BodyContent

 
Etend :

javax.servlet.jsp.JspWriter

 
Implémente :

Aucun

 
Implémentée par :

Classe interne dépendante du container

 
Description

Le container crée une instance de la classe BodyContent en vue de conserver le résultat de l'évaluation du contenu du corps de l'élément au cas où le gestionnaire de balises correspondant implémenterait l'interface BodyTag. Le container permet au gestionnaire de balises d'accéder à l'instance BodyContent en appelant la méthode setBodyContent(), le gestionnaire peut alors traiter le contenu du corps.

Prenons l'exemple d'une classe de gestionnaire de balises qui étend la classe BodyTagSupport. La classe EncodeHTMLTag représente la classe du gestionnaire de balises d'une action personnalisée appelée <ora:encodeHTML>. Cette action permet de lire le corps, de remplacer tous les caractères ayant une signification particulière en langage HTML, par exemple les guillemets simples, les guillemets doubles, les symboles inférieur à, les symboles supérieur à et les esperluettes, par leurs entités caractères HTML correspondantes (c'est-à-dire, ', ", <, >, et &) et d'insérer le résultat dans le corps de la réponse. L'exemple suivant montre comment utiliser l'action dans une page 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 
    <ora:encodeHTML> 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>

Notez que le corps de l'action <ora:encodeHTML> dans l'exemple de page JSP contient des éléments HTML. Si les caractères spéciaux ne sont pas convertis en entités de caractères HTML, le navigateur interprète le code HTML et affiche le résultat de cette interprétation à la place des éléments. La conversion réalisée par l'action personnalisée permet cependant de traiter correctement la page.

Outre du texte statique, le corps de l'action peut contenir tout type d'élément JSP. Pour mieux comprendre, cette action permet donc d'insérer dans une page JSP du texte provenant d'une base de données sans avoir à se soucier de la manière dont le navigateur interprète les caractères spéciaux du texte. La classe du gestionnaire de balises est extrêmement triviale, comme le montre l'exemple suivant :

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("'");
            }
            else if (c == '\"') {
                out.append(""");
            }
            else if (c == '<') {
                out.append("<");
            }
            else if (c == '>') {
                out.append(">");
            }
            else if (c == '&') {
                out.append("&");
            }
            else {
                out.append(c);
            }
        }
        return out.toString();
    }
}

L'action ne possèdant aucun attribut, le gestionnaire de balises n'a besoin d'aucune variable d'instance ni de méthodes d'accès aux propriétés. Le gestionnaire de balises peut réutiliser toutes les méthodes BodyTag implémentées par la classe BodyTagSupport, à l'exception de la méthode doAfterBody().

La méthode doAfterBody() utilise deux méthodes utilitaires fournies par la classe BodyTagSupport. La méthode getBodyContent() renvoie une référence à l'objet BodyContent contenant le résultat du traitement du corps de l'action. La méthode getPreviousOut() renvoie l'objet BodyContent de l'action englobante, le cas échéant, ou l'objet JspWriter principal de la page si l'action se trouve au niveau supérieur.

Vous aimeriez savoir pourquoi la méthode est appelée getPreviousOut() et non getOut(). Ce nom permet de souligner le fait que l'objet affecté doit être utilisé comme sortie de l'élément englobant dans la hiérarchie des éléments imbriqués d'une action. Prenons les éléments d'action suivants d'une page :

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

Le container web crée tout d'abord un objet JspWriter puis l'affecte à la variable out de la page. Lorsqu'il rencontre l'action <xmp:foo>, il crée un objet BodyContent qu'il affecte temporairement à la variable out. Il crée ensuite un autre objet BodyContent pour l'action <xmp:bar> qu'il affecte à nouveau à la variable out. Le container web garde trace de cette hiérarchie des objets de sortie. Le texte modèle et la sortie produits par les éléments JSP standard se retrouvent dans l'objet de sortie courant. Tous les éléments peuvent accéder à leurs propres objets BodyContent en appelant la méthode getBodyContent(), puis en lire le contenu. Pour l'élément <xmp:bar>, le contenu correspond au texte modèle. Une fois le traitement du contenu terminé, il peut être écrit dans le corps <xmp:foo> en appelant la méthode getPreviousOut() pour obtenir l'objet BodyContent de cet élément. Enfin, l'élément <xmp:foo> peut traiter le contenu fourni par l'élément <xmp:bar> et l'ajouter à l'objet de sortie supérieur : l'objet JspWriter obtenu en appelant la méthode getPreviousOut().

Dans l'exemple, le gestionnaire de balises convertit tous les caractères spéciaux trouvés dans son objet BodyContent à l'aide de la méthode toHTMLString(). Il a recours à la méthode getString() pour obtenir le contenu de l'objet BodyContent qu'il utilise ensuite comme argument pour la méthode toHTMLString(). Le résultat est écrit dans l'objet JspWriter obtenu en appelant la méthode getPreviousOut().

Dans cet exemple, la méthode doAfterBody() renvoie la valeur SKIP_BODY qui indique au container de poursuivre et d'appeler la méthode doEndTag(). Pour un gestionnaire de balises implémentant une action personnalisée itérée, la méthode doAfterBody() peut renvoyer à la place la valeur EVAL_BODY_TAG. Le container évalue alors à nouveau le corps de l'élément, écrit le résultat dans l'objet BodyContent de l'élément puis appelle la méthode doAfterBody(). Le traitement est répété jusqu'à ce que la méthode doAfterBody() renvoie la valeur SKIP_BODY.

 
clearBody()  
public void clearBody()

Supprime tout le contenu de la mémoire tampon de cette instance.

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

Ecrase le comportement hérité de l'objet JspWriter de manière à toujours déclencher une exception IOException, puisqu'il est interdit de supprimer une instance BodyContent.

getEnclosingWriter()  
public JspWriter getEnclosingWriter()

Renvoie l'objet englobant JspWriter ; autrement dit, soit l'objet JspWriter supérieur, soit l'objet JspWriter (sous-classe BodyContent) du gestionnaire de balises parent.

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

Renvoie la valeur de cet objet BodyContent sous forme d'objet Reader accompagné du contenu de l'évaluation du corps de l'élément.

getString()  
public abstract String getString()

Renvoie la valeur de cet objet BodyContent sous forme d'objet String accompagné du contenu de l'évaluation du corps de l'élément.

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

Ecrit le contenu de cet objet BodyContent dans un objet Writer.

BodyContent()  
protected BodyContent(JspWriter e)

Crée une nouvelle instance ayant pour scripteur englobant l'objet JspWriter spécifié.