Módulo JSP Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] Índice Analítico 1. O QUE É JSP..............................................................................................................................................................1 2. INSTALANDO UM SERVIDOR JSP ......................................................................................................................2 3. SIMBOLOGIA - PARTE 1 .......................................................................................................................................4 4. SIMBOLOGIA - PARTE 2 .......................................................................................................................................7 5. COMANDOS LOOPS..............................................................................................................................................10 6. COMANDOS CONDICIONAIS.............................................................................................................................13 7. TRATANDO FORMULÁRIOS..............................................................................................................................16 8. OBJETOS IMPLÍCITOS - INTRODUÇÃO .........................................................................................................22 9. OBJETOS RELACIONADOS AO SERVLET .....................................................................................................23 10. OBJETOS RELACIONADOS A OUTPUT/INPUT DA PÁGINA......................................................................24 11. OBJETOS CONTEXTUAIS ...................................................................................................................................28 12. TRATAMENTO DE ERROS..................................................................................................................................33 13. JAVABEANS............................................................................................................................................................34 14. AÇÃO JSP:USEBEAN ............................................................................................................................................38 15. EXEMPLO – MINI APLICAÇÃO USANDO JAVABEANS ..............................................................................40 Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 1. O que é JSP JSP (Java Server Pages) é uma tecnologia para desenvolvimento de aplicações WEB semelhante ao Microsoft Active Server Pages (ASP), porém tem a vantagem da portabilidade de plataforma podendo ser executado em outros Sistemas Operacionais além dos da Microsoft. Ela permite que ao desenvolvedor de sites produzir aplicações que permitam o acesso a banco de dados, o acesso a arquivos-texto, a captação de informações a partir de formulários, a captação de informações sobre o visitante e sobre o servidor, o uso de variáveis e loops entre outras coisas. Quem conhece servlets verá que o JSP não oferece nada que você não possa conseguir com os servlets puros. O JSP, entretanto, oferece a vantagem de ser facilmente codificado, facilitando assim a elaboração e manutenção de uma aplicação. Além disso, essa tecnologia permite separar a programação lógica (parte dinâmica) da programação visual (parte estática), facilitando o desenvolvimento de aplicações mais robustas, onde programador e designer podem trabalhar no mesmo projeto, mas de forma independente. Outra característica do JSP é produzir conteúdos dinâmicos que possam ser reutilizados. Quando uma página JSP é requisitada pelo cliente através de um Browser, esta página é executada pelo servidor, e a partir daí será gerada uma página HTML que será enviada de volta ao browser do cliente. A figura abaixo ilustra esse funcionamento: Quando o cliente faz a solicitação de um arquivo JSP, é enviado um object request para a JSP engine. A JSP engine envia a solicitação de qualquer componente (podendo ser um JavaBeans component, servlet ou enterprise Bean) especificado no arquivo. O componente controla a requisição Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 1 possibilitando a recuperação de arquivos em banco de dados ou outro dado armazenado, em seguida, passa o objeto response de volta para a JSP engine. A JSP engine e o WEB server enviam a página JSP revisada de volta para o cliente, onde o usuário pode visualizar os resultados através do WEB browser. O protocolo de comunicação usado entre o cliente e o servidor pode ser HTTP ou outro protocolo. Por definição, JSP usa Java como sua linguagem de scripts. Por esse motivo, O JSP é apresenta mais flexível e mais robusto do que outras plataformas baseadas simplesmente em JavaScripts e VBScripts. Requisitos para entender JSP? Para tirar um bom proveito do JSP é preciso entender a linguagem Java. Isso porque, a parte lógica do JSP envolve Java Beans, Objetos JDBC, Enterprise Java Beans (EJB) entre outros componentes que interagem com a plataforma Java. Portanto, alertamos aqueles que pretendem desenvolver uma aplicação mais sofisticada que entedam um pouco de programação em Java. O ideal é que se conheça um pouco de HTML, pouco mesmo. É comum em grandes aplicações que o Programador JSP e o Designer sejam pessoas diferentes. Portanto, nesse curso, usamos pouquíssimas tags HTML, nossa preocupação está voltada para a parte lógica das aplicações e não para a parte visual. Nos próximos módulos você aprenderá como instalar um servidor JSP. Num módulo posterior, você iniciará a programação em JSP e aprenderá a simbologia dessa linguagem. 2. Instalando um servidor JSP Para conseguir ver os resultados das páginas que iremos construir nos próximos módulos desse curso, é preciso instalar na sua máquina um servidor JSP. Por se tratar de uma extensão ao modelo de programação Java, o JSP pode ser executado em qualquer plataforma. Existem diversos servidores JSP espalhados na WEB, alguns deles, dispõe de versões para plataforma Windows e Linux. Dois dos mais famosos são o Tomcat, do projeto Jakarta (http://jakarta.apache.org/tomcat) e o Resin da Empresa Caucho (www.caucho.com). Nesse módulo, iremos mostrar a instalação do "Tomcat" para a plataforma Windows NT ou 98/95, é bastante fácil de ser instalado e configurado. Se você nunca instalou um servidor na sua máquina, não se preocupe!!! Mostraremos passo a passo como fazer. Contudo, se você já é um cobra nessa área, um rápida lida na seção abaixo já será suficiente para preparar sua máquina para rodar páginas com scripts JSP. • Passo 1: Instalação da Máquina Virtual. Você necessitará, antes de tudo, ter a máquina virtual Java instalada (JDK Java Development Kit). Se você não tiver ainda o JDK instalado, faça o download através do site da Empresa Sun. (http://java.sun.com). Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 2 • Passo 2: Download do Servidor JSP. Você poderá fazer o download do servidor Tomcat no site da empresa "Jakarta" (http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.1.18/bin/jakarta-tomcat-4.1.18-LE-jdk14.exe). • Passo 3: Executar o arquivo de instalação. Você pode usar a instalação padrão, no final da instalação você de informar uma senha para o administrador do servidor. Após a instalação concluída, será gerado alguns atalhos dentre eles “Start Tomcat” e “Stop Tomcat”, copie estes dois atalhos para o seu desktop, para iniciar o servidor use o atalho “Start Tomcat”, para parar use o atalho “Stop Tomcat”. • Passo 4: Configurações default Tomcat. De acordo com a configuração original do Tomcat, os arquivos deverão estar nos seguintes diretórios: - arquivos *.jsp (páginas com scripts JSP): " C:\Arquivos de programas\Apache Group\Tomcat 4.1\webapps \sistema" - arquivos *class e *.java (classes utilizadas em beans): " C:\Arquivos de programas\Apache Group\Tomcat 4.1\webapps\sistema\WEBINF\classes\pacotes ". • Passo 5: Testando o Tomcat. Agora você deve testar o Tomcat. Abra o seu navegador e digite a url "http://localhost:8080". Se a página de apresentação da empresa Jakarta aparecer no seu navegador então a instalação do software ocorreu com sucesso. Sua máquina estará pronta para rodar páginas JSP. É necessário digitar a porta "8080" pois essa porta fica reservada para esse servidor. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 3 3. Simbologia - Parte 1 A maior parte do código de uma página JSP consiste em template text. O template text é similar ao HTML, obedecendo às mesmas regras de sintaxe e é simplesmente passado ao cliente por um servlet criado especialmente para manusear a página. Para construir uma aplicação usando JSP você geralmente escreve o texto HTML e inclue códigos JSP entre tags JSP. As tags normalmente começam com "<%" e terminam com "%>". Vamos mostrar o clássico exemplo do "Olá Mundo". <html> <body> <h1><%= request.getParameter("text") %></h1> </body> </html> Salve esse artigo com o nome "exemplo01.jsp". Para executar esse código basta digitar em seu browser a URL: ..exemplo01.jsp?text=Ola+Mundo. Perceba que foi possível passar o valor do objeto "text" como parâmetro na própria URL e o servidor de JSP montou o código. Se você verificar o código da página que apareceu no seu browser, verá o seguinte: <html> <body> <h1>Ola Mundo</h1> </body> </html> O que aconteceu foi que o servidor JSP executou os comandos entre as tags especiais "<%" e "%>", gerou e enviou para o browser um código HTML puro. JSP fornece cinco categorias de tags: diretivas, declarações, expressões, scriptlets e comentários. As diretivas serão tratadas na parte 2 desse módulo do curso. Vamos nos concentrar aqui no estudo das declarações, expressões, scriptlets e comentários. Os três primeiras têm sintaxes e usos similares, mas têm diferenças importantes. Vamos explicar, com alguns exemplos, as semelhanças e diferenças entre elas. Declarações (entre <%! and %>): As declarações são usadas para definir variáveis e métodos específicos para uma página JSP. Os métodos e variáveis declaradas podem então ser Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 4 referenciados por outros elementos de criação de scriptlets na mesma página. A cada declaração deve ser finalizada ou separada por "ponto-e-vírgula" e pode assumir a seguinte sintaxe: <%! declaration %> Veja alguns exemplos: <%! int i = 0; %> <%! int a, b; double c; %> <%! Circle a = new Circle(2.0); %> Você deve declarar uma variável ou um método antes de usá-lo. O escopo de uma declaração é geralmente o arquivo JSP, mas se for incluído outros arquivos com a diretiva include, o escopo se expande para o cover do arquivo incluído. Expressões (entre <%= e %>) Podem conter alguma expressão válida da linguagem de script usada nessa página (o padrão é que a Linguagem seja Java), mas sem ponto-e-vírgula. A sintaxe para este elemento de criação de scripts é a seguinte: <%= expression %> Veja alguns exemplos: <%= <%= <%= <%= Math.sqrt(2) %> items[i] %> a + b + c %> new java.util.Date() %> A expressão Java é avaliada (da esquesda para a direita), convertida em String e depois inserida na página. Essa avaliação é feita em tempo de execução (quando a página é solicitada) permitindo fácil e rápido acesso a informação que foi requisitada. Por exemplo, uma exibição de data e hora em que a página é acessada. Para construir uma expressão em JSP você pode colocar entre as tags qualquer expressão definida na Especificação da Linguagem Java. Ao contrário dos scriptlets (que veremos a seguir), uma expressão não aceita ponto e vírgula e define somente uma expressão da Linguagem. Veja um exemplo: Seu hostname: <%= request.getRemoteHost() %> Para simplificar as expressões, existem um número de variáveis predefinidas que você pode usar e que veremos a seguir. Scriptlets (entre <% e %>) Permitem você escrever trechos de código da Linguagem usada na página. Veja o exemplo abaixo: Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 5 <html> <body> . . . <% String option; int numberOption = Integer.parseInt(request.getParameter("option")); if (numberOption == 1) { option = "Compra"; } else if (numberOption == 2) { option = "Venda"; } else { option = "Aluguel"; } %> <font face="verdana, arial" size=5>Opção Escolhida: <%= option %> </font> . . . </body> </html> Lembre-se que em um script você deve finalizar as expressões através do uso de ponto-e-vírgula. Quando você escreve um script, você pode usar algum dos objetos implícitos do JSP ou das classes importadas através da diretiva page, variáveis ou métodos (declarados entre as tags <%! e %> ou objetos nomeados através da tag <jsp:useBean>. Para testar a página acima basta salvá-la com o nome de "classificados.jsp" e digitar a url ".../classificados.jsp?option=2". • Comentários Existem dois tipos principais de comentários que podem ser usados em uma página JSP: Comentário de Conteúdo: esses comentários são transmitidos de volta para o navegador como parte da resposta de JSP e são visíveis na visualização do código da página. O comentário de conteúdo tem a seguinte sintaxe: <!-- comment --> Aqueles familiarizados com HTML percebem que é a mesma sintaxe de comentário para essa linguagem de marcação. Tais comentários não produzem qualquer output visível, mas podem ser visualizados pelo usuário final através do item "view source" do navegador. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 6 Comentários JSP: não são enviados para o cliente e são visíveis apenas nos arquivos fonte JSP originais. O corpo do comentário é ignorado pelo container JSP. Os comentários JSP podem assumir duas sintaxes: <%-- comment --%> e <% /* comment */ %> Esse segundo comentário é introduzido dentro da página através de um scriptlets, usando a sintaxe de comentário nativa da linguagem de criação de scripts, no caso JAVA. 4. Simbologia - parte 2 As diretivas são usadas para fornecer informações especiais ao container JSP sobre a página JSP quando esta é compilada para servlet. As diretivas JSP afetam a estrutura global da classe servlet. Existem dois tipos principais de diretivas: - page: permite situações como importação de classes, customização de super classes servlet entre outras; - include: permite que seja inserido o conteúdo de um arquivo no servlet no momento em que o arquivo JSP é traduzido para servlet. 01. Diretiva page A diretiva page tem a seguinte sintaxe: <%@ page attribute1=valor1 attribute2=valor2 attribute3=... %> Abaixo relacionamos os atributos mais utilizados nas diretivas page: • Atributo import import="package.class" ou import="package.class1,...,package.classN". permite que seja especificado qual o pacote a ser importado. Por exemplo: <%@ page import="java.util.*" %> O atributo import attribute é o único que pode aparecer várias vezes. • Atributo isThreadSafe isThreadSafe="true|false". O valor de true (default) indica o processamento normal do servlet quando múltiplas requisições podem ser acessadas simultaneamente na mesma instância de servlet. O valor false indica que o servlet deve implementar SingleThreadModel, como requisição para cada requisição sinalizada ou com requisições simultâneas sendo uma em cada instância. • Atributo session Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 7 session="true|false". O valor de true (default) indica que a variável predefinida session (do tipo HttpSession) deve estar ligada a sessão existente, caso não exista uma sessão, uma nova sessão deve ser criada para ligá-la. O valor false indica que sessões não devem ser usadas. Aqui está a implementação do contexto. • Atributo buffer buffer="sizekb|none" Especifica o tamanho do buffer para o JspWriter out. O buffer padrão é definido pelo servidor. • Atributo autoFlush autoflush="true|false" O valor de true (default) indica se o buffer deve ser esvaziado quando estive cheio. O valor false, indica que uma exceção deve ser mostrada quando ocorrer overflows. • Atributo extends extends="package.class" Define se a super classe do servlet deve ser gerada. • Atributo info info="message" Define uma string que pode ser recuperada pelo método getServletInfo. Com esse atributo o autor pode adicionar uma cadeia de documentação à página que sumariza sua funcionalidade. O valor padrão para o atributo info é a cadeia vazia. • Atributo errorPage errorPage="url" Especifica que a página JSP deve processar algum Throwables, mas não carregá-lo na página corrente. • Atributo isErrorPage isErrorPage="true|false" Define se uma página pode atuar como uma página de erro para uma outra página JSP. O default é false. • Atributo language language="java" Especifica a linguagem que está sendo usada. Por enquanto o JSP suporta somente Java. 02. Diretiva include Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 8 A diretiva include permite que sejam incluídos arquivos na hora em que a página JSP é traduzida no servlet. Uma directive include é algo como: <%@ include file="relative url" %> Essa diretiva pode ser implementada de acordo com o seguinte exemplo: muitos sites têm uma barra de navegação em cada página. Devido a problemas com frames HTML isto é normalmente implementado com um tabela repetindo o código HTML em cada página do site. Esta directive supre essa necessidade de minimizar os esforços de manutenção conforme o código abaixo: <html> <%@ include file="navbar.html" %> <!-Parte específica da página ... --> </body> </html> Arquivo exemplo_02.jsp <font face="verdana" size=1 color="#ffffcc"> <a href="home.jsp">HOME</a> <a href="secao_01.jsp">SEÇÃO 01</a> <a href="secao_02.jsp">SEÇÃO 02</a> <a href="secao_02.jsp">SEÇÃO 02</a> </font> Arquivo navbar.html <html> <body> <font face="verdana" size=1 color="#ffffcc"> <a href="home.jsp">HOME</a> <a href="secao_01.jsp">SEÇÃO 01</a> <a href="secao_02.jsp">SEÇÃO 02</a> <a href="secao_02.jsp">SEÇÃO 02</a> </font> <!-Parte específica da página ... --> </body> </html> Código do arquivo "exemplo_02.jsp" visto pelo browser Apresentamos a seguir um resumo da sintaxe do JSP: Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 9 Declarações Expressões Scriptlet Comentário HTML Comentário JSP Diretiva "Include" Diretiva "Page" Diretiva Taglib <tagPrefix:name> <jsp:foward> Declara variáveis e métodos válidos no script daquela página. Contém uma expressão válida no script daquela página. Contém um fragmento de código válido no script daquela página. Cria um comentário que é enviado para o cliente viabilizar no código da página. É visto apenas no fonte do JSP mas não é enviado para o cliente. Inclue um arquivo estático, analisando os elementos JSP daquela página. <%! declaração; [declaração;]+ ... %> <%= expressão %> <% fragmento de um código com uma ou mais linhas %> <!-- comentário [<%= expressão %>] --> <%-- comentário --%> ou <% /* comentário */ %> <%@ include file="URL relativa" %> <%@ page [ atributo = valor(es) ] %> atributos e valores: - language="java" - extends = "package.class" - import = "{package.class" | package.* }, ..." ] - session = "true | false" - buffer = "none | 8kb | sizekb" Define atributos que serão aplicados a - autoFlush = "true | false" uma página JSP. - isThreadSafe = "true | false" - info = "text" - errorPage"relativeURL" - contentType = "{mimeType [; charset = characterSet ] text/html; charset = isso8859-1}" - isErrorPage = "true | false" Define uma biblioteca tag e um prefixo <%@ taglib uri="URIToTagLibrary" para uma tag padrão usada na página prefix="tagPrefix" %> JSP. <tagPrefix:name attribute="value" + ... > Acessa um padrão de funcionalidade de other tags and data uma tag. </tagPrefix:name> Redireciona uma requisição para um <jsp:forward page="{relativeURL | <%= arquivo HTML, JSP ou servlet para expressão %>}" processar. 5. Comandos Loops Essa lição trata as rotinas loop do Java que poderão ser usadas em páginas JSP. Três comandos serão tratados a seguir: • • • for; while; do .. while; • Loop For O loop for, repete uma instrução ou um bloco de instruções algum número de vezes até que a condição seja satisfeita. Loops for são freqüentemente usados para simples iterações na qual você repete um bloco de instruções um certo número de vezes e então pára; mas você pode usar loops for para qualquer espécie de loop. O código abaixo mostra um simples exemplo da utilização do laço foor: Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 10 Exemplo 01: <html> <body> <% for (int i = 2; i < 8 ; i++) { %> <font size=<%= i %>>Bom Dia!!! - Fonte: <%= i %></font> <% } %> </body> </html> • Loop While O loop while é usado para repetir uma instrução ou bloco de instruções até que uma condição particular seja verdadeira. Veja o código abaixo: Exemplo 2: <html> <body> <% int i = 0; while (i < 8) { %> <font size=<%= i %>>Bom Dia!!! - Fonte: <%= i %></font><br> <% i++; } %> </body> </html> Observe que se a condição é inicialmente falsa na primeira vez que é testada o corpo do loop while nunca será executado. Se você precisa executar o corpo, pelo menos uma vez, você pode usar o código do..while que será visto a seguir. • Loop Do...While O loop é exatamente como o loop while, exceto pelo fato de o loop do executar uma dada instrução ou bloco até que uma condição seja falsa. A diferença principal entre os dois é que os loops while testam a condição antes de iniciar o loop, tornando possível que o corpo do loop nunca seja executado caso a Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 11 condição seja inicialmente falsa. Os loops do...while executam pelo menos uma vez antes de testar a condição. Veja o exemplo abaixo: Exemplo 3: <html> <body> <% int i = 0; do { %> <font size=<%= i %>>Bom Dia!!! - Fonte: <%= i %></font><br> <% i++; } while (i < 8); %> </body> </html> • Interrupção de Loops Em todos os loops (for, while e do), o loop termina quando a condição que você está testando é atingida. Porém, em alguma situação, você desejará sair do loop antes do seu término normal. Para isso, você pode usar as palavras chaves break e continue. A palavra chave break pára imediatamente a execução do loop corrente. Se você tiver loops aninhados dentro de loop mais externo; caso contrário, o programa simplesmente continua a execução da próxima instrução após o loop. <html> <body> <% int j; for (int i = 1; i < 8 ; i++) { j = i%5; if (j == 0){ break; } %> <font size=<%= i %>>Bom Dia!!! - Fonte: <%= i %></font><br> <% } %> </body> </html> Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 12 No exemplo acima, o código dentro do loop é executado até que a variável i assuma um valor que seja divisível por 5. Quando isso ocorre, o loop é finalizado e o programa continua a ser executado após o final do código do loop. Nesse caso o resultado obtido foi uma a geração de quatro linhas de código html (ao invés de 7). Após gerar a página, o servidor JSP enviará para o navegador o seguinte código: <html> <body> <font size=1>Bom Dia!!! - Fonte: 1</font><br> <font size=2>Bom Dia!!! - Fonte: 2</font><br> <font size=3>Bom Dia!!! - Fonte: 3</font><br> <font size=4>Bom Dia!!! - Fonte: 4</font><br> </body> </html> 6. Comandos Condicionais Embora já possamos escrever algumas aplicações em JSP com o que já aprendemos até agora, elas serão ainda fracas. Um dos grandes potenciais de qualquer linguagem de programação, é a utilização de controles de fluxo (condicionais e loops) para executar diferentes partes de um programa baseado em testes. Nas próximas duas seções, aprenderemos os seguintes tópicos: • • comandos condicionais; comandos de loops. Como foi dito em lições anteriores, o JSP nos permite construir páginas unindo HTML e comandos Java. Mostraremos nessa lição como utilizar as conhecidas rotinas condicionais do Java em páginas JSP. Três comandos serão tratadas a seguir: if.. else, operador condicional, switch. • Comando IF Condicionais if contém a palavra-chave if, seguida de um teste booleano, e de uma instrução (na maioria das vezes um bloco de instruções) para ser executada se o teste for verdadeiro. Exemplo 01: Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 13 <html> <body> <%-- AS DUAS PROXIMAS LINHAS CRIA UMA VARIÁVEL QUE RECEBE O VALOR DA DATA ATUAL DO SERVIDOR --%> <% java.util.Date dateNow = new java.util.Date(); int hourNow = dateNow.getHours(); %> <%-- AS PROXIMAS LINHAS MISTURA HTML E JAVA E PRODUZ COMO RESULTADO UMA SAUDAÇÃO QUE DEPENDE DA HORA --%> <% if ((hourNow >= 5) && (hourNow < 13)) { %> <font face="verdana">Bom Dia!!!</font> <% } else if ((hourNow >= 13) && (hourNow < 19)) { %> < font face="verdana">Bom Tarde!!!</font> <% } else if ((hourNow >= 19) && (hourNow < 24)) { %> <font face="verdana">Bom Noite!!!</font> <% } else { %> <font face="verdana">Boa Madrugada!!!</font> <% } %> </body> </html> • Operador Condicional Uma alternativa para o uso das palavras-chaves if e else em uma instrução condicional é usar o operador condicional, algumas chamado de operador ternário. O operador ternário é uma expressão, significando que ele devolve um valor (diferentemente do if mais geral, o qual pode resultar em qualquer instrução ou bloco sendo executado). O operador ternário é muito útil para condicionais muito curtos ou simples, e tem a seguinte formato: test ? trueResult : falseResul O teste é uma expressão que devolve true e false (semelhante ao teste da instrução if). Se o teste for verdadeiro retorna o valor de trueResult, caso contrário, devolve o valor de falseResult. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 14 Vamos como podemos usar o operador condicional para obter o mesmo efeito do código anterior: Exemplo 2: <html> <body> <%-- AS DUAS PROXIMAS LINHAS CRIA UMA VARIÁVEL QUE RECEBE O VALOR DA DATA ATUAL DO SERVIDOR --%> <% java.util.Date dateNow = new java.util.Date(); int hourNow = dateNow.getHours(); %> <% String mensagem; mensagem = ((hourNow < 12)? "Onde você vai almoçar hoje?" : "Onde você almoçou hoje?"); %> <font face="verdana">Olá, Tudo bem? <%= mensagem %></font> </body> </html> Apesar deste código parecer, a uma primeira vista, um pouco menos fácil de entender que o anterior, ele é menor e portanto mais prático. • Condicionais Switch Na instrução switch, o teste (um tipo primitivo de byte, char, short ou int) é comparado com cada valor em questão. Se um valor coincidente é achado, a instrução (ou instruções) depois do teste é executada. Se nenhum valor for encontrado, a instrução default é executada. Vamos analisar o exemplo abaixo: Exemplo 3: <html> <body> <%-- AS DUAS PROXIMAS LINHAS CRIA UMA VARIÁVEL QUE RECEBE O VALOR DA DATA ATUAL DO SERVIDOR --%> Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 15 <% java.util.Date dateNow = new java.util.Date(); int monthNow = (dateNow.getMonth()+1); %> <% String mes; switch(monthNow){ case 1: mes="Janeiro"; break; case 2: mes="Fevereiro"; break; case 3: mes="Março"; break; case 4: mes="Abril"; break; case 5: mes="Maio"; break; case 6: mes="Junho"; break; case 7: mes="Julho"; break; case 8: mes="Agosto"; break; case 9: mes="Setembro"; break; case 10: mes="Outubro"; break; case 11: mes="Novembro"; break; default: mes="Dezembro"; break; } %> <font face="verdana"> Nós estamos em <%= mes %></font> </body> </html> Esse código atribui a variável monthNow o valor do mês atual. Note que na instrução nós incrementamos o mês em uma unidade porque o método "getMonth()" retorna 0 para o mês de janeiro, 1 para fevereiro e assim por diante. Observe que a limitação significativa no Java é que os testes e valores podem ser somente de tipos primitivos. Você não pode usar tipos primitivos maiores (long, float) ou objetos dentro de um switch, nem pode testar para nenhuma outra relação senão a igualdade. Isso limita a utilidade do switch para todos os casos exceto os mais simples, if´s aninhados podem funcionar para qualquer espécie de teste em qualquer tipo. 7. Tratando Formulários Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 16 Os formulários são ferramentas úteis e muito usada em diversas aplicações: cadastro registros em um banco de dados, validação de um login/senha, envio de email, envio de dados de um pesquisa, etc. Hoje é difícil desenvolver uma aplicação para Web que não exija o uso de formulários. Pois bem, na lição de hoje vamos aprender manipular formulários em aplicações JSP. Apresentamos abaixo um código para mostrar o formato de um formulário HTML e de seus objetos. <html> <body> <!-- cabeçalho do formulário --> <form name="nomedoformulario" action="paginajsp.jsp" method="get"> <!-- caixa de texto --> <input type="text" name="variavel1" size=40 maxlength=40> <!-- caixa de texto para senha --> <input type="password" name="variavel2" size=40 maxlength=40> <!-objeto do tipo radio --> <input type="radio" name="variavel2" value="valordavariavel">Texto da Varivavel 2 <!-objeto do tipo checkbox --> <input type="checkbox" name="variavel3" value="xxxxx"> Texto da Varivavel 3 <!-objeto do tipo select --> <select name="variavel4"> <option value="valor1">Valor 1 <option value="valor2">Valor 2 <option value="valor3">Valor 3 </select> <!- area de texto --> <textarea name="variavel5" cols=40 rows=2> Texto da Variavel 5 </textarea> <!- objeto hidden, para enviar dados que o usuário não vê no formulário --> <input type="hidden" name="asd" value="asd"> <!- botão --> <input type="button" value="textodobotao"> Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 17 <!- botao de limpar informações do formulário --> <input type="submit" value="limpar"> <!- botao de enviar formulário --> <input type="submit" value="ok"> <!- imagem colocada para funcionar com botao de envio de formulário --> <input type="image" src="pathdaimage/image.gif"> <!- objeto para anexar arquivo --> <input type="file" name="asdas" accept="asd"> </form> </body> </html> É importante fazermos algumas observações a cerca do código acima: - no cabeçalho do formulário, indicamos através de action="pathdoarquivo/paginajsp.jsp" o arquivo JSP que receberá os seus dados. - cada objeto do formulário recebe um nome. Deve-se tomar bastante cuidado ao nomear tais objetos, isto porque, como sabemos, as variáveis Java são sensíveis maiúscula/minúscula. Portanto, os objetos: <input name="variavel1" type="text" value=""> <input name="Variavel1" type="text" value=""> São objetos diferentes porque receberam nomes diferentes (variavel1 e Variavel1). Mostraremos mais um exemplo (bastante simples) de como enviar dados a partir de um formulário a uma página JSP. <%-- Arquivo teste.jsp --%> <html> <body> <center><h1> <%= request.getParameter("teste") %> </h1></center> <form action="teste.jsp" method=get> <input type="text" name="teste" size=40 maxlength=40><br> <input type="submit" value="enviar"> Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 18 </form> </body> </html> A página jsp acima, chamada "teste.jsp", contém um formulário que envia para ela mesma. O valor digitado em uma caixa de texto será mostrado como título da página. Observe como fizemos isso: - a página para qual nós enviaremos os dados do formulário é designada no cabeçalho do formulário: <form action="teste.jsp" method=get> - o nome do objeto caixa de texto caixa de texto ("teste") é usado na expressão request.getParameter("teste"). Note que se usássemos request.getParameter("Teste") (com T maiúsculo), a página não iria retornar o valor digitado na caixa de texto. O próximo exemplo é formado por dois arquivos. O primeiro pode contém apenas códigos HTML e o segundo contém códigos HTML e JSP. Arquivo "envia_mês.htm": <html> <body> <h3>Qual o mês do seu aniversário?</h3> <form action="recebe_mes.jsp" method=get> <select name="mesNasceu"> <option value="1">Janeiro <option value="2">Fevereiro <option value="3">Março <option value="4">Abril <option value="5">Maio <option value="6">Junho <option value="7">Julho <option value="8">Setembro <option value="9">Agosto <option value="10">Outubro <option value="11">Novembro <option value="12">Dezembro </select> <input type="submit" value="enviar"> </form> </body> Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 19 </html> Arquivo "recebe_mês.jsp": <%@ page import=java.util.Date %> <%@ page import=java.lang.String %> <% String msg = ""; String mesString = request.getParameter("mesNasceu"); int mes = Integer.parseInt(mesString); Date dateNow = new Date(); int monthNow = dateNow.getMonth() + 1; mes -= monthNow; if (mes == 1) msg = "Falta apenas "+ mes +" mês para o seu aniversário."; if (mes == -1) msg = "Seu aniversário foi no mês passado"; if (mes > 1) msg = "Faltam "+ mes +" meses para o seu aniversário."; if (mes == 0) msg = "Oba... estamos no mês do seu aniversário."; else if (mes < 1) { mes *= -1; msg = "Seu aniversário foi a "+ mes +" meses atrás."; } %> <html> <body> <center> <h3><%= msg %></h3> <br><br><br> <a href="Javascript:history.back(-1)">voltar</a> </center> </body> </html> Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 20 O exemplo acima é um pouco menos simples que o primeiro. O arquivo "envia_mes-jsp" contém um formulário com um objeto select que envia o mês que a pessoa nasceu. Após escolher o mês e clicar no botâo "ok", o formulário chama a página "recebe_mês.jsp" e envia seus dados para ela. Esta segunda página é um pouco menos simples que a primeira. Vamos analisar o que ela faz: - nas primeira linhas utilizamos as tags "page import" para indicar quais classes iremos utilizar em nossa página: <%@ page import=java.util.Date %> <%@ page import=java.lang.String %> - cinco objetos são criados e inicializados. - Usamos o método "request.getParameter(´nomedoparametro´)" com a finalidade de pegar o valor passado para a página através de algum formulário ou passando diretamente em sua URL. O segundo objeto foi inicializado utilizando esse método para pegar o valor passado pelo formulário: String mesString = request.getParameter("mesNasceu"); - O valor passado através de um formulário ou através da URL da página é sempre do tipo String. Ao inicilizarmos o terceiro objeto, o método "Integer.parseInt(variavelString)" transformou o valor contido na variável mesString em Inteiro. int mes = Integer.parseInt(mesString); - O penúltimo objeto criado é do tipo Date (daí a importância de termos importado a classe java.util.Date na primeira linha de nossa página). Ele é inicializado com a hora local do servidor. Date dateNow = new Date(); - Na inicialização do último objeto utilizamos o método "dateNow.getMonth()" que retorna um inteiro indicando o valor da variável. Somamos 1 ao valor retornado a partir desse método porque ele retorna 0 para janeiro, 1 para fevereiro e assim por diante. int monthNow = dateNow.getMonth() + 1; - Cinco teste são efetuados dentro de um script (<% e %>). Eles são usados para definir o valor que a variável "msg" terá, ou seja, a partir dos testes, decidiremos qual mensagem será exibida na tela. - Após efetuar os testes, o texto HTML é inserido na página. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 21 - Uma expressão (<%= %>) é usada para exibir o valor da variável "msg": <%= msg %> 8. Objetos Implícitos - Introdução Como já vimos anteriormente, podemos criar, dentro de scriptlets na página JSP, instâncias de uma classe Java e manipulá-las a fim de produzir conteúdo dinâmico. Por exemplo, podemos criar um objeto de uma classe que acessa uma base de dados e então usar métodos desse objeto para exibir na página uma consulta ou transação com a base de dados. Ou seja, através da manipulação desse objeto, quer seja acessando seus métodos e suas variáveis, podemos gerar conteúdo dinâmico para a página JSP. Além de objetos como esses, que estão completamente sobre o controle do programador, o container JSP se encarrega de instanciar automaticamente, durante a execução de uma página JSP, alguns objetos. Tais objetos podem ser usados dentro da página JSP e são conhecidos como "Objetos Implícitos". Assim como todo objeto em Java, cada objeto implícito é uma instância de uma classe ou interface e segue uma API correspondente. Abaixo segue um resumo dos objetos implícitos disponíveis em JSP, suas respectivas classes/interfaces e uma pequena descrição do objeto. Objetos implícitos de JSP e suas APIS para aplicações de HTTP. Objeto Classe ou Interface Descrição Page Config Request Response Out Session Application javax.servlet.jsp.HttpJspPage javax.servlet.ServletConfig javax.servlet.http.HttpServletRequest javax.servlet.http.HttpServletResponse javax.servlet.jsp.JspWriter javax.servlet.http.HttpSession javax.servlet.ServletContext PageContext Exception javax.servlet.jsp.PageContext javax.lang.Throwable Instância de servlet da página Dados de configuração de servlet Dados de solicitação, incluindo parâmetros Dados de resposta Fluxo de saída para conteúdo da página Dados de sessão específicos de usuário Dados compartilhados por todas as páginas de aplicação Dados de contexto para execução da página Erros não capturados ou exceção Os nove objetos implícitos fornecidos por JSP podem ser classificados da seguinte forma: • Objetos relacionados ao servlet da página (page, config): Os dois objetos implícitos de JSP nesta categoria se baseiam na implementação da página JSP como um servlet. • Objetos relacionados ao output e input da página (request, response, out): Os objetos classificados nessa categoria se concentram na entrada e saída (input/output) de uma página JSP. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 22 • Objetos contextuais (application, session, request, pageContext): Os objetos implícitos dessa categoria fornece à página JSP acesso ao contexto dentro do qual ela está respondendo. • Objetos resultantes de erros (exception): Esta última categoria dos objetos implícitos fornece apenas um objeto que é usado no tratamento de erros dentro de uma página JSP. Esse módulo do curso sobre Objetos Implícitos foi dividido em seis partes. Nas quatro primeiras serão abordadas as categorias de objetos implícitos listadas acima. As duas últimas trazem exemplos práticos do uso dos objetos implícitos: Parte 1 - Objetos Relacionados a Servlets Parte 2 - Objetos Relacionados a Input/Output da página Parte 3 - Objetos Contextuais Parte 4 - Objetos de Tratamento de Erro Parte 5 - Criando funções que manipulam objetos implícitos Parte 6 - Exemplos do uso de Objetos Implícitos 9. Objetos Relacionados ao Servlet Os objetos implícitos nesta categoria se baseiam na implementação da página JSP como um servlet. Os dois objetos classificados nessa categoria são: page config • Objeto page O objeto page representa a própria página JSP ou, mais especificamente, uma instância da classe de servlet na qual a página foi traduzida. O objeto page implementa as interfaces javax.servlet.jsp.HttpJspPage e javax.servlet.jsp.JspPage. Abaixo estão os links para a API que define essas interfaces: HttpJspPage JspPage Exemplo utilizando o objeto implícito page: <%@ page info="Página de Teste" %> ..... <%= ((javax.servlet.jsp.HttpJspPage)page).getServletInfo() %> • Objeto config Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 23 O objeto config armazena dados de configuração de servlet - na forma de parâmetros de inicialização - para o servlet na qual uma página JSP é compilada. Pelo fato das páginas JSP raramente serem escritas para interagir com parâmetros de inicialização, este objeto implícito raramente é usado na prática. O objeto config é uma intância da interface javax.servlet.ServletConfig. Os métodos fornecidos por esta interface para recuperar parâmetros de inicialização de servlet estão listados abaixo: Métodos Enumeration getInitParameterNames() String getInitParameter(String name) Descrição Recupera os nomes de todos os parâmetros de inicialização. Recupera o valor do parâmetro de inicilização a partir de um nome. Abaixo estão os links para a API que define a interface javax.servlet.ServletConfig: ServletConfig 10. Objetos Relacionados a OutPut/InPut da página Os objetos classificados nessa categoria se concentram no input (entrada de dados) e output (saída de informação) de uma página JSP. Os três objetos classificados nessa categoria são: • • • request response out • Objeto request O objeto request representa a solicitação que requisitou a página. O objeto request implementa a interface javax.servlet.http.HttpServletRequest (subinterface de javax.servlet.ServletRequest). Esse objeto, que também é classificado como um objeto contextual, é um dos mais complexos e mais utilizados na construção de páginas JSP. Podemos dividir os métodos desse objeto em quatro funcionalidades: Armazenar e Recuperar valores de atributos: Método Descrição Void setAttribute(String key, Object value) Enumeration getAttributeNames() Object getAttribute(String key) void removeAttribute(String key) Associa um valor de atributo com um nome. Recupera os nomes de todos os atributos associados com o objeto. Recupera o valor de atributo associado com a chave. Remove o valor de atributo associado com a chave. Recuperar parâmetros de solicitação e cabeçalho de HTTP: Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 24 Métodos Descrição Enumeration getParameterNames() String getParameter(String name) String[] getParameterValues(String name) Retorna os nomes de todos os parâmetros de solicitação. Retorna os primeiro valor (principal) de um único parâmetro de solicitação. Recupera todos os valores para um único parâmetro de solictação. Recuperar cabeçalhos de solicitação e cabeçalhos de HTTP: Métodos Descrição Recupera os nomes de todos os cabeçalhos associados com a solicitação. Retorna o valor de um único cabeçalho de solicitação, como uma cadeia. Retorna todos os valores para um único cabeçalho de solicitação. Retorna o valor de um único cabeçalho de solicitação, com um número inteiro. Retorna o valor de um único cabeçalho de solicitação, como uma data. Recupera todos os cookies associados com a solicitação. Enumeration getHeaderNames() String getHeader(String name) Enumeration getHeaders(String name) Int getIntHeader(String name) Long getDateHeader(String name) Cookies[] getCookies() Diversos métodos da interface que javax.servlet.hhtp.HttpServletRequest: Métodos Descrição String getMethod() String getRequestURI() Retorna o método de HTTP (e.g, POST, GET, etc) para a solicitação. Retorna o URL de solicitação (não inclui a cadeia de consulta). Retorna a cadeia de consulta que segue o URL de solicitação, se houver algum. Recupera os dados da sessão para a solicitação (i.e, o objeto implícito session). Recupera os dados da sessão para a solicitação (i.e, o objeto implícito session), opcionalmente criando-o se ele ainda não existir. Cria um dispatcher de solicitação para o URL local indicado. String getQueryString() HttpSession getSession() HttpSession getSession(boolean flag) RequestDispatcher getRequestDispatcher(String path) String getRemoteHost() String getRemoteAddr() String getRemoteUser() Retorna o nome totalmente qualificado do host que enviu a solicitação. Retorna o endereço de rede (IP) do host que enviou a solicitação. Retorna o nome do usuário que enviou a solicitação, se conhecido. Abaixo estão os links para a API que define essas interfaces: ServletRequest HttpServletRequest Exemplo utilizando o objeto implícito request: ..... Seu IP é :<%= request.getRemoteAddr() %><br> Seu Host é :<%= request.getRemoteHost() %><br> ..... • Objeto response O objeto response representa a resposta que será enviada de volta para o usuário como resultado do processamento da página JSP. Este objeto Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 25 implementa a interface javax.servlet.http.HttpServletResponse que é uma subinterface de javax.servlet.ServletResponse. Podemos dividir os métodos desse objeto em quatro funcionalidades: Especificar o tipo de conteúdo e codificação da resposta: Métodos Descrição Void setContentType(String type) String getCharacterEncoding() Define o tipo MIME e, opcionalmente, a codificação de caracteres do conteúdo da resposta. Retorna o conjunto de estilos de codificação de caracteres para o conteúdo da resposta. Definir cabeçalhos da resposta: Métodos Descrição Void addCookies(Cookie cookie) Boolean containsHeader(String name) Adiciona o cookie especificado. Verifica se a resposta inclui o cabeçalho. Atribui o valor definido pela variável "value" ao cabeçalho Void setHeader(String name, String value) especificado por "name" Atribui o valor de número inteiro especificado por "value" ao Void setIntHeader(String name, int value) cabeçalho especificado por "name" Atribui o valor de data especificado por "value" ao cabeçalho Void setDateHeader(String name, long date) especificado por "name" Adiciona o valor definido por "value" ao cabeçalho especificado Void addHeader(String name, String value) por "name" Adiociona o valor de número inteiro especificado por "value" Void addIntHeader(String name, int value) ao cabeçalho especificado por "name" Void addDateHeader(String name, long Adiciona o valor de data especificado por "value" ao cabeçalho date) especificado por "name" Definir códigos de resposta: Métodos Descrição Void setStatus(int code) Void sendError(int msg) status, Define o código de status para a resposta (para cisrcuntâncias sem erro) String Define o código de status e mensagem de erro para a resposta. Void sendRedirect(String url) Reescrita da URL: Métodos String encodeRedirectURL(String url) String encodeURL(String url) Envia uma resposta para o navegador indicando que ele deveria solicitar um URL alternativo (absoluto) Descrição Codifica um URL para uso com o método sendRedirect() para incluir informações de sessão. Codifica um URL usado em um link para incluir informações de sessão. Abaixo estão os links para a API que define essas interfaces: ServletResponse HttpServletResponse O exemplo abaixo ilustra uma das utilidades desse objeto. Vários cabeçalhos são definidos para evitar que a página seja armazenada em cache por um navegador. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 26 <% response.setHeader("Expires", 0); response.setHeader("Pragme, "no-cache"); if(request.getProtocol().equals("HTTP/1.1")){ response.setHeader("Cache-Control", "no-cache"); } %> Este script primeiro define o cabeçalho Expires para uma data no passado. Isto significa que o conteúdo da página já expirou, como uma dica que seu conteúdo não deve ser armazenado em cache. • Objeto out Este objeto implícito representa o fluxo de saída para a página, cujo conteúdo será enviado para o navegador com o corpo de sua resposta. O objeto out é uma intância da classe javax.servlet.jsp.JspWriter. Esse objeto implementa todos os métodos print() e println() definidos por java.io.Writer. Por exemplo, o objeto out pode ser usado dentro de um script para adicionar conteúdo à página gerada. Veja o exemplo abaixo: <% int i = (int)(Math.random()*10); if(i%2==0){ out.print("O Número escolhido "+ i +" é par!"); } else { out.print("O Número escolhido "+ i +" é impar!"); } %> Esse objeto é muito utilizado para para gerar conteúdo dentro do corpo de um script, sem ter que fechá-lo temporariamente para inserir conteúdo de página estático. Contudo, deve-se evitar usar os métodos print() ou println() para inserir cadeias de caracteres muito grandes. No próximo caso, é mais aconselhável fechar o script e inserir o conteúdo estático. Veja o exemplo abaixo: Não Aconselhável: <% if(i == 1){ out.print("<h6>"+ "<font face='verdana'>"+ "Guga viaja nesta sexta"+ Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 27 "para a Suíça para"+ "jogar"+ "</font>"+ "</h6>"); } %> Aconselhável: <% if(i == 1) {%> <h6> <font face='verdana'> Guga viaja nesta sexta para a Suíça para jogar </font> </h6> <% } %> O links abaixo refere-se a API que define a interfaces que o objeto out implementa: JspWriter 11. Objetos Contextuais Os objetos implícitos dessa categoria fornece à página JSP acesso ao contexto dentro do qual ela está respondendo. Os quatro objetos implícitos contextuais são: • • • • request; session; application; pageContext. Todos eles têm a capacidade de armazenar e recuperar valores de atributos arbitrários. Os atributos de página, armazenados no objeto pageContext, duram apenas enquanto o processamento de uma única página ocorre. Os atributos de solicitação, armazenados no objeto request, também tem pouca duração, mas podem ser transferidos entre páginas quando for transferido o controle. Os atributos de sessão, armazenados no objeto session, duram enquanto o usuário continuar a interagir com o servidor da web. Os atributos de aplicação, armazenados no objeto application, são mantidos enquanto o container JSP mantiver uma ou mais páginas de uma aplicação carregada na memória - enquanto o container JSP estiver rodando. A tabela a seguir traz os Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 28 métodos comuns aos quatro objetos e que são usados para armazenar e recuperar valores de atributos: Tabela 1: Os métodos comuns a esses quatro objetos e que são usados para armazenar e recuperar valores de atributos: Métodos Descrição void setAttribute(String key, Object value) Enumeration getAttributeNames() Object getAttribute(String key) void removeAttribute(String key) Associa um valor de atributo com um nome. Recupera os nomes de todos os atributos associados com o objeto. Recupera o valor de atributo associado com a chave. Remove o valor de atributo associado com a chave. • Objeto session Este objeto representa a sessão atual de um usuário individual. Todas as solicitações feitas por um usuário são consideradas parte de uma sessão. Desde que novas solicitações por aqueles usuários continuem a ser recebidas pelo servidor, a sessão persiste. Se, no entanto, um certo período de tempo passar sem que qualquer nova solicitação do usuário seja recebida, a sessão expira. O objeto session armazena informações a respeito da sessão. Um dos principais usos para o objeto session é armazenar e recuperar valores de atributos, a fim de transmitir as informações específicas de usuários entre as páginas. Abaixo segue um exemplo que armazena dados na sessão, na forma de um objeto que é instância de uma classe hipotética "Usuario": <% Usuario u = new Usuario(nome, senha); session.setAttribute("usuario", u); %> Uma vez que um objeto tenha sido armazenado através do método setAttibute(), ele pode ser recuperado - na mesma página ou em outra acessada pelo usuário. O código abaixo ilustra a recuperação do objeto armazenado no código anterior: <% Usuario u = (Usuario)session.getAttribute("usuario"); ..... %> Perceba que o método getAttribute() retorna um objeto da classe Object, portanto, é necessário fazermos um cast para converter o objeto retornado em uma instância da classe desejada. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 29 O objeto session implementa a interface javax.servlet.http.HttpSession. A tabela abaixo traz os principais métodos utilizados por esse objeto, além daqueles descritos anteriormente na tabela 1: Métodos Descrição Object getAttibute(String nome) String getId() long getCreationTime() long getLastAccessedTime() int getMaxInactiveInterval() void setMaxInactiveInterval(int time) boolean isNew() boolean invalidate() Recupera o objeto identificado por "nome". Retorna o Id da sessão. Retorna a hora na qual a sessão foi criada. Retorna a última vez que uma solicitação associada com a sessão foi recebida. Retorna o tempo máximo (em segundos) entre solicitações pelo qual a sessão será mantida. Define o tempo máximo (em segundos) entre solicitações pelo qual a sessão será mantida. Retorna se o navegador do usuário ainda não tiver confirmado o ID de sessão. Descarta a sessão, liberando quaisquer objetos armazenados como atributos. O link abaixo exibe a API completa da interface que implementa o objeto session: HttpSession • Objeto application Este objeto representa a aplicação à qual a página JSP pertence. Ele é uma instância da interface javax.servlet.ServletContext. Os containers JSP tipicamente tratam do primeiro nome de diretório em um URL como uma aplicação. Exemplo: • • • • http://server/dbsystems/index.jsp http://server/dbsystems/principal.jsp http://server/dbsystems/forum/forum.jsp http://server/dbsystems/apostila/apostila.jsp São todos considerados parte da mesma aplicação dbsystems. Além dos métodos descritos na tabela 1, os métodos do objeto application podem ser divididos em quatro funcionalidades: Recuperar informações de versão do container servlet: Método Descrição String getServerInfo() int getMajorVersion() int getMinorVersion() Retorna o nome e versão do container servlet. Retorna a versão principal da API do servlet para o container servlet. Retorna a versão secundária da API do servlet para o container servlet. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 30 Interagir com arquivos e caminhos no servidor: Método Descrição Retorna o tipo MIME para o arquivo indicado, se conhecido pelo servidor. Traduz uma cadeia especificando um URL em um objeto URL getResource(String path) que acessa os conteúdos dos URLs, localmente ou na rede. Traduz uma cadeia especificando um URL em um fluxo de InputStream getResourceAsStream(String path) entrada para ler seu conteúdo. Traduz um URL local em um nome de caminho no sistema String getRealPath(String path) de arquivo local. Retorna o contexto de aplicação para o URL local ServletContext getContext(String path) especificado. RequestDispatcher getRequestDispatcher(String Cria um dispacher de solicitação para o URL local indicado. path) String getMimeType(String filename) Suporte para log de mensagens: Método Descrição Void log(String message) Grava a mensagem o arquivo de log. Grava a mensagem no aqrquivo de log, junto com a trilha de pilha para a exceção especificada. Void log(String message, Exception e) Acessar parâmetros de inicialização: Método Descrição Enumerations getInitParameterNames() String getInitParameter(String name) Recupera os nomes de todos os parâmetros de inicialização. Recupera o valor do parâmetro de inicilização como o nome dado. O link abaixo exibe a API completa da interface que implementa o objeto application: ServletContext • Objeto pageContext O objeto pageContext fornece várias facilidades como gerenciamento de sessões, atributos, páginas de erro, inclusões e encaminhamento de requisições de fluxo de resposta. O objeto pageContext é uma instância da classe javax.servlet.jsp.PageContext. Além dos métodos descritos na tabela 1, os principais métodos desse objeto podem ser divididos em três categorias: Acessar outros objetos implícitos de JSP: Método Descrição Object getPage() ServletRequest getRequest() ServletResponse JspWriter getOut HttpSession getSession() ServletConfig getServletConfig() ServletContext getServletContext() Exception getException() Retorna a instância de servlet para a página atual (objeto implícito page). Retorna a solicitação que iniciou o processamento da página (objeto implícito request). Retorna a resposta para a página (objeto implícito response). Retorna o fluxo de saída atual para a página (objeto implícito out). Retorna a sessão associada com a solicitação da página atual, se houver alguma (objeto implícito session). Retorna o objeto de configuração de servlet (objeto implícito config). Retorna o contexto no qual o servlet da página roda (objeto implícito application). Para páginas de erro, retorna a exceção passada para a página (objeto implícito exception). Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 31 Envio de solicitações de uma página JSP para outra: Método Descrição void forward(String path) void include(String path) Encaminha o processamento para um outro URL local dado pela String path. Inclui o output do processamento de um outro URL local. Acessar atributos através de múltiplos escopos: Método Descrição void setAttribute(String key, Object obj, int scope) Enumeration getAttributeNamesInScope(int scope) Object getAttribute(String name, int scope) removeAttribute(String name, int scope) Object findAttribute(String name) int getAttributesScope(String name) Associa o valor do atributo "obj" com a chave "key" no escopo "scope". Recupera os nomes de todos os atributos associado com "key" no escopo "scope". Recupera o valor de tributo associado com "name" no escopo "scope" Remove o valor de atributo associado com "name" no escope "scope" Procura em todos os escopos pelo atributo associado com "name". Retorna o escopo no qual o atributo associado com "name" está armazenado. Os últimos dois métodos listados na tabela anterior permitem a procura, através de todos os escopos definidos, por um atributo associado com uma String passada como parâmetro. Nos dois casos, o objeto pageContext irá realizar uma busca através dos escopos na seguinte ordem: pageContext, request, session e application. A tabela anterior traz métodos que recebe parâmetros para especificar o escopo. A classe javax.servlet.jsp.PageContext fornece variáveis estáticas para representar estes quatro escopos diferentes. A tabela a seguir resume estas variáveis: Variável Descrição PAGE_SCOPE REQUEST_SCOPE SESSION_SCOPE APPLICATION_SCOPE Escopo Escopo Escopo Escopo para para para para atributos atributos atributos atributos armazenados armazenados armazenados armazenados no no no no objeto objeto objeto objeto pageContext. request. session. application. O exemplo abaixo ilustra o uso do método "getAttribute" e das variáveis estáticas descritas na tabela anterior: <% User uPag=(User)pageContext.getAttibute("user",pageContext.PAGE_SCOPE) //Recupera o object "usuario" do escopo pageContext User uReq=(User)pageContext.getAttibute("user",pageContext.REQUEST_SCOPE) //Recupera o object "usuario" do escopo request User uSes=(User)pageContext.getAttibute("user",pageContext.SESSION_SCOPE) Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 32 //Recupera o object "usuario" do escopo session User uApp=(User)pageContext.getAttibute("user",pageContext.APPLICATION_SCOPE ) //Recupera o object "usuario" do escopo application %> O link abaixo exibe a API completa da interface que implementa o objeto pageContext: PageContext 12. Tratamento de Erros Esta última categoria dos objetos implícitos tem apenas um membro, o objeto exception. Este objeto implícito é fornecido com o propósito de tratamento de erros dentro de uma página JSP. • Objeto Exception O objeto exception não está automaticamente disponível em todas as páginas JSP. Este objeto está disponível apenas nas páginas que tenham sido designadas como páginas de erro, usando o atributo isErrorPage configurado com true na diretiva page. O objeto exception é uma instância da classe java.lang.Throwable correspondente ao erro não capturado que fez com que o controle fosse transferido para a página de erro. Os principais métodos da classe java.lang.Throwable que são utilizados dentro das páginas JSP são listados na tabela abaixo: Método Descrição String getMessage() void printStackTrace(PrintWriter out) String toString() Retorna a mensagem de erro descritiva associada com a exceção quando ela foi lançada. Imprime a pilha de execução em funcionamento quando a exceção foi lançada para o fluxo de saída especificado pelo parâmetro out. Retorna uma cadeia combinando o nome da classe da exceção com sua mensagem de erro, se houver alguma. O trecho abaixo ilustra o uso do objeto exception em uma página de erro JSP: <@ page isErrorPage=true %> <h1>Erro Encontrado</h1> O seguinte erro foi eoncontrado:<br> <b><%= exception %></b><br> <% exception.printStackTrace(out); %> Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 33 13. JavaBeans JavaBeans são componentes de software que são projetados para serem unidades reutilizáveis, que uma vez criados podem ser reusados sem modificação de código, e em qualquer propósito de aplicação, seja um applet, um servlet ou qualquer outra. Um modelo de componente é definido como um conjunto de classes e interfaces na forma de pacotes Java que deve ser usado em uma forma particular para isolar e encapsular um conjunto de funcionalidades. Os componentes JavaBeans são também conhecidos como Beans. Passaremos a usar esta nomenclatura no restante deste curso. Neste curso não falaremos sobre todos os conceitos de JavaBeans, daremos atenção àqueles conceitos que mais são utilizados nas páginas JSP. Regras para Escrever Beans Para que esses componentes possam ser reconhecidos de forma geral, sua implementação deve seguir um conjunto de regras que serão usadas pelas ferramentas para introspecção da classe, ou seja, o processo de descobrir quais as funcionalidades do Bean e disponibilizá-la para o usuário. Cabe ao usuário fazer a interface entre o componente e o restante da aplicação, criando assim um novo tipo de programador, o programador de componenetes. import java.io.Serializable; 01 public class MyBean implements Serializable { 02 03 private int property1; 04 private boolean property2; 05 06 public MyBean() { 07 08 } 09 10 public void setProperty1(int property1) { 11 this.property1 = property1; 12 } 13 14 public void setProperty2(boolean property2) { 15 this.property2 = property2; 16 } Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 34 17 18 19 20 21 22 23 24 25 } public int getProperty1() { return property1; } public boolean isProperty2() { return property2; } Esta classe é um exemplo do que devemos seguir para tornar uma classe um bean, ou seja, o conjunto de regras que devemos obdecer para tornar o compoenente reconhecível por ferramentas e usável. Um bean, como modelo de componente, usa a idéia de encapsulamento. Portanto, as suas variáveis devem ser acessadas somente através de métodos. As variáveis de um Bean são suas propriedades. A primeira regra que devemos respeitar é o construtor. O construtor de um bean deve ser sem parametros. Outra regra que devemos seguir diz respeito ao nome dos métodos que darão acesso as propriedades do bean. Os métodos podem ser divididos em duas categorias: • Métodos de Leitura: Os métodos de leitura de propriedades devem seguir a seguinte convenção: public TipoDaPropriedade getNomeDaPropriedade() Como mostrado no código acima a propriedade chamada property1 tem o método de acesso getProperty1 . Note que a primeira letra da propriedade deve ser minuscula enquanto a primeira letra depois do get deve ser em maiscula. A palavra TipoDaPropriedade deve ser substituida por o tipo da propriedade. Para variáveis booleanas vale o mesmo conceito, mas, ao invés do get usamos a palavra is. No exemplo temos o acesso a propriedade property2 que é booleana como: public boolean isProperty2() Observação: Você pode não definir um método de leitura para a variável. Se isto for feito você não permitirá o acesso a ela. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 35 • Métodos de escrita: Os métodos de escrita permitem ao usuário do componente modificar o conteúdo da propriedade. Ele segue a seguinte terminologia: public void setNomeDaPropriedade(TipoDaPropriedade varName) Nos métodos de escrita não há caso especial para variáveis booleanas que também podem ser modificadas através de métodos set. Você pode não definir métodos de escrita para uma determinada variável, fazendo com que o usuário não seja capaz de modificar o conteúdo da propriedade. Outra regra que um Bean deve seguir é a implementação da interface Serializable. A implementação desta interface fornece ao bean a propriedade chamada de persistência. O conceito de persistência é permitir que o usuário faça uso do componente em um determinado momento e possa salvar o seu estado para o uso posterior partindo do mesmo ponto. A tecnologia que possibilita essa propriedade é a Serialização de Objetos. Esta tecnologia permite salvarmos o objeto em um fluxo para posterior recuperação. Quando houver a recuperação, o objeto deve se comportar como se fosse exatamente o mesmo de quando foi salvo, se olharmos o objeto como uma máquina de estado, então podemos dizer que o objeto é recuperado no mesmo estado de quando foi salvo. A tecnologia de serialização de objetos é muito importante em Java pois permite a linguagem atividades complexas como computação distribuída e além de muitas outras funcionalidades interessantes. Para sermos capazes de serializar objetos basta fazer a classe implementar a interface Serializable e nada mais. • Propriedades de um Bean Os beans possuem diversos tipos de propriedades, que são: • Simples: Propriedades simples alteram a aparência ou comportamento do bean e são acessadas através dos métodos de escrita e leitura mostrados. • Ligadas: As propriedades deste tipo quando alteradas provocam uma notificação para algum evento. • Reprimidas: As propriedades podem ter sua mudança vetada pelo próprio bean ou por objetos externos. • Indexadas: Propriedades indexadas representam coleções de valores acessados por indices, como arrays. A seguinte regra deve ser seguida por propriedades indexadas. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 36 Para as propriedades indexadas temos: • Métodos de leitura do array inteiro: public TipoDaPropriedade[] getNomeDaPropriedade(); public void setNomeDaPropriedade(TipoDaPropriedade[] value); • Métodos de leitura de elementos individuais: public TipoDaPropriedade getNomeDaPropriedade(int index); public void setNomeDaPropriedade(int index, TipoDaPropriedade value); • Como as ferramentas lêem os Beans ? JavaBeans são desenvolvidos param serem usados por terceiros (ou não). As ferramentas de desenvolvimento em Java são capazes de ler beans e prover a funcionalidade do componente para o usuário. Mas como as ferramentas são capazes de descobrir a funcionalidade de um Bean já que ele não é uma classe conhecida, ou seja, pode ser qualquer componente? Para a realização desta tarefa, que chamamos introspecção, é usada uma API disponível no Ambiente Runtime da plataforma Java, a Java Reflection API . Usando a funcionalidade desta API a ferramenta procura os métodos públicos do bean e faz a ligação dos métodos com as propriedades. Após a ferramenta ter obtido todas as informações que ela necessita sobre a classe então as propriedades e os métodos são disponibilizados para uso. A introspecção é realizada pela classe java.beans.Introspector que usa a Reflection API para descobrir as funcionalidades do bean por casamento de padrão. No entanto, alternativamente você pode definir as informações sobre o Bean em separado, em uma classe que implementa a interface BeanInfo, porém não entraremos em detalhes sobre isso. É importante saber que um bean também pode implementar outros métodos que não aqueles que lêem ou gravam as propriedades. Esses métodos não diferem em nada de outros métodos de qualquer outra classe em Java. • JavaBeans x Enterprise JavaBeans Já conhecemos o que é um JavaBean, então agora podemos compará-los com o Enterprise JavaBeans (EJB). Quais as diferenças? Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 37 Os JavaBeans assim como o EJB são modelos de componente, porém apesar dos dois compartilharem o termo JavaBeans os modelos não são relacionados. Uma parte da literatura tem referenciado EJB como uma extensão dos JavaBeans, mas isto é uma interpretação errada. As duas APIs servem para propósitos bem diferentes. O JavaBean tem a intenção de ser usado em propósitos do mesmo processo (intraprocesso) enquanto EJB é projetado para ser usado como componentes interprocessos. Em outras palavras, os JavaBeans não têm a intenção de ser usado como componente distribuído assim como o EJB. O EJB é uma tecnologia que está em grande ascenção e será abordado em futuros materias da DBSystems. 14. Ação jsp:useBean Ações possibilitam a realização de tarefas complexas como instanciação de objetos, comunicação com recursos do lado do servidor como páginas JSP e servlets sem a necessidade de código Java. Embora o mesmo possa ser feito com o uso de código Java dentro de scriptlets, o uso das tags de ações promovem reusabilidade de seus componentes e aumenta a capacidade de manutenção da página. • Usando componentes JavaBeans A tecnologia de componentes para JSP é baseada em componentes JavaBeans. Antes de acessar um bean dentro de uma página JSP, é necessário identificar o bean e obter uma referência dele. A tag jsp:useBean tenta obter uma referência de um bean que já esteja criado, dependendo do escopo em que ele foi definido. Caso não haja o componente definido haverá a criação de um novo objeto. Por exemplo a tag: <jsp:useBean id="contador" class="dbsystems.Contador" scope="session"/> Neste exemplo, a tag useBean instanciará um objeto que será identificado por contador, a partir da classe dbsystems.Contador. A definição do escopo depende muito do projeto em questão. No exemplo acima, este objeto criado será compartilhado por toda sessão que será mantida com o usuário. Caso encontrese uma nova tag de criação de um objeto da classe dbsystems.Contador, o objeto já instanciado será usado não havendo a necessidade de criação de outro. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 38 Passos para criação do objeto: Tentativa de localizar o objeto baseado nas informações (id, scope). Esta inspeção é feita sincronizada apropriadamente por escopo para evitar comportamentos não-determinísticos. Definir a variável de script identificado por id. Se o objeto for encontrado, a variável é inicializada com a referência localizada e então é realizado um casting para o tipo específico. Se o cast falhar então uma exceção do tipo java.lang.ClassCastException irá ocorrer e o processamento da tag acaba. Se o objeto não for encontrado no escopo e a classe não poder ser localizada então uma exceção do tipo java.lang.InstantiationException ocorrerá e o processamento da tag acabará. Se o objeto não foi encontrado no escopo dado e a classe for encontrada com um construtor padrão (sem argumentos) o objeto é instanciado e relacionado com a variável de scriplet identificada por id. Se um contrutor sem argumentos não for encontrado então uma exceção do tipo java.lang.InstantiationException ocorrerá e o processamento da tag acabará. O processamento do corpo da tag é então executado. Um corpo de uma tag <jsp:useBean> é executado para realizar algumas inicializações desejadas, como no exemplo abaixo: <jsp:useBean id="clientes" class="Clientes" scope="page"> <jsp:setProperty name="clientes" property="nome" value="Rafael dos Santos"> <jsp:setProperty name="clientes" property="telefone" value="648-2343"/> </jsp:useBean> O exemplo acima inicializa o objeto instanciado clientes com as propriedades nome e telefone. Entendendo os Escopos: Os escopos definem o ciclo de vida de um objeto, eles podem ser definidos como: • page: Objetos definidos com o escopo page são vistos apenas pela página onde ele foi criado. As referências para objetos no contexto page são armazenados no objeto pageContext. Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 39 • request: Objetos definidos no escopo request são vistos nas páginas usadas para responder a requisição do usuário. Se uma página é redirecionada para outra, os objetos de escopo request são preservados uma vez que fazem parte da mesma requisição. As referências a objetos do contexto request são armazenados no objeto implícito request. • session: Objetos definidos no escopo sessão são acessíveis por páginas que fazem parte da mesma sessão. As referências as esses objetos são armazenadas no objeto session. application: Objetos definidos no escopo application são acessíveis por toda aplicação JSP em questão e são armazenadas no objeto implícito application. • A tag <jsp:useBean> tem a seguinte sintáxe básica: <jsp:useBean id="nome" scope="page|request|session|application" class="nome_completo_da_classe"/> 15. Exemplo – Mini Aplicação usando JavaBeans • Listagem - LoginBean.java package curso; import java.sql.*; import java.io.Serializable; public class LoginBean implements Serializable{ private ResultSet rs; private String senha; private String usuario; /** * Definição dos Metodos Get e Set da senha */ public String getSenha() { return senha; } public void setSenha(String senha) { this.senha = senha; } /** * Definição dos Metodos Get e Set do Usuário */ public String getUsuario() { return usuario; } public void setUsuario(String usuario) { this.usuario = usuario; } /** Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 40 * Verifica o Usuario e senha */ public boolean selectUsuario(String usuario, String senha){ String strSql ="select * from usuarios where usuario = '" + usuario + "' and senha = '" + senha + "'"; try { Connection con = getConnect(); PreparedStatement pstmt = con.prepareStatement(strSql); rs = pstmt.executeQuery(); while(rs.next()){ return true; } } catch(SQLException sqlex){ System.err.println("Sem conexão..."); sqlex.printStackTrace(); }catch(Exception e){ e.printStackTrace(); } return false; } /** * Obtem uma Conexão com o Banco de Dados */ private Connection getConnect() { Connection conectar = null; String driver = "org.gjt.mm.mysql.Driver"; String url = "jdbc:mysql://53.248.185.200:3306/curso"; String user = "root"; String password = ""; try { Class.forName(driver); conectar = DriverManager.getConnection(url,user,password); } catch(ClassNotFoundException cnfex){ System.err.println("Erro ao conectar na base..."); cnfex.printStackTrace(); System.exit(1); } catch(Exception ex){ ex.printStackTrace(); } finally { return conectar; } } } • Listagem – login.jsp <jsp:useBean id="log" class="curso.LoginBean" scope="request"/> <jsp:setProperty name="log" property="*" /> <%! private boolean blnUsuario = false; %> <% if(request.getParameter("acao") != null ) { if(request.getParameter("acao").equals("login")){ blnUsuario = log.selectUsuario( (String)request.getParameter("usuario"), (String)request.getParameter("senha") ); if(blnUsuario){ Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 41 session.setAttribute("nomeUsuario",request.getParameter(" usuario")); %> <jsp:forward page="aplicacao.jsp" /> <% } else { %> <jsp:forward page="error.jsp" /> <% } } } %> <HTML> <HEAD> <TITLE>login.jsp</TITLE> </HEAD> <BODY> <FORM METHOD="POST" ACTION="/" NAME="LOGIN"> <CENTER> <TABLE> <TBODY> <TR> <TD colspan="2" align="center"> <FONT color="#000099" size="5" face="Verdana"> Acesso a Aplicação </FONT> </TD> </TR> <TR> <TD></TD> <TD></TD> </TR> <TR> <TD align="right">Usuário:</TD> <TD><INPUT size="20" type="text" maxlength="20" name= "usuario"></TD> </TR> <TR> <TD align="right">Senha:</TD> <TD><INPUT size="20" type="password" maxlength="8" name="senha"></TD> </TR> <TR> <TD></TD> <TD></TD> </TR> <TR> <TD colspan="2" align="center"> <INPUT type="submit" name="login" value="Login" onClick="LOGIN.action='login.jsp?acao=login';LOGIN.submit()";> <INPUT type="reset" name="limpar" value="Limpar"> </TD> </TR> </TBODY> </TABLE> </CENTER> </FORM> </BODY> </HTML> • Listagem – aplicacao.jsp <%! Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 42 private String strUsuario = ""; %> <% if(session.getAttribute("nomeUsuario") == null){ %> <jsp:forward page="login.jsp" /> <% } else { strUsuario = session.getAttribute("nomeUsuario").toString(); } %> <HTML> <HEAD> <TITLE>aplicacao.jsp</TITLE> </HEAD> <BODY> <FORM METHOD="POST" ACTION="/" NAME="LOGIN"> <CENTER> <TABLE> <TBODY> <TR> <TD align="center"> <FONT color="#000099" size="5" face="Verdana"> Acesso a aplicação liberado para o usuário: </FONT> </TD> </TR> <TR> <TD></TD> </TR> <TR> <TD align="center"> <FONT color="#ff8000" size="5" face="Verdana"> <I><%= strUsuario %></I> </FONT> </TD> </TR> <TR> <TD></TD> </TR> <TR> <TD align="center"> <INPUT type="submit" name="voltar" value="Voltar" onClick="LOGIN.action='login.jsp';LOGIN.submit()";> </TD> </TR> </TBODY> </TABLE> </CENTER> </FORM> </BODY> </HTML> • Listagem – error.jsp <%@page isErrorPage="true"%> <html> <head> <title>Error Page</title> </head> <body> Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 43 <font face="Comic Sans MS" size=4> <blockquote> <center> <h1><font color=red>404 Error Page</font></h1> </center> <p>Favor verificar, os dados não confere! </blockquote> </font> </body> </html> Rua Valorbe, 123 – Lauzane Paulista – Cep 02442-140 – São Paulo – SP [email protected] 44