Skip to content

8. A biblioteca de tags JSTL

8.0.1. Introdução

Consideremos a vista [erreurs.jsp], que apresenta uma lista de erros:

Image

Existem várias formas de escrever uma página deste tipo. Aqui, estamos interessados apenas na parte relativa à exibição dos erros. Uma primeira solução consiste em utilizar código Java, tal como foi feito:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page import="java.util.ArrayList" %>

<%
// recuperam-se os dados do modelo
  ArrayList erreurs=(ArrayList)request.getAttribute("erreurs"); 
  String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
        <%
          for(int i=0;i<erreurs.size();i++){
            out.println("<li>" + (String) erreurs.get(i) + "</li>\n");
        }//for
      %>
    </ul>
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      <%= lienRetourFormulaire %>
    </a>
  </body>
</html>

A página JSP recupera a lista de erros da consulta (linha 8) e apresenta-a através de um ciclo Java (linhas 19-23). A página mistura código HTML e código Java, o que pode ser problemático se a página tiver de ser mantida por um designer gráfico, que, em geral, não compreenderá o código Java. Para evitar esta mistura, utilizam-se bibliotecas de tags que irão proporcionar novas possibilidades às páginas JSP. Com a biblioteca de tags JSTL (Java Standard Tag Library), a visualização anterior passa a ser a seguinte:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
    </ul>
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      ${lienRetourFormulaire}
    </a>
  </body>
</html>

A tag (linha 4)

<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

indica a utilização de uma biblioteca de tags cuja definição se encontra no ficheiro [/WEB-INF/c.tld]. Estas tags serão utilizadas no código da página, precedidas pela letra c (prefix="c"). É possível utilizar qualquer prefixo à escolha. Aqui, c significa [core]. Os prefixos permitem utilizar bibliotecas de tags que possam ter os mesmos nomes para determinadas tags. A utilização do prefixo elimina a ambiguidade. A nova página já não tem código Java nos dois locais onde anteriormente o tinha:

  • a recuperação do modelo da página [erreurs, lienRetourFormulaire] (parte removida)
  • a exibição da lista de erros (linhas 13-15)

O ciclo de exibição dos erros foi substituído pelo seguinte código:


            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
  • a baliza <forEach> serve para delimitar um ciclo
  • A notação ${variável} serve para escrever o valor de uma variável

A baliza <forEach> tem aqui dois atributos:

  • items="${erreurs}" indica a coleção de objetos sobre a qual se deve iterar. Aqui, a coleção é o objeto «erreurs». Onde é que este se encontra? A página JSP procura um atributo chamado «erreurs» sucessivamente e por ordem em:
    • o objeto [request], que representa o pedido transmitido pelo controlador: request.getAttribute("erreurs")
    • o objeto [session], que representa a sessão do cliente: session.getAttribute("erros")
    • o objeto [application], que representa o contexto da aplicação web: application.getAttribute("erros")

A coleção designada pelo atributo items pode assumir várias formas: tableau, ArrayList, objeto que implementa a interface List, ...

  • var="erro" serve para atribuir um nome ao elemento atual da coleção que está a ser processada. O ciclo <forEach> será executado sucessivamente para cada elemento da coleção items. No interior do ciclo, o elemento da coleção que está a ser processado será, portanto, designado aqui por erro.

A notação ${erreur} insere o valor da variável «erreur» no texto. Esta variável não é necessariamente uma cadeia de caracteres. JSTL utiliza o método erreur.toString() para inserir o valor da variável «erreur». Em vez da notação ${erro}, também é possível utilizar a baliza <c:out value="${erro}"/>.

Voltando ao nosso exemplo de exibição de erros:

  • o controlador irá incluir na solicitação enviada à página JSP um ArrayList de mensagens de erro, ou seja, um ArrayList de objetos String: request.setAttribute("erros", erros), em que «erros» é o ArrayList;
  • devido ao atributo items="${erros}", a página JSP procura um atributo chamado erros, sucessivamente na consulta, na sessão e na aplicação. Irá encontrá-lo na solicitação: request.getAttribute("erros") irá devolver o ArrayList colocado na solicitação pelo controlador;
  • a variável erreur do atributo var="erro" irá, portanto, referir-se ao elemento atual de ArrayList, ou seja, a um objeto String. O método erreur.toString() irá inserir o valor deste String, neste caso uma mensagem de erro, no fluxo HTML da página.

Os objetos da coleção processada pela baliza <forEach> podem ser mais complexos do que simples cadeias de caracteres. Tomemos o exemplo de uma página JSP que apresenta uma lista de artigos:

1
2
3
4
5
6
7
            <c:forEach var="article" items="${listarticles}">
                <tr>
                    <td><c:out value="${article.nom}"/></td>
                    <td><c:out value="${article.prix}"/></td>
                    <td><a href="<c:url value="?action=infos&id=${article.id}"/>">Infos</a></td>
                </tr>
     </c:forEach>

onde [listarticles] é um ArrayList de objetos do tipo [Article], que se supõe ser um Javabean com os campos [id, nom, prix, stockActuel, stockMinimum], sendo que cada um desses campos é acompanhado pelos seus métodos get e set. O objeto [listarticles] foi inserido na solicitação pelo controlador. A página anterior JSP irá recuperá-lo no atributo «items» da baliza forEach. O objeto atual «article» (var="article") designa, portanto, um objeto do tipo [Article]. Consideremos a baliza da linha 3:

