JSTL.in.action.tradução

63
Apostila de JSTL Tradução Resumida do Livro JSTL in Action de Shawn Bayern Prof. Carlos Ribeiro

Transcript of JSTL.in.action.tradução

Apostila de JSTL

Tradução Resumida doLivro JSTL in Action

de Shawn Bayern

Prof. Carlos Ribeiro

2

Índice1. A LINGUAGEM DE EXPRESSÕES....................................................................................................................... 4

1.1 Expressões e o tag <c:out> ............................................................................................................................. 41.1.1 Qual a Aparência de uma Expressão............................................................................................................ 51.1.2 Onde Expressões Funcionam ....................................................................................................................... 51.1.3 Valor Default em <c:out> ........................................................................................................................ 51.1.4 Caracteres Especiais e <c:out> ................................................................................................................ 6

1.2 Variáveis com Escopo e a Linguagem de Expressões......................................................................................... 61.2.1 Sintaxe Básica para Acessar Variáveis com Escopo .................................................................................... 61.2.2 Operações envolvendo Variáveis ................................................................................................................. 7

1.3 Parâmetros de Requisição e a Linguagem de Expressões ................................................................................... 71.4 Expressões mais Poderosas ................................................................................................................................. 7

1.4.1 Diferentes formas de Acessar Propriedades ................................................................................................. 71.4.2 Acessando Outros Dados Através da Linguagem de Expressões................................................................. 8

2. CONTROLANDO O FLUXO COM CONDIÇÕES .............................................................................................. 132.1 Condições Sim-Não com <c:if> ................................................................................................................... 13

2.1.1 A Sintaxe Básica de <c:if> .................................................................................................................... 132.1.2 Utilizando <c:if> com Tags HTML....................................................................................................... 132.1.3 Tags <c:if> Aninhados .......................................................................................................................... 142.1.4 Os Atributos var e scope ....................................................................................................................... 14

2.2 Condições Mutuamente Exclusivas .................................................................................................................. 15

3. CONTROLANDO O FLUXO COM ITERAÇÕES ............................................................................................... 163.1 A Iteração de Propósito Geral com <c:forEach> ........................................................................................ 163.2 Iteragindo sobre Strings com <c:forTokens>............................................................................................. 17

3.2.1 Como JSLT Efetua o Parse de Strings ....................................................................................................... 173.3 Iteração Avançada com <c:forEach> e <c:forTokens> ....................................................................... 18

3.3.1 Efetuando um Loop Sobre Parte de uma Coleção...................................................................................... 183.3.2 Efetuando um Loop Sobre Números .......................................................................................................... 183.3.3 Status do Loop ........................................................................................................................................... 19

3.4 Um Exemplo de Loop ....................................................................................................................................... 193.4.1 Entendendo o Exemplo .............................................................................................................................. 203.4.2 Utilizando varStatus no Exemplo............................................................................................................... 22

4. IMPORTANDO TEXTO........................................................................................................................................ 234.1 Incluindo Texto com o Tag <c:import> ............................................................................................................ 23

4.1.1 Recuperando Dados de URLs .................................................................................................................... 234.1.2 Salvando Informações para Uso Posterior ................................................................................................. 244.1.3 Efetuando Comunicação com Páginas Importadas .................................................................................... 244.1.4 Exemplos de Import ................................................................................................................................... 26

4.2 Redirecionando com <c:redirect> ............................................................................................................ 284.3 Formatando URLs com <c:url> ................................................................................................................... 28

4.3.1 Formatando URLs com <c:url> ............................................................................................................ 284.3.2 Porque Utilizar <c:url> ......................................................................................................................... 29

5. PÁGINAS COM ACESSO A BANCOS DE DADOS ........................................................................................... 305.1 Quando Utilizar o Suporte JSTL a Bancos de Dados........................................................................................ 305.2 Criando uma Conexão de Banco de Dados com <sql:setDataSource> ................................................. 30

5.2.1 Cuidado com <sql:setDataSource> ................................................................................................ 325.3 Executando Queries com <sql:query> ....................................................................................................... 32

5.3.1 Executando uma Query de Banco de Dados .............................................................................................. 335.3.2 Lendo o Resultado de uma Query .............................................................................................................. 33

3

5.3.3 Limitando o Tamanho do Resultado de uma Query................................................................................... 365.4 Modificando Dados com <sql:update> ..................................................................................................... 36

5.4.1 Uso Simplificado do Tag <sql:update> .............................................................................................. 375.4.2 Medindo o Efeito de um Tag <sql:update> ........................................................................................ 37

5.5 Utilizando <sql:param> com Queries Ajustáveis........................................................................................ 385.5.1 Queries Modelos (Templates) .................................................................................................................... 385.5.2 Utilizando <sql:param>........................................................................................................................ 385.5.3 Parâmetros do Tipo Date com <sql:dateParam> ............................................................................... 40

5.6 Gerenciando Transações com <sql:transaction> .................................................................................. 405.6.1 O Tag <sql:transaction>............................................................................................................................. 405.6.2 Níveis de Isolamento.................................................................................................................................. 42

6. FORMATAÇÃO..................................................................................................................................................... 436.1 Imprimindo Números com <fmt:formatNumber> .................................................................................... 43

6.1.1 Uso Básico de <fmt:formatNumber>................................................................................................. 436.1.2 Diferentes Formas de Imprimir um Número .............................................................................................. 446.1.3 Armazenando um Número em vez de Imprimi-lo...................................................................................... 446.1.4 Imprimindo Diferentes Tipos de Números................................................................................................. 446.1.5 Agupamento de Milhar .............................................................................................................................. 446.1.6 Controlando Quantos Dígitos Devem Ser Impressos ................................................................................. 446.1.7 Utilizando Padrões ..................................................................................................................................... 45

6.2 Imprimindo Datas ............................................................................................................................................. 456.2.1 Utilizando Padrões ..................................................................................................................................... 46

6.3 Lendo Números com <fmt:parseNumber> ............................................................................................... 466.3.1 Porque Efetuar o Parse de Números........................................................................................................... 476.3.2 Como <fmt:parseNumber> Funciona por Default ............................................................................. 476.3.3 Modificando as Regras de Parse de <fmt:parseNumber> .................................................................. 48

6.4 Lendo Datas com <fmt:parseDate>.......................................................................................................... 496.4.1 Como <fmt:parseDate> Funciona por Default .................................................................................. 506.4.2 Modificando Como <fmt:parseDate> Efetua o Parse de Datas ......................................................... 50

7. TAREFAS COMUNS............................................................................................................................................. 517.1 Tratando Parâmetros do tipo CheckBox ........................................................................................................... 51

7.1.1 O Formulário HTML.................................................................................................................................. 517.1.2 Um Manipulador de CheckBox Simples.................................................................................................... 527.1.3 Tratando Alguns CheckBoxes de Forma Especial ..................................................................................... 53

7.2 Lendo Datas ...................................................................................................................................................... 547.2.1 O Formulário HTML.................................................................................................................................. 547.2.2 Tratando o Formulário e Lendo a Data ...................................................................................................... 55

7.3 Tratando Erros................................................................................................................................................... 567.3.1 Capturando Erros com <c:catch> ......................................................................................................... 567.3.2 Enviando Erros para uma Página de Erro .................................................................................................. 58

7.4 Validando Entrada de Dados............................................................................................................................. 597.4.1 Diferentes Tipos de Validação de Formulários .......................................................................................... 597.4.2 Tarefas Relacionadas à Validação de um Formulário ................................................................................ 59

4

1. A LINGUAGEM DE EXPRESSÕES

JSTL utiliza uma linguagem denominada uma expression language para simplificar o acesso àinformação. Antes de JSTL era necessário conhecer Java para produzir determinadas páginasJSP. Por exemplo, para se descobrir o que um usuário digitou em uma caixa de textodenominada “nomeusuario” era necessário programar o seguinte código:

<%= request.getParameter("nomeusuario") %>

A linguagem de expressões JSTL torna bem mais simples a construção de páginas.

1.1 Expressões e o tag <c:out>

O tag <c:out> nos permite imprimir o resultado de uma expressão. O tag <c:out> possui amesma funcionalidade de uma expressão (<%= conteúdo %>) JSP. Quando tags JSTLaparecem em uma página, eles não são enviados para o browser. A classe Java que implementa otag customizado lê os atributos do tag e produz um efeito específico. Neste caso, simplesmenteimprime um texto.

Os atributos de <c:out> são:

Atributo Descrição Obrigatório Defaultvalue A expressão (na linguagem de expressões

JSTL) a ser calculadaSim Nenhum

default A expressão a ser calculada se valuefalhar

Não Nenhum

escapeXml Se algum caracter deve ser substituído(scaped); Por exemplo, para imprimir ocaracter & como &amp;.

Não True

Por default, <c:out> imprime o que quer que apareça no seu atributo value.

Por exemplo:

<c:out value="Alô Mundo!"/>

Naturalmente, isto só faz sentido se o atributo value contiver uma expressão na linguagem deexpressões JSTL.

5

1.1.1 Qual a Aparência de uma Expressão

Uma expressão começa com ${ e termina com }; Tudo o que aparece no meio é tratado comouma expressão. Exemplo:

<c:out value="${1 + 2}"/>

Neste caso será impresso o valor 3. Todos os tags JSTL funcionam assim. Na maioria dos casos,quando uma expressão aparece em um atributo de um tag JSTL, esta expressão é calculada. Oresultado desta avaliação é fornecido ao tag como o valor do atributo.

1.1.2 Onde Expressões Funcionam

Em JSTL 1.0, expressões possuem um significado especial apenas dentro de atributos de tagsJSTL.

Não se pode escrever:

<p>Oi ${nomeusuario}</p>

Expressões JSTL também não possuem significado especial como valor de um atributo de umtag HTML.

<a href="${link}" />

Neste caso o texto ${link} não é interpretado como uma expressão JSTL.

1.1.3 Valor Default em <c:out>

No exemplo abaixo, se a expressão falhar – por exemplo, no caso do valor da variávelnomeusuario não ser encontrado – será impresso ninguem.

<c:out value="${nomeusuario}" default="Ninguem"/>

Esta é uma outra forma de especificar um valor default:

<c:out value="${nomeusuario}"/> Ninguem</c:out>

6

1.1.4 Caracteres Especiais e <c:out>

Por default, o tag <c:out> com caracteres com significados especiais em HTML e XML sãosubstituídos (scaped) pelas entities references correspondentes. Por exemplo, se uma variávelpossui o valor <o>, ao ser impressa com o tag </c:out>, será produzido o seguinte resultado:

&lt;o&gt;

Logo, um browser HTML irá exibir o texto <o>. Se <c:out> não fizesse estas substituições, obrowser receberia os caracteres <o> - sem as substituições – o que faria o browser interpretarestes caracteres como um tag HTML desconhecido.

Normalmente este mecanismo de substituição dos caracteres especiais funciona exatamentecomo se deseja. Como este mecanismo também substitui as aspas simples e as aspas duplas queocorrem dentro de <c:out>, pode-se utilizar com segurança <c:out> como valor de umatributo de um tag HTML, conforme vem abaixo:

<input type="text" name="usuario" value="<c:out value="${param.usuario}"/>" />

Se esta substituição não ocorresse automaticamente, a linha acima provocaria um erro.

Em alguns casos raros, você pode desejar desligar este mecanismo de substituição de caracteresespeciais de <c:out>. Para obter este efeito basta designar o valor false para o atributoescapeXml.

<c:out value="${texto}" escapeXml="false"/>

Isto pode ser útil caso se deseje acrescentar ao texto tags HTML como <b>, <i>, etc.

1.2 Variáveis com Escopo e a Linguagem de Expressões

1.2.1 Sintaxe Básica para Acessar Variáveis com Escopo

