Clique aqui para ler todos os artigos desta edição
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/"
...