<c:out value="${article.nom}"/>

O que significa ${article.nom}? Na verdade, pode significar várias coisas, dependendo da natureza do objeto «artigo». Para obter o valor de article.nom, a página JSP irá tentar duas coisas:

  1. article.getNom() — repare-se na grafia getNom para recuperar o campo «nome» (norma JavaBean)
  2. article.get("nome")

O objeto [article] pode, portanto, ser um bean com um campo «nom», ou um dicionário com uma chave «nom».

Não há limites para a hierarquia do objeto em questão. Assim, a baliza

<c:out value="${individu.enfants[1].nom}"/>

permite processar um objeto [individu] do seguinte tipo:

class Individu{
    private String nom;
    private String prénom;
    private Individu[] enfants;
     // métodos da norma JavaBean
    public String getNom(){ return nom;}
    public String getPrénom(){ return prénom;}
    public Individu getEnfants(int i){ return enfants[i];}
}

Para obter o valor de ${individu.enfants[1].nom}, a página JSP irá tentar vários métodos, incluindo este, que será bem-sucedido:

individu.getEnfants(1).getNom(), em que «individuo» designa um objeto do tipo «Indivíduo».

8.0.2. Instalar e explorar a biblioteca JSTL

As explicações fornecidas anteriormente serão suficientes para a aplicação que nos interessa, mas a biblioteca de tags JSTL oferece outras tags além das apresentadas. Para as descobrir, pode-se instalar um tutorial fornecido no pacote da biblioteca.

Iremos utilizar a implementação JSTL 1.1 do projeto [Jakarta Taglibs], disponível no URL [http://jakarta.apache.org/taglibs/] (maio de 2006):

O ficheiro zip descarregado tem um conteúdo semelhante ao seguinte:

Image

Os dois ficheiros com a extensão .war são arquivos de aplicações web:

  • standard-doc: documentação sobre as balizas JSTL
  • standard-examples: exemplos de utilização das balizas

Vamos implementar esta última aplicação no Tomcat. Iniciamos o Tomcat através da opção adequada do menu [Démarrer], depois introduzimos o URL [http://localhost:8080] e seguimos o link [Tomcat Manager]:

Image

Surge então uma página de autenticação. Identificamo-nos como manager / manager ou admin / admin, tal como foi demonstrado no parágrafo 2.3.3.

Image

Aparece uma página que lista as aplicações atualmente implementadas no Tomcat:

Image

Podemos adicionar uma nova aplicação através dos formulários localizados na parte inferior da página:

Image

Utilizamos o botão [Parcourir] para selecionar um ficheiro .war a implementar.

Image

A captura de ecrã não o mostra, mas selecionámos o ficheiro [standard-examples.war] da distribuição JSTL que descarregámos. O botão [Deploy] guarda e implementa esta aplicação no Tomcat.

Image

A aplicação [/standard-examples] foi corretamente implementada. Vamos iniciá-la:

Image

O leitor é convidado a seguir os vários links disponibilizados nesta página quando procurar exemplos de utilização das balizas JSTL.

A aplicação [standard-doc] poderá ser implementada da mesma forma a partir do ficheiro [standard-doc.war]. Esta aplicação dá acesso a informações bastante técnicas sobre a biblioteca JSTL. Apresenta menos interesse para o principiante.

8.0.3. Utilizar o JSTL numa aplicação web

Nos exemplos fornecidos com a biblioteca JSTL 1.2, as páginas JSP têm, no início do ficheiro, a seguinte baliza:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

Já nos deparámos com esta baliza no parágrafo 8.1.1 e demos uma breve explicação:

  • [uri]: URI (Uniform Resource Identifier), onde se encontra a definição das etiquetas utilizadas na página. Esta URI será utilizada pelo servidor web quando a página JSP for convertida em código Java para se tornar um servlet. É também utilizada pelas ferramentas de desenvolvimento de páginas web para verificar a sintaxe correta das balizas utilizadas na página ou para sugerir sugestões de preenchimento automático. Quando se começa a escrever uma baliza, uma ferramenta que conheça a biblioteca pode então sugerir ao utilizador os atributos possíveis para essa baliza.
  • [prefix]: prefixo que identifica estas etiquetas na página

O URI [http://java.sun.com/jsp/jstl/core] não pode ser utilizado se não se estiver ligado à Internet pública. Nesse caso, é possível colocar localmente o ficheiro de definição das etiquetas. Vários ficheiros deste tipo são fornecidos com a distribuição JSTL 1.2 na pasta [tld] (Tag Language Definition):

Image

JSTL é, na verdade, um conjunto de bibliotecas de tags. Iremos utilizar apenas a biblioteca [c.tld], conhecida como biblioteca «core». Iremos colocar o ficheiro [c.tld] acima referido na pasta [WEB-INF] das nossas aplicações:

Image

e inseriremos a seguinte tag nas nossas páginas JSP para declarar a utilização da biblioteca «core»:

<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

Embora a utilização de bibliotecas de tags nos permita evitar a inserção de código Java nas páginas JSP, estas tags são, naturalmente, convertidas em código Java durante a conversão da página JSP num servlet Java. Estas utilizam classes definidas em dois ficheiros [jstl.jar, standard.jar] que se encontram na pasta [lib] da distribuição JSTL:

Image

Estes dois arquivos estão localizados na pasta [WEB-INF/lib] das nossas aplicações:

Image

Temos agora as bases para abordar a próxima versão da nossa aplicação de exemplo.