Em certo sentido, a linguagem de expressões JSTL lida com variáveis com escopo. Umaexpressão como ${usuario} significa “ a variável com escopo denominada usuario”. Quandoum nome de uma variável com escopo aparece sozinho em uma expressão – como em${usuario} – isto faz com que a linguagem de expressão procure por esta variável em todos osescopos possíveis, na seguinte ordem: página, requisição, sessão e aplicação.

7

Como recuperar o valor de uma variável em determinado escopo:

Exemplo de Expressão Significado${pageScope.usuario} Variável usuario em escopo de página.${requestScope.usuario} Variável usuario em escopo de

requisição.${sessionScope.usuario} Variável usuario em escopo de sessão.${applicationScope.usuario} Variável usuario em escopo de aplicação.

Para uma página poder imprimir o nome do usuário armazenado no objeto sessão:

<c:out value="${session.usuario}"/>

1.2.2 Operações envolvendo Variáveis

JSTL suporta os seguintes operadores matemáticos em expressões:

Operador Descrição Exemplo+ Adição ${10 + 2}- Subtração ${10 - 2}* Multiplicação ${10 * 2}/ ou div Divisão ${10 / 2}% ou mod Resto ${10 % 2}

1.3 Parâmetros de Requisição e a Linguagem de Expressões

Para apontar para um parâmetro de requisição utilizando a linguagem de expressão, utilizesimplesmente ${param.nome}. Se um parâmetro de requisição possui diversos valores seránecessário utilizar ${paramValues.nome} em vez de ${param.nome}. UtilizandoparamValues lhe permite recuperar uma coleção de todos os parâmetros com um determinadonome.

1.4 Expressões mais Poderosas

1.4.1 Diferentes formas de Acessar Propriedades

Vimos anteriormente que é possível utilizar o ponto (.) para acessar um membro de uma coleçãonão ordenada. Por exemplo, para obter a propriedade telefone da variável usuario é possívelescrever ${usuario.telefone}.

Também é possível acessar propriedades de coleções não ordenadas utilizando a sintaxe comcolchetes ([]), assim como com listas ordenadas. A razão de JSTL utilizar duas sintaxes

8

diferentes é porque Java Script também utiliza estas sintaxes. Por outro lado, se uma propriedadeutiliza um caracter especial como ponto ou hífem, pode-se utilizar a notação com colchetes. porexemplo, uma propriedade denominada meu-endereco poderia ser acessada assim:${usuario[“meu-endereco”]}. Observe as aspas em torno do nome da propriedade. Sevocê não utilizar aspas com colchetes, ocorrerá o seguinte:

${usuario.telefone} – sempre recupera o telefone do usuário.${usuario[info]} – esta expressão primeiramente procura pelo valor da variável info paraem seguida utilizar seu valor para obter uma propriedade de usuario.

1.4.2 Acessando Outros Dados Através da Linguagem de Expressões

Cookies

JSTL não nos permite criar cookies, uma vez que esta é uma tarefa do código Java sendoexecutado em um servidor. No entanto, se você sabe que existe um cookie denominadocorPreferida, é possível acessá-lo através da expressão ${cookie.corPreferida}.

Cabeçalhos (Headers)

Cabeçalhos são dados que servidores web e browsers utilizam para se comunicar. Os cabeçalhoscontêm informações como: o tipo do browser, informações sobre a localização da máquinacliente, etc. Browsers enviam informações sobre seu fabricante e modelo para os servidoresatravés de um cabeçalho denominado User-Agent. Para acessar esta informação pode serutilizada a expressão:

${header["User-Agent"]}

Parâmetros de Inicialização

Assim como variáveis com escopo, os programadores de código java (back-end) podem designarinformações denominadas context initialization parameters.

Para acessar um parâmetro de inicialização utilize a seguinte sintaxe:

${initParam.headerUrl}

9

PageContext

A variável que pode ser acessada com ${pageContext} permite que você acesse algumasinformações detalhadas sobre o ambiente corrente da página.

Expressão Descrição Exemplo de Valor${pageContext.request.authType}

O tipo de autenticaçãoutilizado pela página,se aplicável

BASIC

${pageContext.request.remoteUser}

O ID do usuário, se oservidor efetuaautenticação

djdavis

${pageContext.request.contextPath}

O nome da sua WebApplication

/jstl

${pageContext.request.cookies}

Uma coleção ordenadacontendo todos oscookies recebidos pelapágina

n/a

${pageContext.request.method}

O método HTTPutilizado para enviara requisição

GET

${pageContext.request.queryString}

O query string dapágina

p1=valor1&p2=valor2

${pageContext.request.requestURL}

O URL utilizado paraacessar a página

http://server/app/pagina.jsp

${pageContext.session.new}

true, se a sessão énova; false, casocontrário

true

${pageContext.ServletContext.serverInfo}

Informação sobre seucontainer JSP

Apache Tomcat/5.0.0

${pageContext.exception.message}

Para uma páginadesignada comoerrorPage, umadescrição do erro queocorreu.

“Algo muito ruimaconteceu”

Comparações

Você pode utilizar a linguagem de expressões para produzir valores boleanos, como no exemploabaixo:

${2 == 2}

Os operadores possíveis são: == ou eq; != ou ne; < ou lt; > ou gt; <= ou le; >= ouge.

10

Para comparar valores de variáveis deve ser utilizada a seguinte sintaxe:

${usuario.peso gt usuario.qi}

Pode-se verificar se um parâmetro de requisição possui um determinado valor:

${param.mes eq "Maio"}

Verificando se uma Variável Existe

Pode-se utilizar a palavra-chave empty para determinar se um determinado parâmetro existe.

${empty param.mes}

será true apenas se o parâmetro mes não tiver sido especificado no formulário ou se seu valorfor um string vazio. Verificar .........

Operadores Boleanos e Parênteses

O operadores relacionais são: and, or e not ou &&, || e !.

Exemplos:

${(param.mes == 5) or (param.mes == 6 and param.dia == 25)}

${not empty param.mes}

Múltiplas Expressões

<c:out value="Oi ${usuario.primeironome} ${usuario.ultimonome}" />

embora a combinação abaixo produza o mesmo resultado:

Oi <c:out value="${usuario.primeironome}" /> <c:out value="${usuario.ultimonome}" />

Esta habilidade de utilizar múltiplas expressões é interessante em outros tags da biblioteca JSTL.

11

Salvando Dados com <c:set>

Muitos tags JSTL podem criar variávies com escopo. O mais básico é <c:set>.

Atributo Descrição Obrigatório Defaultvalue A expressão a ser calculada Não Conteúdo do corpovar O nome da variável com escopo Sim Nenhumscope O escopo da variável Não page

Os atributos var e scope são os únicos atributos de tags JSTL com os quais não se pode utilizarexpressões. Por exemplo, não se pode escrever: var=”${usuario}”. Este código criará umavariável com escopo chamada literalmente ${usuario}.

Exemplo de designação de valor a uma variável com escopo de página:

<c:set var="quatro" value="${3 + 1}" />

Para que esta variável tenha escopo de sessão será preciso fazer o seguinte:

<c:set var="quatro" scope="session" value="${3 + 1}" />

Utilizando o Corpo do Tag

Se você escrever um tag <c:set> sem um atributo value, será atribuído à variável o valor queestiver no corpo do tag. Todo o espaço em branco – no início e no final do corpo – é removido.

Quando <c:set> é Útil

O tag <c:set> é útil, em primeiro lugar, quando desejamos avaliar alguma coisa uma única vez,para que possamos reutilizá-la diversas vezes.

Um outro uso seria:

<c:set var="email" scope="session" value="${param.email}" />

Neste caso, outras páginas na mesma sessão do usuário poderão referenciar o email assim:

${sessionScope.email}

12

Removendo Dados com <c:remove>

Atributos do tag <c:remove>:

Atributo Descrição Obrigatório Defaultvar O nome da variável com escopo a

removerSim Nenhum

scope O escopo da variável a serremovida

Não qualquer

Exemplo:

<c:remove var="email" scope="session" />

Quando o scope não é especificado todos os escopos são pesquisados, sendo removida a variávelquando ela for encontrada em um dos quatro escopos possíveis. Se a variável não for encontrada,nada acontecerá.

13

2. CONTROLANDO O FLUXO COM CONDIÇÕES

2.1 Condições Sim-Não com <c:if>

2.1.1 A Sintaxe Básica de <c:if>

Atributos do tag <c:if>:

Atributo Descrição Obrigatório Defaulttest Condição a ser avaliada. Se true,

processa o corpo, caso contrário,não processa.

Sim Nenhum

var Nome do atributo que receberá umvalor boleano

Não Nenhum

scope Escopo do atributo que recebe ovalor boleano

Não page

O atributo test do tag <c:if> aceita qualquer expressão boleana:

<c:if test="${usuario.niveleducacional == 'doutorado'}"> Dr.</c:if>

<c:out value="${usuario.nome}"/>

Neste caso será impresso o nome do usuário precedido do texto “Dr.”, caso se trate de um doutor.

2.1.2 Utilizando <c:if> com Tags HTML

Pode-se utilizar o tag <c:if> em qualquer lugar de uma página HTML.

Exemplo:

<font size="2" <c:if test="${usuario.niveleducacional == 'doutorado'}"> color="red" </c:if>><c:out value="${usuario.nome}"/></font>

14

Caso o nível educacional seja diferente de 'doutorado' obteremos:

<font size="2"> Nome</font>

2.1.3 Tags <c:if> Aninhados

Exemplo:

<c:if test="${erro1 or erro2}"> <ul> <c:if test="${erro1}"> <li> Ocorreu o erro 1. </c:if> <c:if test="${erro2}"> <li> Ocorreu o erro 2. </c:if> </ul></c:if>

2.1.4 Os Atributos var e scope

Estes atributos são utilizados para criar e expor uma variável com escopo que outros tags podemutilizar. Neste caso, no entanto, esta variável é boleana.

Exemplo:

<c:if test="${sessionScope.flags.errors.serious.erro1}" var=”erro1”> Salva a variável Um erro sério ocorreu.</c:if>[ ... um corpo de página grande ...]<c:if test="${erro1}"> Usa a variável Desde que um erro sério ocorreu, seus dados não foram slavos.</c:if>

Neste exemplo, quando o primeiro tag é alcançado, a expressão no atributo test é avaliada, e oresultado é armazenado em uma variável com escopo de página denominada erro1. Destemomento em diante o valor desta variável não mudará, mesmo que o valor desessionScope.flags.errors.serious.erro1 seja alterado. Se você utilizar o tag<c:if> apenas para salvar o valor da variável definida em var, neste caso <c:if> não precisaráter um corpo, conforme vem abaixo:

<c:if test="${sessionScope.flags.errors.serious.erro1}" var="erro1"/>

15

Outros tags, mais adiante na página poderão utilizar a variável erro1.

2.2 Condições Mutuamente Exclusivas

JSTL suporta condições mutuamente exclusivas através de três tags: <c:choose>, <c:when>, e<c:otherwise>.

Exemplo: Neste exemplo apenas uma das quatro mensagens será exibida.

<c:choose> <c:when test="${erro1}"> <li>Ocorreu o erro 1.</li> </c:when> <c:when test="${erro2}"> <li>Ocorreu o erro 2.</li> </c:when> <c:when test="${erro3}"> <li>Ocorreu o erro 3.</li> </c:when> <c:otherwise> <li>Nenhum erro ocorreu.</li> </c:otherwise></c:choose>

O tag <c:when> não possui o atributo var, mas ele pode utilizar uma variável boleana criadaanteriormente por um tag <c:if>.

16

3. CONTROLANDO O FLUXO COM ITERAÇÕES

3.1 A Iteração de Propósito Geral com <c:forEach>

O tag <c:forEach> é um tag JSTL para controle de loops de propósito geral. Como vimosanteriormente, a linguagem de expressões pode retornar uma coleção de itens. O tag<c:forEach> nos permite percorrer praticamente qualquer coleção de itens que a linguagem deexpressões é capaz de retornar.

