Esse artigo faz parte da revista Java Magazine edição 15.
Clique aqui para ler todos os artigos desta edição
 

jm15_capa.jpg

para seu arsenal web

Conheça as bibliotecas de tags do projeto Taglibs, que hospeda a implementação de referência da JSTL – por um dos committers do projeto

O uso de taglibs tem se tornado cada vez mais difundido no desenvolvimento de páginas JSP. E não é para menos, já que as tags customizadas ajudam a separar as camadas de negócio e apresentação. Com a lógica embutida nas tags, é possível mudar o layout das páginas sem interferir na lógica, e alterar a lógica sem a necessidade de modificar o código de apresentação.

Embora muitas vezes precisemos criar tags específicas para nossos projetos, em outras situações podemos reaproveitar tags existentes, criadas para atender situações genéricas. Felizmente temos um grande leque de opções disponíveis – muitas já apresentadas em artigos da Java Magazine, como as tags HTML do Struts (“Struts: Primeiros Passos”, Edição 6, “Validação na Web”, Edição 7, e "Struts vai às compras”, Edição 11), as taglibs da JSTL (“JSTL: Guia completo”, Edições 7, 8 e 9), além das bibliotecas de tags para paginação (“Paginação na Web”, Edição 13).

Nesse artigo analisaremos mais uma importante opção: o projeto Jakarta Taglibs.

 

Nota: É comum usar o termo custom tag (tag customizada) como sinônimo de taglib (biblioteca de tags), mas isso não é correto. Uma taglib é uma coleção de custom tags.

Sobre o projeto

Basicamente, o Jakarta Taglibs é um repositório de bibliotecas de tags open source, sem restrições de funcionalidade ou relação entre si. O projeto se destaca por hospedar a implementação de referência (RI) da JSTL, um conjunto de taglibs padrão definidas pela JSR-52 (A Standard Tag Library for JavaServer Pages).

Cada biblioteca do Jakarta Taglibs pode ser encarada como um subprojeto à parte. Tem características próprias, como código fonte e JARs independentes, releases próprias e desenvolvedores responsáveis. E há também partes comuns: mesmas listas de discussão e mesmo gerenciador de bugs, repositório CVS compartilhado, e uma estrutura de buildfiles em que cada subprojeto compartilha um mesmo buildfile common.xml, contendo tasks comuns. Outra característica comum às taglibs do projeto é um mecanismo para geração dos TLDs e da documentação HTML das tags, a partir do mesmo documento XML.

Antes de apresentarmos detalhes das taglibs, é importante entendermos como são classificadas.

Categorias

As bibliotecas do Jakarta Taglibs são divididas por status, e não por suas funcionalidades. Atualmente temos as seguintes categorias:

·         Padronizadas (standardized): definidas por especificações do JCP

·         Suportadas (supported): oficialmente suportadas pelo projeto

·         Sandbox: em desenvolvimento, ainda não suportadas oficialmente

·         Depreciadas (deprecated): que deixaram de ser suportadas

 

Embora esta seja a classificação “oficial”, algumas das taglibs na categoria supported estão parcialmente obsoletas, pois boa parte de suas funcionalidades foi englobada pelas tags da JSTL. Por isso, entre os planos do projeto está a criação de uma categoria "obsoletas" (veja mais sobre o estado do Jakarta Taglibs no quadro “Passado, presente e futuro”).

A Tabela 1 relaciona as taglibs divididas em categorias, já incluindo a futura "obsoletas" na lista. Note que muitas bibliotecas não tiveram nenhuma release lançada ainda: para usá-las será necessário baixar a "nightly build" (veja links).

Taglibs suportadas

A seguir, apresentaremos uma breve descrição das mais interessantes taglibs do projeto, fornecendo exemplos para algumas de suas principais tags. Veja também o quadro “Taglibs no limbo” para informações sobre taglibs fora da categoria supported.

Standard

A taglib Standard é a principal do Jakarta Taglibs, pois se trata da implementação de referência da JSTL. Atualmente, são mantidas duas séries: Standard-1.1 e Standard-1.0 (que são implementações da JSTL 1.1 e da JSTL 1.0, respectivamente). As últimas versões foram liberadas em janeiro de 2004. Desde então foram corrigidos alguns bugs, mas não o suficiente para justificar  novas releases.

 

Nota: Não houve mudanças significativas especificação da JSTL desde o último artigo publicado sobre o assunto (Edição 9). Entretanto, muitas mudanças estão por vir. No final de abril, foi lançada a JSR-244, a especificação “guarda-chuva” da nova plataforma J2EE 1.5. Como de praxe, ela definirá as APIs e JSRs componentes, e entre estas, estará uma nova especificação para a JSTL. Porém, ainda não está definido se será criada uma nova JSR ou apenas uma extensão à especificação atual.

Benchmark

A taglib Benchmark permite medir o tempo de execução de trechos de código JSP. O trecho a ser analisado é colocado no corpo da tag <benchmark:duration>. O exemplo a seguir calcula o tempo gasto nos dois tipos de include JSP (dinâmico e estático) de um cabeçalho que tem apenas uma linha de HTML, sem código JSP:

 

<%@ taglib prefix="benchmark"

    uri="http://jakarta.apache.org/taglibs/benchmark-1.0" %>

 

Tempo gasto usando include dinâmico:

<benchmark:duration output="false">

  <jsp:include page="cabecalho.jsp"/>

</benchmark:duration>

ms

<br>

Tempo gasto usando include estático:

<benchmark:duration output="false">

  <%@ include file="cabecalho.jsp" %>

</benchmark:duration>

ms

 

Este é o resultado:

 

Tempo gasto usando include dinâmico: 3001 ms
Tempo gasto usando include estático: 0 ms

 

 

Nota: Neste exemplo, o tempo gasto no include estático é praticamente nulo (na verdade, tão pequeno que é mostrado como zero). Isso porque o conteúdo de cabecalho.jsp é apenas uma linha de HTML (que quando compilada transforma-se em uma chamada a out.println(...)). Já no exemplo de include dinâmico, gasta-se a maior parte do tempo na requisição à página cabecalho.jsp. Caso o conteúdo desse JSP fosse mais complexo, a diferença de tempo não seria tão acentuada.

 

Cache

Uma das técnicas mais usadas para aumentar a performance de aplicações é o uso de caches. Um cache pode ser usado em diversos níveis, por exemplo para armazenar o resultado de consultas a um banco de dados, ou para otimizar lookups freqüentes em serviços de nomes. Caches também podem agilizar código JSP, e é esta a funcionalidade da taglib Cache. O mecanismo é o seguinte:

·        Delimita-se o trecho a ser posto em cache com a tag <cache:cache>, que recebe como atributos o nome do cache a ser usado (o nome é necessário porque a mesma aplicação web pode criar vários caches), além do escopo onde será armazenado (page, request, session ou application, sendo application o padrão), e uma chave para identificar o trecho sendo armazenado no cache.

·            Na primeira vez que a tag <cache:cache> é acessada, o código JSP no seu corpo é executado normalmente e o resultado da execução (isto é, o código HTML/JavaScript/etc. enviado ao browser) é armazenado no cache.

·            Nos acessos subseqüentes, a tag verifica se o trecho de código já está em cache. Se estiver, exibe seu conteúdo; caso contrário, executa o corpo da tag e armazena em cache o resultado.

 

Nota: Um trecho de código é automaticamente removido do cache após um intervalo de tempo determinado, ou manualmente, usando <cache:invalidate>. Os caches são criados com o default de 64kb de tamanho e cinco minutos de vida para cada trecho armazenado. Essas definições podem ser alteradas chamando métodos estáticos da classe org.apache.taglibs.cache.CacheUtil.

 

A Listagem 1 usa as taglibs Cache e Benchmark para demonstrar o mecanismo de cache. Nesse exemplo primeiro teste demora vários segundos, pois o trecho ainda não estava em cache; o segundo teste retorna 0, pois nele foi usado o valor armazenado; e o terceiro volta a demorar, pois o tempo de vida do código em cache já havia expirado.

 

Nota: Como a biblioteca Cache suporta o uso de expressões EL em seus atributos, ela requer a presença do arquivo standard.jar em WEB-INF/lib (mesmo em um container compatível com JSP 2.0).

IO

A biblioteca IO inclui tags para a realização de operações de entrada e saída, principalmente requisições remotas usando protocolos como HTTP, HTTPS, XML-RPC e SOAP. A tag <io:request> tem funcionamento semelhante à tag <c:include> da JSTL: ela faz a inclusão do conteúdo de páginas localizadas fora da aplicação, usando o método GET do HTTP.

As demais tags vão além dos recursos oferecidos pela JSTL. A tag <io:http>, por exemplo, pode ser usada para fazer um POST:

 

<io:http url="http://site.com.br/login" action="POST"/>

  <io:param name="nome" value="felipe"/>

  <io:param name="senha" value="1234"/>

</io:http>

 

Outra tag interessante é <io:soap>, que permite a chamada de métodos de web services. O exemplo seguinte usa essa tag para traduzir um texto usando o web service BabelFish:

 

<%@ taglib prefix="io"

    uri="http://jakarta.apache.org/taglibs/io-1.0" %>

 

<io:soap

    url="http://services.xmethods.net:80/perl/soaplite.cgi"

    SOAPAction="urn:xmethodsBabelFish#BabelFish">

 <io:body>

  <SOAP-ENV:Envelope

    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

...

Quer ler esse conteúdo completo? Tenha acesso completo