Para cada item em uma coleção, o corpo do tag <c:forEach> será processado uma vez, e o itemcorrente será exposto através de uma variável de página com escopo cujo nome é especificadopelo atributo var de <c:forEach>.

Exemplo:

<p>Lamento, mas você possui as seguintes doenças:<p><ul><c:forEach items="${usuario.condicoesDeSaude}" var="doenca"> <li><c:out value="${doenca}"/></li></c:forEach></ul>

Este tag <c:forEach> efetua um loop sobre todos os itens da propriedade condicoesDeSaudeda variável usuario.

Os atributos do tag <forEach> para iteração básica vem abaixo:

Atributos Descrição Obrigatório Defaultitems Uma coleção sobre a qual ocorrerá a

iteração.Não Nenhum

var Nome do atributo que exporá o itemcorrente.

Não Nenhum

17

3.2 Iteragindo sobre Strings com <c:forTokens>

O tag <c:forTokens> efetua um loop sobre tokens (substrings de um string maior delimitadospor um caracter específico) .

Os atributos do tag <forTokens> para iteração básica vem abaixo:

Atributos Descrição Obrigatório Defaultitems String de entrada sobre o qual

ocorrerá a iteraçãoNão Nenhum

delims Caracter delimitador que separa ostokens

var Nome do atributo que expõe o tokencorrente

Não Nenhum

Exemplo:

<c:forTokens items="a;b;c;d" delims=";" var="corrente"> <li><c:out value="${corrente}"/></li></c:forTokens>

Produzirá a seguinte saída:

<li>a</li><li>b</li><li>c</li><li>d</li>

3.2.1 Como JSLT Efetua o Parse de Strings

Diversos caracteres delimitadores consecutivos são tratados como um único delimitador.

<c:forTokens items="a;;b;;c;;d" delims=";" var="corrente"> <li><c:out value="${corrente}"/></li></c:forTokens>

Logo, este código produz a mesma lista exibida acima.

18

3.3 Iteração Avançada com <c:forEach> e <c:forTokens>

3.3.1 Efetuando um Loop Sobre Parte de uma Coleção

Ambos <c:forEach> e <c:forTokens> aceitam 3 parâmetros opcionais para suportar o loopsobre parte de uma coleção.

Atributos Descrição Obrigatório Defaultbegin O item que inicia o loop.

(0=primeiro; 1=segundo, etc.)Não 0

end O item que encerra o loop. Não Último itemstep Passo da iteração. Não 1

Exemplo:

<c:forTokens items="a;b;c;d;e" delims=";" var="letra" begin="2" end="4"> <li><c:out value="${letra}"/></li></c:forTokens>

Esta iteração irá exibir as letras c, d, e e – os tokens com índices 2,3, e 4.

3.3.2 Efetuando um Loop Sobre Números

Se você não especificar o atributo items (que é opcional), então os atributos begin e end deverãoestar presentes.

Exemplo:

<c:forEach begin="1" end="5" var="corrente"> <c:out value="${corrente}"/></c:forEach>

O exemplo acima produzirá a seguinte saída:

1 2 3 4 5

Em <c:forTokens> o atributo items é obrigatório. Se você deseja iteragir sobre número,utilize apenas <c:forEach>.

Como a maioria dos atributos JSLT, os atributos begin e end aceitam expressões.

19

3.3.3 Status do Loop

Assim como o atributo var em <c:forEach> e <c:forTokens>, o atributo varStatus permiteque você crie uma variável com escopo que pode ser acessada dentro do loop. Se var=”corrente”,o item corrente é exposto dentro do loop através de uma variável com escopo de páginadenominada corrente. Da mesma forma, se varStatus=”s”, é criada uma variável comescopo de página denominada “s” que contém informações sobre a iteração corrente. A tabelaabaixo mostra propriedades úteis desta variável.

Propriedades Tipo Descriçãoindex número O índice do ítem corrente da coleção.count número A posição da volta corrente na iteração,

começando com 1.first boolean Se a iteração atual é a primeira.last boolean Se a iteração atual é a última.

Exemplo:

<c:forTokens items="a;b;c;d;e" delims=";" var="letra" begin="0" end="4" step="2"> <c:out value="${letra}"/></c:forTokens>

Letra 'a' Letra 'c' Letra 'e'index = 0 index = 2 index = 4count = 1 count = 2 count = 3first = true first = false first = falselast = false last = false last = true

3.4 Um Exemplo de Loop

Vamos escrever uma página exemplo que permita o usuário paginar através de informações.

Como ainda não vimos como recuperar informações de arquivos XML e de bancos de dados, nãopoderemos exibir dados reais. Logo, utilizaremos o tag <c:forEach> para gerar númerosautomaticamente.

20

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

<c:set var="totalDeItens" scope="session" value="100"/><c:set var="porPagina" scope="session" value="20"/>

<c:forEach var="inicioDaFaixa" begin="0" end="${totalDeItens - 1}" step="${porPagina}">

<a href="?inicio=<c:out value="${inicioDaFaixa}"/>"> [ <c:out value="${ inicioDaFaixa }"/> - <c:out value="${ inicioDaFaixa + porPagina - 1}"/> ] </a></c:forEach>

<c:forEach var="corrente" varStatus="status" begin="${param.inicio}" end="${param.inicio + porPagina - 1}"> <c:if test="${status.first}"> <ul> </c:if> <li><c:out value="${corrente}"/></li> <c:if test="${status.last}"> </ul> </c:if></c:forEach>

3.4.1 Entendendo o Exemplo

Dois tags <c:set> foram utilizados para configurar o comportamento da nossa página.Evidentemente estes valores poderiam ser designados através de parâmetros de requisição, ouatravés de um outro meio qualquer.

<c:set var="totalDeItens" scope="session" value="100"/><c:set var="porPagina" scope="session" value="20"/>

totalDeItens Representa o número total de itens que gostaríamos que o usuário fossecapaz de percorrer.

porPagina A quantidade de resultados que devem ser exibidos para o usuário de cadavez.

21

Agora podemos imprimir a seção no topo da página. Esta seção terá sempre a mesma aparência,independentemente da faixa escolhida pelo usuário. Estes dados dependem apenas de duasvariáveis que configuram o comportamento da nossa página: totalDeItens e porPagina.

<c:forEach var="inicioDaFaixa" begin="0" end="${totalDeItens - 1}" step="${porPagina}">

<a href="?inicio=<c:out value="${inicioDaFaixa}"/>"> [ <c:out value="${ inicioDaFaixa }"/> - <c:out value="${ inicioDaFaixa + porPagina - 1}"/> ] </a></c:forEach>

Observe que um link como

<a href="?inicio=20">

provoca o envio de uma requisição para a página corrente, contendo um parâmetro inicio como valor 20. Logo, quando o usuário seleciona uma faixa específica, o parâmetro inicio iráindicar o início da faixa que o usuário deseja. Este parâmetro pode ser acessado através daexpressão ${param.inicio}, conforme vem no código abaixo.

<c:forEach var="corrente" varStatus="status" begin="${param.inicio}" end="${param.inicio + porPagina - 1}"> <c:if test="${status.first}"> <ul> </c:if> <li><c:out value="${corrente}"/></li> <c:if test="${status.last}"> </ul> </c:if></c:forEach>

Quando nenhuma faixa é selecionada – isto é, se o parâmetro inicio é vazio – começamos com onúmero 0. Isto acontece em função do valor default definido para o parâmetro begin, quando ovalor deste parâmetro não existe.

22

3.4.2 Utilizando varStatus no Exemplo

Com o código abaixo, as linhas ímpares serão impressas com um tipo de letra na cor vermelha.

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

<c:set var="totalDeItens" scope="session" value="100"/><c:set var="porPagina" scope="session" value="20"/>

<c:forEach var="inicioDaFaixa" begin="0" end="${totalDeItens - 1}" step="${porPagina}">

<a href="?inicio=<c:out value="${inicioDaFaixa}"/>"> [ <c:out value="${ inicioDaFaixa }"/> - <c:out value="${ inicioDaFaixa + porPagina - 1}"/> ] </a></c:forEach>

<c:forEach var="corrente" varStatus="status" begin="${param.inicio}" end="${param.inicio + porPagina - 1}"> <c:if test="${status.first}"> <ul> </c:if> <c:if test="${status.count % 2 == 0}"> <font color=”red”> </c:if> <li><c:out value="${corrente}"/></li> <c:if test="${status.count % 2 == 0}"> </font> </c:if> <c:if test="${status.last}"> </ul> </c:if></c:forEach>

23

4. IMPORTANDO TEXTO

4.1 Incluindo Texto com o Tag <c:import>

Para recuperar conteúdo de uma página JSP local ou proveniente de outro servidor, você podeutilizar o tag <c:import>. Às vezes você deseja apenas imprimir a informação recuperada, mas<c:import> também permite que você armazene o texto recuperado em uma variável comescopo em vez de impri-la.

A tabela abaixo mostra os atributos do tag <c:import>:

Atributos Descrição Obrigatório Defaulturl O url que se deseja recuperar e

importar na página.Sim Nenhum

context / seguida do nome de umaaplicação web local.

Não Contextocorrente

var Nome do atributo para expor oconteúdo String do url.

Não Nenhum

scope Escopo do atributo que irá exporo conteúdo String do url.

Não Page

Exemplo de <c:import> com um caminho relativo para o url:

<c:import url="cabecalho.html">

URLs relativos em JSTL funcionam da mesma forma como URLs relativos em HTML. URLsque começam por uma / possuem um significado diferente para tags JSTL do seu significado emHTML.

Em HTML, se você utilizar o tag

<img src="/imagens/foto.jpg"/>

então o arquivo foto.jpg virá do diretório imagens na raiz de todo o servidor web. Este diretórioarmazena imagens que são compartilhadas por páginas estáticas e dinâmicas.

Por outro lado, se utilizarmos este mesmo URL como entrada de um tag JSTL, a imagem seráprocurada no diretório imagens na raiz da aplicação web de página JSP. Observe que um servidorweb geralmente possui diversas aplicações web.

4.1.1 Recuperando Dados de URLs

Para importar uma página residente no diretório corrente:

<c:import url="cabecalho.html"/>

24

Supondo que a página atual, source.jsp, está em um diretório denominado source e que apágina target.jsp está em um diretório denominado target, ambos os diretórios na raiz daaplicação web corrente, para source.jsp importar target.jsp seria preciso:

<c:import url="/target/target.jsp"/>

Agora suponha que target.jsp esteja localizada em um servidor web diferente. Neste caso, a únicaforma de recuperar o arquivo utilizando <c:import> é através do seguinte URL:

<c:import url="http://www.servidor.com/diretorio/target.jsp"/>

Importando de Outra Aplicação Web

É possível recuperar arquivos de outra aplicação web especificando o nome da outra aplicaçãoweb utilizando o atributo context do tag <c:import>.

<c:import context="/outra" url="/diretorio/target.jsp"/>

4.1.2 Salvando Informações para Uso Posterior

Por default, <c:import> recupera informação de um URL e a imprime imediatamente na suapágina. Isto é exatamente o que <jsp:include> faz, e na maioria das vezes é o que você deseja.

No entanto, você pode desejar importar uma página e incluir seu texto diversas vezes, conformevem abaixo:

<c:import url="http://legal.com/copyright-notice.html" var="copyright"/><c:out value="${copyright}"/>... Mais conteúdo ...<c:out value="${copyright}"/>

4.1.3 Efetuando Comunicação com Páginas Importadas

Às vezes não é suficiente apenas recuperar uma página. Se a página é gerada dinâmicamente,você pode desejar customizar sua saída. Primeiramente é possível utilizar o tag <c:param> paraenviar parâmetros de requisição para a página. E em segundo lugar, se você está importando umURL relativo para uma página da mesma aplicação, você pode utilizar os objetos request,session, e application para se comunicar com a página de destino. O escopo de página é oúnico não compartilhado. Além disso, quando se importa uma página de um mesmo containerJSP, todos os parâmetros de requisição da página de origem são passados automaticamente para apágina de destino.

25

O Tag <c:param>

O tag <c:param> é um tag filho opcional do tag <c:import> (e de alguns outros tags JSTL).Quando ele aparece ele diz para <c:import> para enviar um parâmetro de requisição para apágina que ele está carregando.

A tabela abaixo mostra os atributos do tag <c:param>:

Atributos Descrição Obrigatório Defaultname Nome do parâmetro Sim Nenhumvalue Valor do parâmetro Não Corpo

Exemplo: Como enviar um parâmetro para a página target.jsp.

<c:import url="http://www.servidor.net/aplicacao/target.jsp"/> <c:param name="param" value="valor"/></c:import>

Este código causa o envio de uma requisição HTTP do tipo GET, assim:

http://www.servidor.net/aplicacao/target.jsp?param=valor

Observações:

1. <c:param> permite o envio de simples parâmetros de comunicação, que possuem a formanome=valor. Parâmetros de requisição são flexíveis mas podem representar apenas texto esuportam comunicação em apenas um sentido (da origem para o destino).

2. Em contraste com os parâmetros de requisição, as variáveis com escopo – que podem seracessadas tanto pela origem como pelo destino de um tag <c:import> - podem incluirestruturas de dados arbitrárias. Elas suportam comunicação em dois sentidos, no entanto, sófuncionam quando a página de destino pertence à mesma aplicação web da origem.

26

4.1.4 Exemplos de Import

O exemplo abaixo mostra como padronizar a aparência dos cabeçalhos das páginas de umaaplicação através do uso de <c:import>.

Exemplo 1: Customização com <c:param>

Nosso exemplo utiliza três páginas:• pagina1.jsp – Uma primeira página exemplo.• pagina2.jsp – Uma segunda página exemplo.• cabecalho.jsp – Uma página JSP que imprime imformação de cabeçalho que é utilizada por

ambas as páginas.

Código de cabecalho.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %><table width="100%"> <tr> <td align="left" bgcolor="#888888"> <big><font color="#FFFFFF"> <c:out value="${param.titulo}"/> </font></big> </td> <td align="right"> <small> Exemplo de Aplicação com Import </small> </td> </tr></table><hr />

Código da pagina1.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %><html><body><c:import url="cabecalho.jsp"> <c:param name="titulo" value="Benvindo à Página 1"/></c:import>

<h4>Informações da Página 1</h4>

Texto da <b>Pagina 1</b>.

</body></html>

27

Código da pagina2.jsp:

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

<html><body><c:import url="cabecalho.jsp"> <c:param name="titulo" value="Bevindo à Página 2"/></c:import>

<font color="pink"> <h4>Informações da Página 2</h4> Esta é a <b>página 2</b>. <br/> Uma versão aboiolada da página 1.</font></body></html>

No exemplo abaixo, a página origem.jsp importa destino.jsp, e ambas enviam dados uma daoutra.

Exemplo 2: Customização sem <c:param>

Código de origem.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %><c:set var="entrada" scope="request" value="TEXTO DE ENTRADA" />Chamando destino.jsp...<hr /><c:import url="destino.jsp" /><hr />origem.jsp recebeu de volta: <c:out value="${requestScope.saida}" />

Código de destino.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>destino.jsp recebeu: <c:out value="${requestScope.entrada}" /><c:set var="saida" scope="request" value="TEXTO DE SAÍDA" />

28

4.2 Redirecionando com <c:redirect>

A tabela abaixo mostra os atributos do tag <c:redirect>:

Atributos Descrição Obrigatório Defaulturl URL que receberá o redirecionamento Sim Nenhumcontext / seguida do nome da aplicação web

localNão Contexto

Corrente

Exemplo 1: Redirecionando para uma página no mesmo diretório da origem.

<c:when test="${param.acao == 'comprar'}"> <c:redirect url="comprar.jsp"/></c:when>

Exemplo 2: Redirecionando para uma página em outro contexto, isto é, em outra aplicação:

<c:redirect context="/aplic" url="/comprar.jsp"/>

Quando o atributo context é fornecido, o valor de ambos os atributos (context e url) devemcomeçar com uma /.

Exemplo 3: Assim como o <c:import>, <c:redirect> também permite o uso de <c:param> dentrodele para enviar um parâmetro de requisição para a página que irá receber o redirecionamento:

<c:redirect context="/aplic" url="/comprar.jsp"/> <c:param name="estoque" value="IBM"/></c:redirect>

4.3 Formatando URLs com <c:url>

4.3.1 Formatando URLs com <c:url>

A função do tag <c:url> é imprimir um URL (ou armazená-lo em uma variável com escopo).

A tabela abaixo mostra os atributos do tag <c:url>:

Atributos Descrição Obrigatório Defaultvalue URL base para imprimir ou armazenar Sim Nenhumcontext / seguido do nome da aplicação web

localNão Contexto

correntevar Nome do atributo para expor o URL

finalNão Nenhum

scope Escopo do atributo para expor o URLfinal

Não Page

29

Assim como o <c:import> e <c:redirect>, também é possível incluir tags <c:param> nocorpo de um tag <c:url>.

É fácil utilizar <c:url>. Simplesmente o insira na sua página sempre que você quiser imprimirum URL. Com freqüência você desejará inserir <c:url> no meio de um tag HTML, como noexemplo abaixo:

<a href="<c:url value="comprar.jsp"> <c:param name="HD" value="Quantum"/> </c:url>">Compre um HD Quantum</a>

4.3.2 Porque Utilizar <c:url>

A primeira razão é pelo fato de ser mais fácil construir um link que passa parâmetros para apágina de destino. Duas outras razões são:

• Freqüentemente URLs necessitam ser reescritos para preservar a sessão de um usuário porvárias páginas. O tag <c:url> reescreve os URL (acrescentando o ID da sessão)automaticamente.

• Você pode desejar ajustar URLs relativos a contextos para que eles apontem para a raiz dasua aplicação web, e não para todo o servidor. Isto é, se um URL começa com uma /, ele émapeado para o diretório raiz da sua aplicação web, e não para a raiz do servidor. O tag<c:url> efetua estes ajustes para você.

Em tags HTML como o que vem abaixo, o URL referencia o diretório info na raiz do servidorweb:

<a href="/info/copyright.txt">Leia as informações de Copyright</a>

Mas em um tag JSTL como o que vem abaixo, o URL aponta para o diretório info abaixo da raizda sua aplicação web:

<c:import url="/info/copyright.txt">

Para que uma imagem seja localizada na pasta imagens da sua aplicação web utilize o tag<c:url>, assim:

<img src="<c:url value="/imagens/logo.gif"/>"/>

Você pode utilizar o atributo context do tag <c:url> para criar um URL para uma página emoutra aplicação web existente no seu container JSP.

O tag <c:url> também é útil quando se deseja salvar um URL (utilizando os atributos var escope) e utilizá-lo diversas vezes na sua aplicação.

30

5. PÁGINAS COM ACESSO A BANCOS DE DADOS

5.1 Quando Utilizar o Suporte JSTL a Bancos de Dados

A maioria das grandes aplicações para a Web baseadas em Java não são construídas inteiramentede páginas JSP. Muitas aplicações contêm servlets para tratar as requisições provenientes dosusuários. Servlets podem invocar diretamente qualquer lógica que uma aplicação necessite, eentão passar a requisição do usuário para uma página JSP. Em um ambiente como este páginasJSP apenas exibem informações formatadas.

Se uma aplicação utiliza páginas JSP apenas para exibir informações, e não para tratar lógica deaplicação, então estas páginas JSP não necessitam acessar bancos de dados. Se você estátrabalhando em um projeto onde os programadores Java tratam todos os acessos a bancos dedados, você não precisará utilizar os tags JSTL de acesso a banco de dados. Em vez disso, vocêirá provavelmente utilizar JavaBeans ou tags customizados construídos pelos programadores.Porque um componente de apresentação deveria conhecer onde os dados estão mantidos? Estaabordagem explica a popularidade de frameworks de aplicações baseados em servlets.

No entanto, para pequenas aplicações, protótipos, ou projetos onde você é o único desenvolvedor,os tags JSTL de acesso a banco de dados são bastante úteis.

5.2 Criando uma Conexão de Banco de Dados com <sql:setDataSource>

Os tags JSTL de acesso a bancos de dados necessitam saber qual banco de dados deve serutilizado, e o tag que fornece esta informação é o <sql:setDataSource>.

Em muitas aplicações grandes, o tag <sql:setDataSource> não é necessário, poisdesenvolvedores Java gerenciam todas as conexões de banco de dados. Estes desenvolvedorespodem designar um banco de dados default de tal forma que você nunca precise se preocuparcom esta questão. Ou eles podem te passar uma variável com escopo como entrada para os tagsJSTL de banco de dados.

No entanto, para pequenas aplicações, ou para as aplicações onde todo o gerenciamento de acessoa banco de dados é efetuado por páginas JSP em vez de por código Java, o tag<sql:setDataSource> é bastante útil. Este tag aceita como atributos todas as informaçõesnecessárias para efetuar uma conexão com um banco de dados. Com esta informação, você podefazer duas coisas: 1. Você pode decidir expor uma variável com escopo que represente o bancode dados. 2. Você pode definir um banco de dados (set up a database) toda vez que um usuário selogar, declarar este banco de dados como default na sessão do usuário, e nunca se preocupar comisto novamente.

31

A tabela abaixo mostra os atributos do tag <sql:setDataSource>:

Atributos Descrição Obrigatório DefaultdataSource Um banco de dados existente a ser

utilizadoNão Nenhum

driver O nome da classe Java do driver JDBC Não Nenhumurl O URL para acesso a um banco via JDBC Não Nenhumuser Nome do usuário Não Nenhumpassword Senha do usuário Não Nenhumvar Nome da variável que representa o banco Não Nenhumscope Escopo da variável ou um novo default Não page

Para preparar conexões para um banco Oracle, poderíamos utilizar o seguinte tag:

<sql:setDataSource driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@sbd:1521:orcl" user="jstl01" password="jstl01" scope="session" />

O atributo scope o tag <sql:setDataSource> irá definir um novo banco de dados para asessão do usuário. Poderíamos ter especificado scope=”request” ouscope=”application”. Observe que um conjunto de páginas pode utilizar um banco comescopo de aplicação enquanto outro conjunto utiliza um banco com escopo de sessão.

Se a sua aplicação trabalha com vários bancos de dados, em vez de utilizar<sql:setDataSource> para estabelecer uma conexão default, você pode utilizá-la para exporuma variável com escopo que representa o banco. Você pode fazer isto adicionando um atributovar:

<sql:setDataSource driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@sbd:1521:orcl" user="jstl01" password="jstl01" var="bancoUm" scope="session" />

Este tag expõe uma variável com escopo denominada bancoUm. Um outro tag pode expor umavariável diferente denominada bancoDois.

Se um código Java, ou um tag <sql:setDataSource> que você utilizou, criou uma variávelcom escopo que aponta para um banco de dados, você pode informar o nome desta variável emoutros tags <sql:setDataSource> para definir um novo default. Após termos expostobancoUm, podemos tornar este banco o default para escopo de requisição, assim:

32

<sql:setDataSource dataSource="${bancoUm}" scope="request" />

Note que quando você utiliza os atributos url, driver, user, e password, você pode deixar deinformar todos eles, exceto o url. Você pode deixar de informar o driver porque, às vezes, umadministrador de sistema pode prometer para você que o driver já estará registrado. Você podeomitir user ou a password caso seu banco não exija estas informações.

5.2.1 Cuidado com <sql:setDataSource>

O tag <sql:setDataSource> não implementa um pool de conexões, isto é, apenas abre umanova conexão com o banco de dados que será utilizada pela página JSP. Logo, o uso deste tag éineficiente para aplicações necessitam suportar muitos usuários.

Uma solução mais eficiente seria a designação, através de código Java, de um pool de conexõesdefault para as páginas JSP.

5.3 Executando Queries com <sql:query>

O objetivo do tag <sql:query> é expor uma variável com escopo que representa o resultado deuma query de banco de dados.

A tabela abaixo mostra os atributos do tag <sql:setDataSource>:

Atributos Descrição Obrigatório Defaultsql O comando sql SELECT a ser

executadoNão Corpo

dataSource O provedor de uma conexão de BD Não Ver seção 5.2startRow A linha do resultado que deve

ser retornadaNão 0 (a 1ª linha)

maxRows Quantidade máxima de linhas aretornar

Não ver seção x.x

var Nome da variável que deve exporo resultado

Sim Nenhum

scope Escopo da variável que deveexpor o resultado

Não Page

Se você fornecer uma variável com escopo para o atributo dataSource, então o tag <sql:query>irá se conectar ao banco de dados utilizando esta variável fornecida. Você pode expor umavariável com escopo para o atributo dataSource através do tag <sql:setDataSource>, ou vocêpode recuperar uma variável com escopo de requisição, sessão ou aplicação proveniente decódigo Java. Neste caso o tag <sql:query> teria a seguinte sintaxe:

33

<sql:query dataSource="${sessionScope.bancoUm}" ... />

Se você não utilizar o atributo dataSource, então o tag <sql:query> irá tentar encontrar umbanco default. Mais adiante veremos como configurar um banco de dados default.

5.3.1 Executando uma Query de Banco de Dados

Exemplo 1:

<sql:query var="resultado"> SELECT * FROM CLIENTES<sql:query>

Exemplo 2:

<sql:query var="resultado" sql="SELECT * FROM CLIENTES" />

Exemplo 3:

<sql:query var="resultado" sql="${query}" />

Exemplo 4: Recuperando a query de um documento XML

<sql:query var="resultado"> <x:out select="$doc/query/queryCliente" /><sql:query>

Observação: Estes exemplos assumem que um banco defaut está corretamente definido. Se umbanco default não foi definido com <sql:setDataSource>, e se as suas páginas não possuemum banco default definido por um programador Java, então será necessário utilizar o atributodataSource para estes exemplos funcionarem.

5.3.2 Lendo o Resultado de uma Query

O tag <sql:query> não exibe o resultado da query. O objetivo deste tag é simplesmenteexecutar a query e armazenar o resultado em uma variável com escopo definida por var escope. Esta variável com escopo possui uma série de propriedades. Estas propriedades nospermitem acessar duas coisas sobre o resultado:

• Os dados na tabela• Informações sobre os dados (metadata).

34

Acessando Metadata

Supondo que você utilizou um tag <sql:query> para criar uma variável denominadaresultado, as seguintes propriedades podem ser recuperadas a respeito deste resultado:

• resultado.rowCount nos permite recuperar a quantidade de linhas no resultado.

• resultado.columnNames retorna uma lista de nomes de colunas.

• resultado.limitedByMaxRows indica se a quantidade de linhas retornada pelo tag<sql:query> foi truncada. Veja o item 5.4.

A variável do tag <sql:query> nos permite acessar dados através de duas propriedades: rowse rowsByIndex. Ambas as propriedades expõem coleções. Geralmente você irá desejarpercorrer estas coleções para imprimir os resultados. A diferença entre rows e rowsByIndex éque durante cada loop você acessa os dados em rows utilizando os nomes de colunas, e acessadados em rowsByIndex utilizando os números das colunas.

Exemplo:

<sql:query var="usuariosEspertos"> SELECT NOME, QI FROM USUARIOS WHERE QI > 120<sql:query><table><c:forEach items="${usuariosEspertos.rows}" var="row"> <tr> <td><c:out value="${row.NOME}"/></td> <td><c:out value="${row.QI}"/></td> </tr></c:forEach><table>

Embora tenhamos escrito ${row.NOME}, também poderíamos ter escrito ${row.nome}. Apropriedade rows nos perimte acessar valores de colunas individuais em cada linha, por nome. Ea propriedade rowsByIndex nos permite acessar valores para cada linha, por número. Ambos osatributos são coleções de coleções, mas columnNames é uma simples coleção que nos permiteacessar nomes de colunas por nome.

Para utilizar rowsByIndex, é necessário escrever um loop similar. Mas em vez de referenciarrow.NOME e row.QI, é preciso utilizar row[0] e row[1]. Esta abordagem pode ser interessantese você não conhece os nomes das colunas.

35

Exemplo:

<sql:query var="usuariosEspertos"> SELECT NOME, QI FROM USUARIOS WHERE QI > 120<sql:query><table><c:forEach items="${usuariosEspertos.rowsByIndex}" var="row"> <tr> <td><c:out value="${row[0]}"/></td> <td><c:out value="${row[1]}"/></td> </tr></c:forEach><table>

É possível, em um único loop, combinar dados e metadata para produzir um cabeçalhoconveniente. Esta abordagem é útil quando se deseja escrever uma página genérica para tratardiversas queries. Por exemplo, você pode escrever uma página genérica denominadaimprimeQuery.jsp e incluir esta página, enviando para ela o resultado de um tag <sql:query>utilizando um atributo com escopo de requisição.

Exemplo:

<c:forEach items="${requestScope.resultado.rowsByIndex}" var="row" varStatus="s"> <c:if test="${s.first}"> <h4>Relação de Usuários Espertos</h4> <table border="1"> <tr> <c:forEach items="${requestScope.resultado.columnNames}" var="col"> <th><c:out value="${col}"/></th> </c:forEach> </tr> </c:if> <tr> <c:forEach items="${row}" var="valor"> <td><c:out value="${valor}"/></td> </c:forEach> </tr> <c:if test="${s.last}"> </table> </c:if></c:forEach>

36

5.3.3 Limitando o Tamanho do Resultado de uma Query

Como limitar em 20 linhas o resultado de uma query:

<sql:query var="empregados" maxRows="20"> SELECT NOME, SALARIO FROM EMPREGADOS WHERE SALARIO > 2000<sql:query>

Para ser informado que que a resposta da query foi truncada você utilizar a propriedadelimitedByMaxRows da variável exposta por <sql:query>, assim:

<sql:query var="empregados" maxRows="20"> SELECT NOME, SALARIO FROM EMPREGADOS WHERE SALARIO > 2000<sql:query>

<c:if test="${empregados.limitedByMaxRows}"> O resultado da sua query retornou empregados demais. Por favor, seja mais específico da próxima vez.<c:if>

Programadores Java podem designar um valor default para o atributo maxRows das suas páginas,mas você sempre poderá efetuar o override deste valor. Se você quer garantir que o resultado desua query não será truncado, atribua –1 a maxRows.

O Atributo startRow

A query abaixo retorna todas as linhas da tabela de clientes exceto as duas primeiras linhas (aslinhas cujos números são 0 e 1):

<sql:query var="clientes" startRow="2"> SELECT NOME, SALARIO FROM CLIENTES<sql:query>

Se a tabela só possuir duas linhas, então será atribuída à variável clientes uma coleção vazia.

5.4 Modificando Dados com <sql:update>

Novamente cabe salientar que grandes aplicações são mantidas mais facilmente quando páginasJSP não acessam bancos de dados diretamente, deixando esta tarefa para código Java emJavaBeans ou para tags customizados.

No entanto, JSTL provê o tag <sql:update> que poderá ser utilizado sem problemas emaplicações relativamente pequenas.

37

5.4.1 Uso Simplificado do Tag <sql:update>

Através do tag <sql:update> é possível emitir comandos Insert, Update, Delete, CreateTable, etc.

A tabela abaixo mostra os atributos do tag <sql:update>:

Atributos Descrição Obrigatório Defaultsql O comando sql UPDATE a ser

executadoNão Corpo

dataSource O provedor de uma conexão de BD Não Ver seção 5.2var Nome da variável que deve expor

a quantidade de linhas afetadasNão Nenhum

scope Escopo da variável que deveexpor a quantidade de linhasafetadas

Não Page

Exemplo 1:

<sql:update> INSERT INTO EMPREGADOS(NUMERO, NOME, PESO) VALUES(1, 'João Carlos', 80)</sql:update>

Exemplo 2:

<sql:update sql="DELETE FROM EMPREGADOS WHERE NUMERO = 1"/>

5.4.2 Medindo o Efeito de um Tag <sql:update>

Você pode utilizar o atributo var do tag <sql:update> para saber qual foi a quantidade delinhas afetadas pelo tag.

Exemplo 1:

<sql:update var="n"> DELETE FROM EMPREGADOS WHERE SALARIO > 2000</sql:update>

<p>Foram removidos <c:out value="${n}"/> empregados, todos com saláriomaior do que 2000,00 reais.</p>

<c:if value="${n == 0}"> Nenhum empregado foi removido.</c:if>

38

5.5 Utilizando <sql:param> com Queries Ajustáveis

5.5.1 Queries Modelos (Templates)

É possível utilizar o tag <c:out> para completar parte de uma query:

<sql:query var="resultado"> SELECT * FROM CLIENTES WHERE NOME = <c:out value='"${nomeCliente}"'/></sql:query>

E se o usuário digitar:

SERGIO' OR NOME <> 'SERGIO

Neste caso, o final da query será:

WHERE NOME = 'SERGIO' OR NOME <> 'SERGIO'

Logo, não é uma boa idéia utilizar <c:out> para construir comandos SQL.

5.5.2 Utilizando <sql:param>

JSTL permite que você evite estes problemas utilizando uma sintaxe especial emprestada deJDBC. Utilizando esta sintaxe você pode escrever uma query template e deixar de fora todas aspartes não conhecidas, colocando interrogações (?) nos seus lugares. Você poderá preencher estasinterrogações utilizando o tag <sql:param>. Este tag deve ser acrescentado como filho dos tags<sql:query> e de <sql:update>.

A tabela abaixo mostra o atributo do tag <sql:param>:

Atributos Descrição Obrigatório Defaultvalue Valor do parâmetro Não Corpo

Exemplo 1:

<sql:query var="resultado"> SELECT * FROM CLIENTES WHERE NOME = ? AND ENDERECO = ? AND IDADE = ? <sql:param value="${page.nomeusuario}"/> <sql:param value="${param.endereco}"/> <sql:param value="${idade}"/></sql:query>

39

Quando um tag possui várias interrogações, ele deve ter exatamente um tag <sql:param> paracada interrogação, na ordem em que as interrogações aparecem.

Exemplo 2:

<sql:update> INSERT INTO EMPREGADOS (NUMERO, NOME, SALARIO) VALUES (?, ?, ?) <sql:param value="${param.numero}"/> <sql:param value="${param.nome}"/> <sql:param value="${param.salario"/></sql:update>

Exemplo 3:

<sql:update> UPDATE EMPREGADOS SET SALARIO = ? WHERE NUMERO = ? <sql:param value="${param.salario"/> <sql:param value="${param.numero}"/></sql:update>

Exemplo 4: Se o tag <sql:param> não contiver um atibuto value, o tag irá utilizar o conteúdode seu corpo. Logo, é possível produzir um valor utilizando outros tags.

<sql:update> UPDATE EMPREGADOS SET SALARIO = ? WHERE NUMERO = ? <sql:param> <x:out select="$doc/empregados/empregado/salario"/> </sql:param> <sql:param value="${param.numero}"/></sql:update>

40

5.5.3 Parâmetros do Tipo Date com <sql:dateParam>

Considere o comando SQL abaixo:

SELECT * FROM USUARIOSWHERE DATA_NASC < ?

Neste caso, se você tiver uma variável com escopo representando uma data (mais adianteveremos como criar esta variável com escopo), talvez não seja possível utilizar esta variável com<sql:param>. Vai depender do driver que você estiver utilizando. Para ter certeza de que vocêconseguirá adicionar datas às suas queries, JSTL provê o tag <sql:dateParam> cujos atributossão relacionados absixo:

Atributos Descrição Obrigatório Defaultvalue A data que irá substituir a ? Sim Nenhumtype Um dos seguintes valores: time,

date, ou timestampNão timestamp

O atributo value requer uma expressão que aponte para uma variável com escopo que armazeneuma data, e o atributo type permite que você descreva mais precisamente como o banco devetratar o valor: apenas armazena a hora do dia (time), uma data (date), ou ambos – data e hora(timestamp).

Exemplo:

<sql:query> SELECT * FROM USUARIOS WHERE DATA_NASC < ? <sql:dateParam value="${dataNasc}"/></sql:query>

5.6 Gerenciando Transações com <sql:transaction>

5.6.1 O Tag <sql:transaction>

JSTL suporta transações através do tag <sql:transaction>. Este tag age como o tag pai dostags <sql:update> e <sql:query>. Ou todos os tags filhos de <sql:transaction> sãobem sucedidos, ou todos falham juntos. Sua transação pode ser formada por um update seguidade uma query, seguida de outro update baseado na query intermediária. Esta é a razão pela qual otag <sql:transaction> permite que tags <sql:query> participem de uma transação.

Note que qualquer texto válido, tags JSTL, ou outro conteúdo JSP, pode aparecer dentro de umtag <sql:transaction>. Se um erro fatal ocorrer em qualquer lugar dentro deste bloco – porexemplo, se você decidir recuperar um arquivo com <c:import> e este arquivo não forencontrado – então toda a transação será interrompida e sofrerá um rollback imediato. Esteprocesso permite a você amarrar o sucesso de uma operação de bano de dados ao sucesso de

41

operações que não são de banco de dados. Tenha em mente apenas que <sql:transaction>efetua o rollback apenas das operações de banco de dados. Ele não apaga, por exemplo, variáveiscom escopo criadas ao longo da execução deste bloco.

A tabela abaixo mostra os atributos do tag <sql:transaction>:

Atributos Descrição Obrigatório DefaultdataSource Quem provê a conexão de banco

de dadosNão Ver seção 5.2

isolation Nível de isolamento dastransações

Não Ver seção 5.6.2

O tag <sql:transaction> determina qual banco de dados será utilizado da mesma forma que<sql:query> e <sql:update>. Ele pode utilizar seu atributo dataSource ou, caso não sejaespecificado, se basear em um banco de dados default, que pode ter sido estabelecido por<sql:setDataSource> ou por código Java. Quando um tag <sql:transaction> aparece nasua página, ele imediatamente inicia uma transação de banco de dados. Esta transação utiliza umaconexão de banco de dados, e esta conexão é fornecida, por default para todos os tags<sql:query> e <sql:update> filhos de <sql:transaction>.

Por exemplo, considere o seguinte tag:

<sql:update sql="${comando}"/>

Este tag normalmente utilizaria o banco de dados default, uma vez que nenhum atributodataSource foi especificado. Mas quando este tag aparece dentro de um tag<sql:transaction>, ele utiliza o banco definido para seu pai <sql:transaction>.

Exemplo:

<sql:transaction dataSource="${database}"> <sql:update> UPDATE CONTAS SET SALDO = SALDO - ? WHERE NUMERO = ? <sql:param value="${param.valor}"/> <sql:param value="${param.contaDebitada}"/> </sql:update> <sql:update> UPDATE CONTAS SET SALDO = SALDO + ? WHERE NUMERO = ? <sql:param value="${param.valor}"/> <sql:param value="${param.contaCreditada}"/> </sql:update></sql:transaction>

42

5.6.2 Níveis de Isolamento

A tabela abaixo mostra o valores possíveis do atributo isolation do tag<sql:transaction>, e seus respectivos significados:

Níveis de Isolamento Dirty Reads? Nonrepeatable reads? Phantom reads?read_uncommited --- --- ---read_commited Evita --- ---repeatable_read Evita Evita ---serializable Evita Evita Evita

Esta tabela mostra os quatro níveis de isolamento possíveis e os tipos de leituras indesejáveis queeles proíbem.

Uma dirty read (leitura suja) é aquela capaz de recuperar linhas ainda não comitadas por outrosusuários.

Uma nonrepeatable read (leitura sem repetição) ocorre quando o mesmo comando SELECTretorna diferentes resultados quando executado mais de uma vez dentro de uma mesma transação.

E uma phantom read (leitura fantasma) é como uma nonrepeatable read, mas envolve novaslinhas adicionadas a uma tabela que aparecem no segundo SELECT (enquanto, umanonrepeatable read pode afetar dados existentes).

Você poderia pensar que serializable é o melhor nível de isolamento, uma vez que evita todos osproblemas. No entanto, este nível de isolamento provoca uma queda no desempenhoconsiderável.

43

6. FORMATAÇÃO

Neste capítulo veremos uma coleção de tags JSTL que auxiliam na leitura e escrita de números edatas. Tdos os tags introduzidos neste capítulo vêm da biblioteca fmt de tags JSTL. Para utilizarqualquer dos exemplos apresentados neste capítulo será preciso acrescentar no topo da página aseguinte diretiva:

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

6.1 Imprimindo Números com <fmt:formatNumber>

6.1.1 Uso Básico de <fmt:formatNumber>

O uso mais simples deste tag imprime o número utilizando a melhor suposição sobre o formatoque o usuário deseja ver. Browsers podem transmitir informações sobre seus locale –essencialmente, o local e os formatos preferidos para números, datas e outros dados.

Exemplo:

<fmt:formatNumber value="${valor}"/>

Se você está utilizando o Internet Explorer, você pode experimentar diferentes locaismodificando no painel de controle as opção referente ao país/língua.

A tabela abaixo mostra alguns atributos do tag <fmt:formatNumber>:

Atributos Descrição Obrigatório Defaultvalue O número a ser formatado Não Corpotype Se deve ser impresso: numbers,

currency ou percentageNão number

currencyCode ISO-4217 currency code Não NenhumcurrencySymbol Símbolo monetário (como $) Não NenhumgroupingUsed Se deve haver agrupamento de

milharNão true

maxIntegerDigits Número máximo de dígitosinteiros

Não Nenhum

minIntegerDigits Número mínimo de dígitosinteiros

Não Nenhum

maxFractionDigits Número máximo de dígitosfracionários

Não Nenhum

minFractionDigits Número mínimo de dígitosfracionários

Não Nenhum

pattern Padrão a ser utilizado Não Nenhumvar Variável que deve expor o número

formatado como um StringNão Nenhum

scope Escopo da variável var Não page

44

6.1.2 Diferentes Formas de Imprimir um Número

Suponha que sua empresa produz um tag que imprime um número, como o seguinte:

<minhaEmpresa:imprimeFrete/>

Para formatar a saída a ser impressa:

<fmt:formatNumber> <minhaEmpresa:imprimeFrete/><fmt:formatNumber/>

6.1.3 Armazenando um Número em vez de Imprimi-lo

Para armazenar um número na variável numero, com escopo de sessão:

<fmt:formatNumber value="${valor}" var="numero" scope="session"/>

6.1.4 Imprimindo Diferentes Tipos de Números

Percentuais:

<fmt:formatNumber value="24" type="percent"/>

Valor Monetário:

<fmt:formatNumber value="78.74901" type="currency"/>

6.1.5 Agupamento de Milhar

<fmt:formatNumber value="500000.01" groupingUsed="true"/>

6.1.6 Controlando Quantos Dígitos Devem Ser Impressos

<fmt:formatNumber value="0.1" minIntegerDigits="1" minFractionDigits="2" maxFractionDigits="2"/>

45

6.1.7 Utilizando Padrões

Um caso especial difícil de solucionar sem a utilização de padrões é o uso da notação científica:

<fmt:formatNumber value="52577" pattern="###.##E0"/>

irá imprimir:

52.577E3

6.2 Imprimindo Datas

A tabela abaixo mostra os atributos do tag <fmt:formatDate>:

Atributos Descrição Obrigatório Defaultvalue A data a ser impressa Sim Nenhumtype Se deve ser impresso: data, timeou

ambosNão date

dateStyle Estilo pré-formatado para data (full,short)

Não default

timeStyle Estilo pré-formatado para hora Não defaulttimeZone Time zone a ser utilizado Não Ver 6.5pattern Padrão explícito a ser utilizado Não Nenhumvar Variável que deve expor a data

formatada como um StringNão Nenhum

scope Escopo da variável var Não page

O atributo value do tag <fmt:formatDate> deve apontar para uma variável do tipo date. Nãohá como interpretar Strings como data. Esta é a tarefa do tag <fmt:parseDate>, que seráexaminado mais adiante.

Você pode obter uma data de algumas formas. É possível recuperar uma data de um banco dedados, de código Java, ou você pode utilizar o tag <fmt:parseDate> para produzir umavariável do tipo Date. Você também pode produzir uma data utilizando o tag <useBean>,assim:

<jsp:useBean id="umaData" class="java.util.Date"/>

Este tag cria uma variável com escopo de página denominada umaData que armazena a datacorrente.

Exemplo:

<jsp:useBean id="umaData" class="java.util.Date"/><fmt:formatDate value="${umaData}"/>

46

6.2.1 Utilizando Padrões

O atributo pattern nos permite especificar exatamente como uma data deve aparecer.

A tabela abaixo mostra os caracteres mais úteis que você pode utilizar em um pattern:

Caracter(es) Significado Exemployy Ano com dois dígitos 02yyyy Ano com 4 dígitos 2002MM Mês com dois dígitos 04MMMM Mês por extenso abrildd Dia com dois dígitos 07EEEE Dia da semana por extenso Sexta-feiraH Hora com 1 dígito no padrão 24h 21HH Hora com 2 dígitos no padrão 24h 21h Hora com 1 dígito no padrão 12h 9hh Hora com 2 dígitos no padrão 12h 09m Minuto com 1 dígito 4mm Minuto com 2 dígitos 04s Segundo com 1 dígito 6ss Segundo com 2 dígitos 06a AM / PM PM

Exemplo:

<jsp:useBean id="umaData" class="java.util.Date"/>Data: <fmt:formatDate value="${umaData}" pattern="dd/MM/yyyy"/><br>Hora: <fmt:formatDate value="${umaData}" pattern="hh:mm:ss"/>

6.3 Lendo Números com <fmt:parseNumber>

JSTL possui dois tags que nos auxiliam na leitura de números e datas: <fmt:parseNumber> e<fmt:parseDate>.

O tag <fmt:parseNumber> é específico para casos nos quais é necessário interpretar númerosmais complicados. Por exemplo, se o usuário digita 50.000 (incluindo o ponto) ou se você lê - deum arquivo XML ou de um banco de dados - valores que incluem vírgulas ou espaços embranco> Nestes casos, você não pode tratar estes valores como números; É preciso primeiramenteefetuar o parse destes valores.

47

A tabela abaixo mostra os atributos do tag <fmt:parseNumber>:

Atributos Descrição Obrigatório Defaultvalue O String que deve sofrer o parse Não Corpotype Como efetuar o parse(number,

currency, ou percent)Não number

integerOnly Se a parte fracionária deve serdescartada

Não false

pattern Informações mais detalhadas de comoefetuar o parse do número

Não Nenhum

parseLocale Locale a ser utilizado em vez dodefault

Não Ver6.3.2

var Variável que deve expor o número apóso parse (como um número)

Não Nenhum

scope Escopo da variável var Não page

6.3.1 Porque Efetuar o Parse de Números

Na maioria das páginas você provavelmente não necessitará efetuar o parse de números. Vocêsentirá a necessidade de efetuar o parse de números nas seguintes situações:

• Você necessita salvar um valor numérico em um banco de dados utilizando <sql:update> e<sql:param>, mas tudo o que você tem é um String como 500.000,00.

• Você deseja normalizar a exibição de números – isto é, fazer com que todos sejam exibidoscom a mesma aparência. Mas alguns de seus números podem vir de usuários ou bancos dedados diferentes, e aparecem de formas diferentes. Antes de poder passar um número para otag <fmt:formatNumber> é preciso efetuar o seu parse com <fmt:parseNumber>.

• Às vezes (embora raramente) você possui um String como 500,000 mas necessita de umnúmero para ser utilizado em tags como <c:forEach> (como valor dos atributos begin,end, e step), <sql:query> (como valor dos atributos startRow ou maxRows), e etc.

• Você necessita efetuar uma operação matemática sobre um número digitado pelo usuário ourecuperado de algum lugar.

6.3.2 Como <fmt:parseNumber> Funciona por Default

O tag <fmt:parseNumber> recebe o número que deve sofrer o parse através do seu atributovalue ou através do seu corpo. Após efetuar o parse, o valor resultante é armazenado na variávelcom escopo indicada ou é impresso sem nenhuma formatação especial. Quando o tag<fmt:parseNumber> é utilizado para efetuar o parse de um número digitado pelo usuário (ourecuperado de algum outro local) ele assume, por default, que os usuários poderão entrar comvalores com formatações do país/língua do usuário.

48

Por exemplo, considere o formulário HTML abaixo:

<form method="post" action="parseNumber.jsp"> Qual é o seu número favorito? <input type="text" name="favorito" size="10"/><br/> <input type="submit" value="Enviar"/></form>

A página JSP abaixo mostra como tratar este formulário:

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

<p>Você digitou "<c:out value="${param.favorito}"/>". </p>

<fmt:parseNumber var="fav" value="${param.favorito}"/>

<p>Aparentemente este número corresponde ao número<c:out value="${fav}"/>.</p>

<p>Se você multiplicar este número por 2 e somar 1, você obtém<c:out value="${fav * 2 + 1}"/>, certo?</p>

6.3.3 Modificando as Regras de Parse de <fmt:parseNumber>

Os demais atributos de <fmt:parseNumber> permitem que você modifique as regras que serãoutilizadas por default.

Ignorando Dígitos Fracionários

<fmt:parseNumber var="numero" value="50.05" integerOnly=”true”/>

Modificando o Locale

Como ignorar o Locale informado pelo Browser:

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

<html> <body> <h4>Utilizando o Locale Referente aos EUA</h4>

<fmt:setLocale value="en_US"/> <fmt:parseNumber var="numero1" value="50,05"/> <fmt:parseNumber var="numero2" value="50,05" integerOnly="true"/>

49

<p>O parse de 50,05 corresponde ao número <c:out value="${numero1}"/> sem formatação.

<p>O parse de 50,05 corresponde ao número <fmt:formatNumber value="${numero1}"/> com formatação.

<p>O parse de 50,05 - removendo a parte fracionária - corresponde ao número <fmt:formatNumber value="${numero2}" /> com formatação.

<h4>Utilizando o Locale Referente ao Brasil</h4>

<fmt:setLocale value="pt_BR"/> <fmt:parseNumber var="numero1" value="50,05"/> <fmt:parseNumber var="numero2" value="50,05" integerOnly="true"/>

<p>O parse de 50,05 corresponde ao número <c:out value="${numero1}"/> sem formatação.

<p>O parse de 50,05 corresponde ao número <fmt:formatNumber value="${numero1}"/> com formatação.

<p>O parse de 50,05 - removendo a parte fracionária - corresponde ao número <fmt:formatNumber value="${numero2}" /> com formatação. </body></html>

6.4 Lendo Datas com <fmt:parseDate>

A tabela abaixo mostra os atributos do tag <fmt:parseDate>:

Atributos Descrição Obrigatório Defaultvalue O String que deve sofrer o parse Não Corpotype Como efetuar o parse(time, date, ou

ambos)Não date

pattern Pdrão a ser utilizado ao efetuar oparse de uma data

Não Nenhum

parseLocale O locale que deve ser utilizado, emvez do default

Não Ver6.3.2

timeZone O time zone a ser aplicado à data Não Ver 6.5var Variável que deve expor a data após o

parse (como um número)Não Nenhum

scope Escopo da variável var Não page

50

Os atributos value, var, scope e parseLocale funcionam exatamente como no tag<fmt:parseNumber>.

6.4.1 Como <fmt:parseDate> Funciona por Default

O funcionamento do tag <fmt:parseDate> assim como outros tags de formatação e de parse, édependente do locale default do browser do usuário. Sem nenhum atributo além de value, eleefetua o parse de uma data da mesma forma como <fmt:formatDate> formata uma data. Asregras de parse são bastante restritivas. Logo, o tag

<fmt:parseDate value="Aug 24, 1981"/>

irá funcionar para o locale English, mas

<fmt:parseDate value="Aug 24, 1981"/>

causará um erro pois falta a vírgula. Este comportamento torna o default muito pouvo útil.

6.4.2 Modificando Como <fmt:parseDate> Efetua o Parse de Datas

O tag <fmt:parseDate> possui o atributo pattern, que é a forma mais útil de utilizar estetag. O atributo pattern aceita um padrão de data – com a mesma sintaxe vista na seção 6.2.1 – eefetua o parse de acordo com este padrão.

Exemplo:

<fmt:parseDate var="umaData" value="26/05/1990" pattern="dd/MM/yyyy"/>

51

7. TAREFAS COMUNS

7.1 Tratando Parâmetros do tipo CheckBox

Parâmetros de CheckBox são especiais uma vez que o mesmo nome pode ser mapeado a diversosvalores. Suponha que uma página HTML possui os seguintes tags:

<input type="checkbox" name="lingua" value="ingles" /><input type="checkbox" name="lingua" value="espanhol" /><input type="checkbox" name="lingua" value="frances" />

Se o usuário clicar nas três caixas, o parâmetro língua terá os três valores: Inglês, Espanhol eFrancês.

Você pode acessar uma coleção que contém todos estes valores através da expressão${paramValues.nome} onde nome é o nome do parâmetro que você deseja (lingua, nestecaso). Você pode utilizar o tag <c:forEach> para efetuar um loop sobre os parâmetosindividuais nesta coleção, para tratá-los um de cada vez.

7.1.1 O Formulário HTML

<form method="post" action="checkbox.jsp"> <p>Por favor selecione as línguas que você conhece:</p>

<p>Inglês <input type="checkbox" name="lingua" value="Inglês" />

<p>Espanhol <input type="checkbox" name="lingua" value="Espanhol" />

<p>Francês <input type="checkbox" name="lingua" value="Francês" />

<p><input type="submit" value="Enviar" /></p></form>

52

7.1.2 Um Manipulador de CheckBox Simples

Segue abaixo a página JSP manipuladora do formulário HTML acima:

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

<c:choose> <c:when test="${not empty paramValues.lingua}"> As línguas que você conhece são: <ul> <c:forEach items="${paramValues.lingua}" var="idioma"> <li><c:out value="${idioma}"/></li> </c:forEach> </ul> </c:when> <c:otherwise> Você não selecionou nenhuma caixa de verificação. </c:otherwise></c:choose>

Na verdade não é um problema efetuar um loop sobre um parâmetro inexistente. O tag<c:forEach> simplesmente não fará nada. O raciocínio é o seguinte: uma coleção inexistente écomo uma coleção com zero elementos, logo faz sentido efetuar uma iteração zero vezes.

No entanto, como desejamos enviar uma mensagem caso o usuário não selecione nenhumalíngua, foi acrescentado o tag <c:choose>.

Há outras maneiras de garantir que os tags <ul> e </ul> serão impresos apenas quando a listativer pelo menos um item.

Exemplo:

<c:forEach items="${paramValues.lingua}" var="idioma" varStatus="s"> <c:if test="${s.first}"> <ul> </c:if> <li><c:out value="${idioma}"/></li> <c:if test="${s.last}"> </ul> </c:if></c:forEach>

53

7.1.3 Tratando Alguns CheckBoxes de Forma Especial

Com o tag <c:forEach> é possível utilizar expressões para referenciar o item corrente –idioma, neste caso – para tomar decisões sobre como tratar cada item individualmente.

Exemplo:

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

<c:choose> <c:when test="${not empty paramValues.lingua}"> As línguas que você conhece são: <ul> <c:forEach items="${paramValues.lingua}" var="idioma"> <c:choose> <c:when test="${idioma == 'Inglês'}"> <font size="+2"> </c:when> <c:otherwise> <font size="-2"> </c:otherwise> </c:choose> <li><c:out value="${idioma}"/></li> </font> </c:forEach> </ul> </c:when> <c:otherwise> Você não selecionou nenhuma caixa de virificação. </c:otherwise></c:choose>

Para atualizar o banco de dados quando a página é carregada com a língua Inglesa selecionada,poderíamos executar o código abaixo:

<sql:update> UPDATE idiomas set ingles = ingles + 1</sql:update>

54

7.2 Lendo Datas

7.2.1 O Formulário HTML

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

<html> <body> <form method="post" action="trataData.jsp">

Por favor, entre com a data de seu nascimento: <p> <select name="dia"> <c:forEach begin="1" end="31" var="dia"> <option><c:out value="${dia}"/></option> </c:forEach> </select>

<select name="mes"> <option value="01">Janeiro</option> <option value="02">Fevereiro</option> <option value="03">Março</option> <option value="04">Abril</option> <option value="05">Maio</option> <option value="06">Junho</option> <option value="07">Julho</option> <option value="08">Agosto</option> <option value="09">Setembro</option> <option value="10">Outubro</option> <option value="11">Novembro</option> <option value="12">Dezembro</option> </select>

<select name="ano"> <c:forEach begin="1930" end="2003" var="ano"> <option><c:out value="${ano}"/></option> </c:forEach> </select>

<input type="submit" value="Enviar" />

</form> </body></html>

Note que embora a página acima gere um simples formulário de entrada de dados HTML, não setrata de uma página HTML estática. Nesta página há um campo de formulário estático (mes), edois campos gerados dinamicamente: dia e ano.

55

7.2.2 Tratando o Formulário e Lendo a Data

Segue abaixo o código fonte da página manipuladora do formulário:

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

<fmt:parseDate var="umaData" parseLocale="pt_BR" value="${param.dia}/${param.mes}/${param.ano}" pattern="d/MM/yyyy"/>

<p>Você nasceu<fmt:formatDate value="${umaData}" dateStyle="full"/>.

<p>Você nasceu em<fmt:formatDate value="${umaData}" dateStyle="short"/>.

<p>Você nasceu em<fmt:formatDate value="${umaData}" pattern="dd/MM/yyyy"/>.

Observe que no tag <fmt:parseDate> foi incluído o atributo parseLocale para fazer comque o parse ocorra com base no locale português/Brasil em vez de utilizar o locale do browser.Assim, a data sofrerá o parse corretamente e será armazenada na variável data. Para provar quea data realmente passou pelo processo de parse mandamos imprimi-la utilizando o estilo fullque exibe o dia da semana correspondente.

Naturalmente poderíamos ter feito outras coisas com a data além de apenas imprimi-la, comovem no exemplo abaixo:

<sql:update> UPDATE usuarios SET data_nasc = ? <sql:param value="${umaData}"/></sql:update>

56

7.3 Tratando Erros

Quando você utiliza tags JSTL, existem basicamente três coisas que você pode fazer com oserros:

• Evitar pensar neles. Quando você faz isso, qualquer erro que ocorra em sua página faz comque a execução da página falhe. Nestes casos, geralmente o container JSP provê informaçõessobre o tipo de erro que ocorreu. Esta abordagem é boa enquando você está debugando apágina, mas parece pouco profissional para os usuários.

• Utilizar o tag <c:catch> para capturar e até mesmo tentar recuperar erros dentro da mesmapágina. Fazendo isto você ganha em flexibilidade, mas pode tornar as páginas muitocomplicadas. Por outro lado, você poderá descartar um erro significativo.

• Utilizar uma facilidade que JSP provê conhecida como error page (geralmente escrita comoerrorPage). Uma errorPage JSP é uma página que você pode projetar para tratar erros dediversas páginas. Uma vantagem desta página de erro é que ela permite que o mesmocomportamento seja utilizado para um conjunto de páginas. Basta apontar todas elas para umamesma página de erro e definir o que esta página deve fazer quando um erro ocorre.

7.3.1 Capturando Erros com <c:catch>

Este tag permite que você capture o erro para descartá-lo ou para armazenar informações sobreele para uso posterior.

A tabela abaixo mostra o único atributo do tag <c:catch>:

Atributos Descrição Obrigatório Defaultvar Variável que expõe informações sobre

o erroNão Nenhum

Erros que acontecem no corpo de um tag <c:catch> não fazem com que seja abortada toda aexecução da página. Estes erros abortam apenas o resto do corpo do tag <c:catch>.

Se você utilizar <c:catch> sem um atributo var, todos os erros que ocorrerem no corpo do tagserão ignorados e a execução da página irá prosseguir. Se uma página possui um contador queatualiza seu valor em um banco de dados, a atualização deste contador poderá estar envolta emum tag <c:catch>. Neste caso, caso o banco de dados esteja fora dor ar, a página seráexecutada, sem o contador.

A seguir será apresentado um exemplo onde o usuário digita um número inteiro que deverápassar pelo processo de parse. Se o processo de parse não for bem sucedido, será apresentadauma mensagem de erro.

57

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

<html> <body> <p>Você digitou "<c:out value="${param.numero}"/>". </p>

<c:catch var="erro"> <fmt:parseNumber var="num" value="${param.numero}"/>

<p>Multiplicando <c:out value="${num}"/> por dois e somando 1 dá <c:out value="${num * 2 + 1}"/>. </p> </c:catch>

<c:if test="${not empty erro}"> Erro: o que você digitou não é um número. </c:if> </body></html>

Para adicionar o tratamento de erro a esta página adicionamos o tag <c:catch> em torno dostags que podem provocar erros. Este tag garante que nenhum erro que ocorra será percebido pelocontainer JSP. Observe que se um erro ocorre durante o processo de parse, isto é, durante aexecução de <fmt:parseNumber>, então as demais linhas de código dentro do tag <c:catch>não serão executadas. este comportamento faz sentido: se o valor digitado não é um número, nãofaz sentido efetuar operações aritméticas com ele.

A coisa mais útil que se pode fazer com a variável criada com o tag <c:catch var="erro"> éverificar se ela está empty. Neste caso, se erro está Empty, então nenhum erro ocorreu. Casocontrário teremos certeza de que um erro ocorreu dentro do bloco <c:catch>. As variáveiscriadas pelo tag <c:catch> possuem pelo menos uma propriedade útil: message, que contémalguma informação que descreve o erro que ocorreu. Esta propriedade é útil se você quer que ousuário tenha uma idéia do erro que ocorreu. Para incluir informações sobre o erro ocorrido, oseguinte tag pode ser utilizado:

<c:out value="${erro.message}"/>

ou simplesmente:

<c:out value="${erro}"/>

Esta última opção inclui algumas outras informações técnicas sobre o erro que ocorreu.

58

7.3.2 Enviando Erros para uma Página de Erro

Quando um erro alcança o container JSP, o container exibe, por default, a sua própria mensagemde erro. No entanto, você pode modificar este comportamento utilizando uma página de erro JSP.Quando sua página possui uma página de erro, o usuário recebe um forward para esta página deerro sempre que um erro ocorre (como se você tivesse manualmente incluído um tag<jsp:forward> na sua página).

Para declarar uma página de erro, você deve utilizar a diretiva <%@ pageerrorPage=”destino” %>, onde destino é o nome da página de erro, por exemplo,paginaDeErro.jsp.

Esta página de erro é uma página JSP normal. A única diferença é que ela deve incluir a seguintelinha:

<%@ page isErrorPage="true" %>

Esta linha indica ao container JSP que ele pode utilizar esta página como página de erro. Noteque você pode utilizar o tag <c:catch> e a página de erro na mesma página JSP. A página deerro receberá o forward apenas se um erro ocorrer e não for capturado pelo bloco <c:catch>.

Criando uma Página de Erro

Listagem da página de erro:

<%@ page isErrorPage="true" %><%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %><%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>

<h4>Erro!</h4>

<p>Algo ruim ocorreu em uma das suas páginas:</p>

<p><c:out value="${pageContext.exception.message}"/></p>

Note como utilizamos a expressão ${pageContext.exception.message} para imprimirinformações sobre o erro que ocorreu. A variável pageContext.exception é a variável comescopo que é armazenada pelo bloco <c:catch>.

Listagem da página que contém um erro:

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

<fmt:parseDate value="abcd"/>

59

7.4 Validando Entrada de Dados

7.4.1 Diferentes Tipos de Validação de Formulários

A primeira coisa a compreender sobre validação é que, em grandes aplicações para a web, não éfunção das páginas JSP efetuar validação de entrada de dados, especialmente me uma aplicaçãoque utiliza Struts ou um outro framework para prover a separação do trabalho e implementação.Em uma aplicação deste tipo, a função das páginas JSP é apenas apresentar e formatar ainformação. O código Java executado no back-end cuida do resto.

Os tags JSTL disponíveis para validação incluem coisas como:

• Verificar se o usuário digitou algo em um campo de um formulário (ou o deixou em branco).• Garantir que se um campo foi preenchido um outro também deveria ter sido (ou não).• Comparar um número digitado pelo usuário com uma faixa de valores.

7.4.2 Tarefas Relacionadas à Validação de um Formulário

A seguir será apresentada uma página JSP responsável pela validação dos campos de umformulário de entrada de dados exibido por esta mesma página JSP. Esta página é exibidarepetidamente, até que todos os campos do formulário tenham sido informados corretamente.

Exemplo:

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

<html><body><h1>Serviço de Correio Eletrônico Tabajara</h1>

<c:if test="${param.enviado}"> <c:if test="${empty param.nome}" var="semNome" /> <c:if test="${empty param.email}" var="semEmail" /> <c:if test="${empty param.idade}" var="semIdade" />

<c:catch var="erroIdade"> <fmt:parseNumber var="idadeNumerica" value="${param.idade}" /> <c:if test="${idadeNumerica < 13}" var="abaixo13" /> </c:catch> <c:if test="${not empty erroIdade}" var="idadeInvalida" />

<c:if test="${not (semNome or semEmail or semIdade or idadeInvalida or abaixo13)}">

60

<c:set value="${param.nome}" var="nome" scope="request"/> <c:set value="${param.email}" var="email" scope="request"/> <c:set value="${param.idade}" var="idade" scope="request"/> <jsp:forward page="obrigado.jsp" /> </c:if></c:if>

<form method="post"> <p> Obrigado por assinar o serviço de correio eletrônico Tabajara.<br/> Ao submeter suas informações no formulário abaixo, você começará a receber "de grátis" todo tipo de "spam" que você sempre quis. </p>

<input type="hidden" name="enviado" value="true" />

<p> Digite seu nome: <input type="text" name="nome" value="<c:out value="${param.nome}"/>" /> <br /> <c:if test="${semNome}"> <small><font color="red"> Erro: Você deve digitar seu nome </font></small> </c:if> </p>

<p> Digite seu endereço de e-mail: <input type="text" name="email" value="<c:out value="${param.email}"/>" /> <br /> <c:if test="${semEmail}"> <small><font color="red"> Erro: Você deve digitar seu endereço de e-mail </font></small> </c:if> </p>

<p> Digite sua idade: <input type="text" name="idade" size="3" value="<c:out value="${param.idade}"/>" /> <br /> <c:choose> <c:when test="${semIdade}"> <small><font color="red"> Erro: Você deve digitar sua idade </font></small> </c:when>

61

<c:when test="${idadeInvalida}"> <small><font color="red"> Erro: Não fui capaz de decifrar sua idade </font></small> </c:when> <c:when test="${abaixo13}"> <small><font color="red"> Erro: Se manca garoto!!! Você é muito jovem para assinar o serviço <br> de e-mail Tabajara. Aqui tem besteira demais para você! <br> Por favor, cresça e tente novamente. </font></small> </c:when> </c:choose> </p>

<input type="submit" value="Assinar" />

</form></body></html>

Esta página começa com lógica de validação de dados. Primeiramente o tag <c:if> é utilizadopara determinar se esta página está respondendo a um formulário ou exibindo o formulário pelaprimeira vez.

Em seguida os parâmetros enviados a esta página são validados.

O tag <c:if test="${empty param.nome}" var="semNome" /> designa true a umavariável com escopo de página denominada semNome, se param.nome não possui um valorsignificativo. Para testar se o usuário digitou um número no campo idade utilizamos o elemento<c:catch>.

O código abaixo,

<c:catch var="erroIdade"> <fmt:parseNumber var="idadeNumerica" value="${param.idade}" /> <c:if test="${idadeNumerica < 13}" var="abaixo13" /></c:catch>

designa uma variável com escopo de página denominada erroIdade caso ocorra um errodurante o processo de parse.

Em seguida, caso nenhum erro tenha ocorrido, efetuamos um forward para a página seguinte.Observe que antes do forward, são designados valores para três variáveis com escopo derequest para que a página seguinte possa recuperar seus valores. Se o forward não acontecer,então o formulário será exibido. Neste caso, um campo hidden designa o valor true para o

62

campo enviado para indicar que o formulário está sendo submetido pelo usuário em vez desolicitado pela primeira vez.

Os campos do formulário (nome, email e idade) recebem os valores dos parâmetros enviados àpágina, e para cada campo, se um erro é detectado, uma mensagem em vermelho é impressa. Nocaso do campo idade, foi utilizado o tag <c:choose> uma vez que três mensagens de errodiferentes podem ser emitidas.

Para campos do tipo <input type=”text”> podemos utilizar o atributo value para fornecerum valor para o campo, assim:

<input type="text" name="nome" value="<c:out value="${param.nome}">

Para outros tipos de campos de entrada de dados – caixas de seleção, botões de rádio, e caixas deconfirmação – é mais complicado designar valores default. Para uma caixa do tipo <select>,não basta especificar um atributo value para o valor default. Você deve adicionar o atributoselected=”selected” ao tag <option> correto. Você pode fazer isto comparando o valor doparâmetro com os valores do tag <option> que você está prestes a imprimir. Por exemplo:

<select name="Idioma"> <option value="Inglês" <c:if test="${param.lingua == 'Inglês'}"> selected="selected" </c:if> >Inglês</option> <option value="Francês" <c:if test="${param.lingua == 'Francês'}"> selected="selected" </c:if> >Francês</option></select>

O atributo selected=”selected” será impresso apenas para o valor correto.

Botões de rádio e caixas de confirmação funcionam da mesma forma, mas em vez de adicionar oatributo selected=”selected”, você adiciona o atributo checked=”checked”. Para camposdo tipo <textarea>, simplesmente insira o valor desejado no corpo da <textarea>:

<textarea name="observação"><c:out value="${param.obs}"/><textarea>

Observe que o tag form não possui um atributo action, indicando que a mesma página JSPdeve receber a requisição quando este formulário for submetido.

63

A página JSP abaixo é exibida quando não é detectado mais nenhum erro nos campos doformulário:

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

<html> <body> <font face="arial"> <h4> Excelente! Os seguintes dados foram recebidos e estão corretos: </h4> <ul> <li>Nome: <c:out value="${requestScope.nome}" /> <li>E-Mail: <c:out value="${requestScope.email}" /> <li>Idade: <c:out value="${requestScope.idade}" /> </ul> </font> </body></html>