155
Introdução 1-3 O que é necessário para começar ? Servletse JavaServer Pages (JSP) são duas tecnologias desenvolvidas pela Sun para desenvolvimento de aplicações na Web a partir de componentes Java que executem no lado servidor. Essas duas tecnologias fazem parte da plataforma J2EE (Java 2 Plataform Enterprise Edition) que fornece um conjunto de tecnologias para o desenvolvimento de soluções escaláveis e robustas para a Web. Serão abordadas apenas as tecnologias Servlets eJS P, sendo o suficiente para o desenvolvimento de sites dinâmicos de razoável complexidade. Se a aplicação exigir uma grande robustez e escalabilidade deve ser considerar o uso em conjunto de outras tecnologias da plataforma J2 EE. Para tirar um bom proveito do JS P é preciso entender a linguagem ou ter um conhecimento básico emJava. Isso porque, a parte lógica do JS P envolve Java Beans, Objetos JDBC, Enterprise Java Beans (EJB) entre outros componentes que interagem com a plataforma Ja v a. Portanto, para aqueles que pretendem desenvolver uma aplicação mais sofisticada que entendam um pouco mais de programação emJa va. O ideal é que se conheça um pouco de H T ML (HyperText Markup Language), um pouco mesmo. É comum em grandes aplicações que o Programador JS P e oDesi gner sejam pessoas diferentes. Portanto, será usado pouquíssimas tags HTML, dessa forma é presumido que todos já tenham um conhecimento básico emHT

Artigo Interessante WEB

Embed Size (px)

Citation preview

Page 1: Artigo Interessante WEB

Introdução 1-3

O que é necessário para começar ? Servletse JavaServer Pages (JSP) são duas tecnologias desenvolvidas pela Sun para desenvolvimento de aplicações na Web a partir de componentes Java

que executem no lado servidor. Essas duas tecnologias fazem parte da plataforma J2EE (Java 2 Plataform Enterprise Edition) que fornece um conjunto de tecnologias para o desenvolvimento de soluções escaláveis e robustas para a

Web.

Serão abordadas apenas as tecnologias Servlets eJS P, sendo o suficiente para o desenvolvimento de sites dinâmicos de razoável complexidade. Se a aplicação exigir uma grande robustez e escalabilidade deve ser considerar o uso em conjunto de outras tecnologias da plataforma J2 EE.

Para tirar um bom proveito do JS P é preciso entender a linguagem ou ter um conhecimento básico emJava. Isso porque, a parte lógica do JS P envolve Java Beans, Objetos JDBC, Enterprise Java Beans (EJB) entre outros componentes

que interagem com a plataforma Ja v a. Portanto, para aqueles que pretendem desenvolver uma aplicação mais sofisticada que entendam um pouco mais de programação emJa va.

O ideal é que se conheça um pouco de H T ML (HyperText Markup Language), um pouco mesmo. É comum em grandes aplicações que o

Programador JS P e oDesi gner sejam pessoas diferentes. Portanto, será usado pouquíssimas tags HTML, dessa forma é presumido que todos já tenham um conhecimento básico emHT ML, porque a preocupação está voltada para a parte lógica das aplicações e não para a parte visual.

Introdução 1-4

Page 2: Artigo Interessante WEB

A tecnologia servlet

Servlets são classes Java que são instanciadas e executadas em associação com servidoresWeb, atendendo requisições realizadas por meio do protocolo HTTP. Ao serem acionados, os objetos Servlets podem enviar a resposta na forma de uma página HTML ou qualquer outro conteúdo MIME1 . Na verdade os Servlets podem trabalhar com vários tipos de servidores e não só servidores Web, u m a v e z q u e a A P I ( Application Programming Interface) dos Servlets não assume nada a respeito do ambiente do servidor, sendo independentes de protocolos e plataformas. Em outras palavras Servlets é uma API para construção de componentes do lado servidor com o objetivo de fornecer um padrão para comunicação entre clientes e servidores. Os Servlets são tipicamente usados no desenvolvimento de sites dinâmicos.Sit es dinâmicos são si t es onde algumas de suas páginas são construídas no momento do atendimento de uma requisição HTTP. Assim é possível criar páginas com conteúdo variável, de acordo com o usuário, tempo, ou informações armazenadas em um banco de dados.

Servlets não possuem interface gráfica e suas instâncias são executadas dentro de um ambiente Java denominado de Container. Oco nt ain er gerencia as instâncias dos Servlets e provê os serviços de rede necessários para as requisições e respostas. Oco nt ai ner atua em associação com servidoresWeb recebendo as requisições reencaminhadas por eles. Tipicamente existe apenas uma instância de cada Servlet, no entanto, oco nt ai ner pode criar vários threads de modo a permitir que uma única instânciaServl et atenda mais de uma requisição simultaneamente A figura 1-1 fornece uma visão do relacionamento destes componentes.

Servlets provêem uma solução interessante para o relacionamento cliente/servidor na Internet, tornando-se uma alternativa para a implantação de sistemas para a Web.

A tecnologia JSP

JavaServer Pages (JSP) é uma tecnologia para desenvolvimento de aplicaçõesweb 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 Mi c ro so ft. Ela permite que o desenvolvedor de sites produza 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 edesi gn er podem trabalhar no mesmo projeto, mas de forma independente. Outra característica do JSP é produzir conteúdos dinâmicos que possam ser reutilizados.

Page 3: Artigo Interessante WEB

Quando uma página JSP é requisitada pelo cliente através de um Br o wse r, esta página é executada pelo servidor, e a partir daí será gerada uma página HTML que será enviada de volta ao br o wse r do cliente. A figura 1-2 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 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 enginee 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 é mais flexível e mais robusto do que outras plataformas baseadas simplesmente em JavaScripts e VBScripts.

Servlets e JSP na arquitetura J2EE

Java é, atualemente, uma plataforma completa para desenvolvimento de sistemas e não mais simplesmente uma única linguagem como quando começou. O grupo de tecnologias conhecido como J2EE (Java 2 Enterprise Edition) agrega uma série de tecnologias para rodarem dentro de servidores de aplicações conhecidos como “Servidores J2EE”, na maioria das vezes. Estas tecnologias que rodam em servidores fazem uso de serviços oferecidos pelo servidor (Enterprise JavaBeans, por exemplo) ou estendem as funcionalidades dos mesmos (Servlets, por exemplo).

Abaixo apresentamos uma figura típica que é utilizada pra localizar e apresentar as tecnologias Servlets, JSP, EJB, bem como tecnologias que podem ser utilizadas para criação de uma interface gráfica do sistema. Estas tecnologias estão distribuídas em uma arquitetura conhecida como n-tier.

Page 4: Artigo Interessante WEB

A figura acima mostra um servidor J2EE e dentro do mesmo dois “containers”, um web e outro EJB. Estes containers são os responsáveis pela execução das tecnolgias neles mostradas. Neste curso iremos trabalhar com Servlets e JSP, desta forma precisamos utilizar um web container. No curso iremos utilizar como web container um software chamado TomCat. Este software é uma implementação de referência para web containers. Veja que TomCat não é um servidor J2EE, pois o mesmo só executa as tecnologias Servlet e JSP. Como servidores J2EE, os quais são capazes de processar além de Servlets e JSP, também a tecnologia EJB, temos o JBoss, Geronimo, IAS, WebSphere, etc..

SERVLETS

Os servlets são módulos que estendem as solicitações HTTP (request/response) de servidores, tais como servidores Web Java. Um servlet deve ser responsável por realizar os processos solicitados pelos clientes aplicando a lógica de negócios definida no sistema.

Os servlets são para os servidores aquilo que os applets representam para os browsers. Ao contrário dos applets, os servlets não têm interface gráfica.

Os servlets têm um modelo de programação similar aos scripts CGI (Commom Gateway Interface) na medida que eles recebem uma solicitação de http de um navegador web como input e espera-se que localizem e/ou construam o conteúdo apropriado para a resposta do servidor.

Page 5: Artigo Interessante WEB

Diferentemente dos programas tradicionais de CGI que necessitam de um novo processo para tratar de cada nova solicitação, todos os servlets associados com um servidor da web rodam dentro de um único processo. Esse processo roda uma Java Virtual Machine (JVM), que é o programa específico de plataforma para rodar programas de Java compilados (compatível com várias plataformas).

Os encadeamentos de Java têm muito menos overhead do que os processos completos, e são executados dentro de uma memória do processador já alocada pela JVM, tornando a execução do servlet consideravelmente mais eficiente do que o processamento CGI.

Pelo fato dos servlets serem escritos em Java, eles se aproveitam de todos os benefícios da plataforma Java básica: um modelo de programação orientado a objetos, gerenciamento automático de memória, portabilidade compatível com várias plataformas e acessam todas a APIs de Java.

Servlets 2-4

Características dos servlets

Os servlets são uma alternativa para outras tecnologias dinâmicas de conteúdo da Web, como ASP e CGI. O que difere os servlets são as suas vantagens sobre os demais, incluindo: portabilidade, força, resistência, segurança, elegância e eficiência.

Portabilidade

Pelo fato dos servlets serem escritos em Java e de acordo com uma API bem definida e amplamente aceita, eles são altamente portáveis em sistemas operacionais e execuções em servidores Web. Um servlet pode ser desenvolvido por uma máquina Windows NT executando o Java Web Service e depois portado facilmente em um servidorU ni x executando o servidorA pac he.

ForçaOs servlets podem subordinar a força integral do core Java API: acesso a

rede e a URL, multithreading, manipulação de imagem, compressão de dados, conectividade ao banco de dados, internacionalização, invocação de método remoto (RMI), conectividade CORBA, serialização de objetos e muitos outras funcionalidades.

Eficácia e Resistência

A invocação do servlet é altamente eficiente. Uma vez que o servlet é carregado, ele permanece na memória do servidor como uma instância de objeto. Conseqüentemente, o servidor invoca o servlet para lidar com um pedido utilizando um método de invocação simples e leve.

Page 6: Artigo Interessante WEB

Em geral os servlets são naturalmente objetos duradouros. Pelo fato do servlet ficar na memória do servidor como uma instância única do objeto, ele mantém automaticamente seu estado para que possa firmar-se em recursos externos, como ,por exemplo, as conexões de banco de dados.

Servlets 2-5

Segurança

Os servlets suportam práticas de programação seguras em diversos níves. Os servlets herdam a segurança da linguagem Java, o recurso de coleção automática (Garbage Collection) permite que os servlets sejam seguros a partir de problemas de gerenciamento de memória como, indicadores pendentes e referências de indicador inválido.

Os servlets podem interagir seguramente com erros, devido ao mecanismo de exceções Java. Caso um servlet execute uma divisão por zero ou realize alguma operação ilegal, é disparada uma exceção para ser tratada seguramente pelo servidor, que pode refinadamente mapear o erro e responder no contexto do usuário.

Um servidor pode proteger-se de servlets através do uso do gerenciador de segurança Java. Um servidor pode executar seus servlets sob a mira de um restrito gerenciador de segurança que, por exemplo, reforça a política de segurança destinada a prevenir um servlet escrito pobremente ou mal intencionado em prejudicar o sistema de arquivos do servidor. A própria JVM fornece esta gerência de segurança das classes Java.

Elegância do código

A elegância do código servlet é notável. O código servlet é limpo, orientado a objeto, modular e muito simples. Uma razão para esta simplicidade é o Servlet API, que inclui os métodos e classes para lidar com as tarefas de rotina de desenvolvimento dos servlets.

Operações avançadas, como o manuseio de cookies e monitoramento de sessões, são abstraídas dentro de classes adequadas. Integração Os servlets são intimamente integrados com o servidor. Esta integração permite que um servlet coopere com o servidor.

Um servlet, por exemplo, pode utilizar o servidor para traduzir caminhos de arquivos, realizar logging, verificar a autorização, realizar o mapeamento do tipo MIME e também adicionar usuários no banco de dados do usuário do servidor

Page 7: Artigo Interessante WEB

A API Servlet é composta por um conjunto de interfaces e Classes. O componente mais básico da API é ai nt erface Servlet. Ela define o comportamento básico de um Servlet. O código 2-1 demonstra ain t erface Servlet.

public interface Servlet { public void init(ServletConfig config) throws ServletException; public ServletConfig getServletConfig(); public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; public String getServletInfo(); public void destroy(); }Código 2-1: Interface Servlet.

O métodoserv i ce( ) é responsável pelo tratamento de todas as requisições dos clientes. Já os métodos in it () ed estro y () são chamados quando o Servlet é carregado e descarregado do container, respectivamente. O método

getServletConfig() retorna um objeto ServletConfig que contém os parâmetros de inicialização do Servlet. O métodoget Servlet Inf o() retorna um String contendo informações sobre oServl et, como versão e autor. Tendo como base aint erf ace Servlet o restante da API Servlet se organiza hierarquicamente como mostra a figura 2-2.

A classeGene ricSer vl et implementa um servidor genérico e geralmente não é usada. A classeHttpSer vl et é a mais utilizada e foi especialmente projetada para lidar com o protocolo HTTP. O código 2-2 mostra a definição da classe

interfaceHttp Se rvl et. public abstract classHttpServlet extends GenericServlet implements java.io.Serializable Código 2-2: Interface Servlet Note que a classeHt tpServ let é uma classe abstrata. Para criar um Servlet que atenda requisições HTTP o programador deve criar uma classe derivada da HttpServlet e sobrescrever pelo menos um dos métodos descritos na tabela 2-1 que segue abaixo

GET, POST, PUT, DELETE, SERVICE

Todos esses métodos são invocados pelo servidor por meio do método service(). O método doGet() trata as requisições GET. Este tipo de requisição

pode ser enviada várias vezes, permitindo que seja colocada em um bookmark. O métododoPo st( ) trata as requisiçõesPOST que permitem que o cliente envie dados de tamanho ilimitado para o servidorWeb uma única vez, sendo útil para enviar informações tais como o número do cartão de crédito. O métododoP ut () trata as requisiçõesPUT. Este tipo de requisição permite que o cliente envie um arquivo para o servidor à semelhança de como é feito viaF TP. O método

Page 8: Artigo Interessante WEB

doDelete() trata as requisições DELETE, permitindo que o cliente remova um

documento ou uma página do servidor. O métodoserv i ce(), que recebe todas as requisições, em geral não é sobrescrito, sendo sua tarefa direcionar a requisição para o método adequado.

Diferenças entre as requisições GET e POST

Os dois métodos mais comuns, definidos pelo protocoloHTTP, de se enviar requisições a um servidorWeb são os métodos POST eGET. Apesar de aparentemente cumprirem a mesma função, existem diferenças importantes entre estes dois métodos. O métodoGE T tem por objetivo enviar uma requisição por um recurso. As informações necessárias para a obtenção do recurso (como informações digitadas em formulários HTML) são adicionadas a URL e, por conseqüência, não são permitidos caracteres inválidos na formação de URLs, como por espaços em branco e caracteres especiais. Já na requisiçãoPOS T os dados são enviados no corpo da mensagem.

O métodoGET possui a vantagem de ser idempotente, ou seja, os servidores Web podem assumir que a requisição pode ser repetida, sendo possível adicionar a URL ao bo o k mark. Isto é muito útil quando o usuário deseja manter a URL resultante de uma pesquisa. Como desvantagem às informações passadas viaGE T não podem ser muito longas, uma vez que o número de caracteres permitidos é por volta de 255 caracteres.

Já as requisiçõesPOST a princípio podem ter tamanho ilimitado. No entanto, elas não são idempotente, o que as torna ideais para formulários onde os usuários precisam digitar informações confidenciais, como número de cartão de crédito. Desta forma o usuário é obrigado a digitar a informação toda vez que for enviar a requisição, não sendo possível registrar a requisição em um

bookmark. Abaixo segue exemplos de utilização dos métodos para tratamento das requisições GET e POST.

Servlets 2-24

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class ContaAcessos extends HttpServlet { private int contador; public void service(HttpServletRequest request, HttpServletResponse response)

Page 9: Artigo Interessante WEB

throws IOException, ServletException{

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<h1 align=’center’>Contador = "+( contador++ )"</h1>"); out.close(); } }Código 2-9: Servlet com problemas de concorrência.

Note que o Servlet utiliza uma variável de instância para armazenar o número de acessos. Se não forem usadas primitivas de sincronização (como no código 2-9 de exemplo) e duas requisições simultâneas chegarem ao Servlet o resultado pode ser inconsistente, uma vez que o contador poderá conter parte dos valores de uma requisição e parte dos valores de outra requisição. Neste caso, para corrigir esse problema basta declarar a variável como local ao métodoserv ice () ou usar primitivas de sincronização (como mostra o exemplo a seguir).

Servlets 2-25

Obtendo Informações sobre a Requisição

O objetoHttpServle tRequest passado para o Servlet contém várias informações importantes relacionadas com a requisição, como por exemplo o protocolo utilizado, o endereço remoto, informações contidas no cabeçalho e muitas outras. O Servlet do código 2-11 retorna uma página contendo informações sobre a requisição e sobre o cabeçalho da requisição.

import java.io.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class Requisicao extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<html><head>");

out.println("<title>Exemplo sobre Requisicao de Informação </title>");

out.println("</head><body>");

out.println("<h3> Exemplo sobre Requisicao de Informação </h3>");

out.println("Metodo: " + request.getMethod()+"<br>");

out.println("Request URI: " + request.getRequestURI()+"<br>");

out.println("Protocolo: " + request.getProtocol()+"<br>");

out.println("PathInfo: " + request.getPathInfo()+"<br>");

out.println("Endereco remoto: " + request.getRemoteAddr()+"<br><br>");

Enumeration e = request.getHeaderNames();

Page 10: Artigo Interessante WEB

while (e.hasMoreElements()) {

String name = (String)e.nextElement();

String value = request.getHeader(name);

out.println(name + " = "+ value+"<br>");

}out.println("</body></html>"); } }Código 2-11 : Servlet que retorna as informações sobre a requisição

Page 11: Artigo Interessante WEB

Servlets 2-26 A figura 2-6 mostra o resultado de uma execução do Servlet do código 2- 11.

Page 12: Artigo Interessante WEB

Exemplo sobre Requisição de Informação Figura 2-6 : Saída da execução do Servlet que exibe as informações sobre a requisição

Servlets 2-29

Arquivow eb. xml

Arquivo descritor de módulos web. Módulos web contêm um ou mais componentes web (tais como JSP, servlet, ou arquivos HTML). O descritor de distribuição fica em /META-INF/web.xml e tem a função principal de definir as configurações dos componentes web. Geralmente são armazenados em arquivos WAR.

Como todo arquivo XML, o descritor começa com o cabeçalho XML, declarando a versão do XML em uso e a codificação utilizada no arquivo. Logo a seguir deve aparecer a declaração de DOCTYPE que informará ao servidor de aplicações a versão da especificação de servlets utilizada.

Page 13: Artigo Interessante WEB

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app PUBLIC

"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">

<web-app>

<!-- Outros elementos vão aqui. Todos são opcionais. --> </web-app> Código 2-15 : Exemplo de arquivo web.xml.

Em documentos XML, os elementos são sensíveis ao caso. Além disso, são sensíveis também em relação a ordem na qual eles aparecem dentro de outros elementos. Por exemplo, o cabeçalho XML deve ser a primeira entrada no arquivo, a declaração de DOCTYPE deve ser a segunda e o elemento web-app deve ser a terceira. Dentro do elemento web-app, a ordem dos elementos também importa. Os servidores não são obrigados a forçar esta ordenação, mas eles podem forçá-la, e alguns realmente fazem isto na prática, recusando-se a executar aplicações web que contenham elementos que estão fora de ordem. Isto significa que arquivos web.xml que usam ordenação de elementos não padronizada não são portáveis.

A lista a seguir apresenta alguns dos elementos legais que são permitidos dentro do elemento web-app, na ordem padronizada: • description - O elemento description apresenta um texto explicativo sobre

a aplicação Web. • servlet - Antes de atribuir os parâmetros de inicialização ou URLs

personalizadas para os servlets ou páginas JSP, você deve primeiro dar um nome para o o servlet ou página JSP. Você usa o elemento servlet para este propósito.

• s ervl et-mappi ng - Os servidores geralmente fornecem uma URL default

para servlets: http://host/prefixoAplicacaoWeb/servlet/ServletName. Contudo, você geralmente pode alterar esta URL de forma que o Servlet

Page 14: Artigo Interessante WEB

Servlets 2-30 possa acessar parâmetros de inicialização ou tratar URLs relativas mais facilmente. • s essi on -con fi g - Se uma sessão não tiver sido acessada por um certo

período de tempo, o servidor pode eliminá-la para economizar memória. Você pode explicitamente ajustar o timeout para objetos de sessão individuais usando o método setMaxInactiveInterval de HttpSession, ou você pode usar o elemento session-config para designar um timeout default.

Page 15: Artigo Interessante WEB

• we lcom e-fil e -li st - O elemento welcome-file-list instruí o servidor qual arquivo

usar quando o servidor receber URLs que referem-se a um nome de diretório mas não a um nome de arquivo. • er r or -p a g e - O elemento error-page permite que você indique as páginas

que serão exibidas quando certos códigos de status HTTp são retornados ou quando certos tipos de exceções são lançadas. Exemplo de arquivo web.xml <web-app>

<servlet>

<servlet-name>cicloVida</servlet-name>

<servlet-class>com.targettrust.exemplos.CicloVidaServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>cicloVida</servlet-name>

<url-pattern>/ciclo</url-pattern>

</servlet-mapping> </web-app> Código 2-16 : Exemplo de mapemaneto do servlet CicloVidaServlet no arquivo web.xml.

Page 16: Artigo Interessante WEB
Page 17: Artigo Interessante WEB

Servlets 2-31

Page 18: Artigo Interessante WEB

Parâmetros de Inicialização

O container de servlet possui a capacidade de armazenar informações de configuração e de inicialização para um servlet específico. Após instanciar o servlet, o container torna esta informação disponível para a instância do servlet.

Parâmetros de inicialização são fornecidos através do elemento <init- param> do descritor de distribuição. Este elemento possui os sub-elementos <param-name> e <param-value>.

Suponha o seguinte descritor:

<web-app>

<servlet>

<servlet-name>NomeServlet</servlet-name>

<servlet-class>com.targettrust.ClasseServlet</servlet-class>

<init-param>

<param-name>param_1</param-name>

<param-value>value_1</param-value>

</init-param>

<init-param>

<param-name>param_2</param-name>

<param-value>value_2</param-value>

</init-param>

...

</servlet>

...

</web-app> Código 2-17: Exemplo de arquivo web.xml utilizando parâmetros de inicialização Os valores em param_1 e param_2 podem ser lidos dentro do método init de um servlet com o seguinte código: private String param1 = null; private String param2 = null;

public void init(ServletConfig config) {

param1 = config.getInitParameter("param_1");

param2 = config.getInitParameter("param_2");

} Código 2-18 : Exemplo de utilização dos parâmetros de inicialização. • O retorno de getInitParameter() é sempre String, então caso você queira

um valor de outro tipo, deve fazer a conversão adequada

Servlets 2-32 • Os parâmetros de inicialização só estarão disponíveis quando acessados

Page 19: Artigo Interessante WEB

através do nome registrado do servlet no web.xml.

Em algumas situações você pode querer disponibilizar parâmetros de inicialização para todo o sistema de forma que você possa lê-los de qualquer servlet através do método getInitParameter de ServletContext. Para isto você usa o elemento context-param para declarar esses parâmetros de inicialização de abrangência mais ampla. O elemento context-param deve conter os sub- elementos param-name, param-value e, opcionalmente, description, como mostrado a seguir.

<context-param>

<param-name>webmaster-email</param-name>

<param-value>[email protected]</param-value>

</context-param> Código 2-19 : Exemplo de arquivo web.xml utilizando parâmetros de inicialização de contexto.

Servlets 2-33

Carregando um servlet

Ainda falando de inicialização. Um servlet é carregado para a memória na primeira vez que um usuário o acessa. Suponha então que um servlet possui um método init que demore um pouco para executar. Nestes casos, você pode forçar o servidor a carregar os servlets no momento da sua inicialização para que o usuário do sistema não sinta este atraso na carga dos servlets. Para isto você pode usar o sub-elemento load-on-startup. Abaixo um exemplo.

<servlet> <servlet-name> ... </servlet-name> <servlet-class> ... </servlet-class> <load-on-startup> ... </load-on-startup> </servlet> Código 2-20 : Exemplo de arquivo web.xml carregando um servlet na inicialização do container.

Se você quiser carregar mais de um servlet você pode especificar a ordem do carregamento utilizando um inteiro em load-on-startup como mostrado a seguir.

<servlet>

<servlet-name>Pesquisa</servlet-name>

<servlet-class>com.targettrust.PesquisaServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet>

<servlet-name>Cadastro</servlet-name>

Page 20: Artigo Interessante WEB

<servlet-class>com.targettrust.CadastroServlet</servlet-class>

<load-on-startup>2</load-on-startup>

</servlet> Código 2-21 : Exemplo de arquivo web.xml carregando mais de um servlet na inicialização do container. Quando o servlet estiver sendo carregado o mesmo ia executar o método init() rodando assim eventual código que possa estar lá

Exercícios Exercício 1: Uma vez estudado os métodos GET e POST do protocolo http, descreva as principais características dos mesmos mostrando em que situação cada um deve ser utilizado. Exercício 2: Todo servlet tem um ciclo de vida. Alguns métodos são chamados pelo container web durante o ciclo de vida de um servlet. Descreva o método init(), service() e destroy() Exercício 3: Neste exercício você irá criar um servlet que possa receber várias

requisições e seja capaz de identificar cada uma pelo seu endereço IP. Este servlet deve contar e armazenar quantos acessos/request cada cliente fez a ele. Siga os passos abaixo para isto:

Passo 1: Crie uma classe dentro de um pacote chamado com.targettrust.exemplos, esta classe deve ter o seguinte nome: ContaAcessosServlet Passo 2: Declare nesta classe um atributo privado chamado tabelaAcessos que seja uma Hashtable para guardar os acessos a este servlet. No método init construa a Hashtable. Passo 3: No método service() identifique o usuário pelo endereço IP do

mesmo. Para obter o endereço IP utilize o método request.getRemoteAddr(). Observe que este método retorna uma String com o IP do cliente que esta fazendo o request.Você irá utilizar este endereço IP como chave para identificar cada um dos usuários. O endereço IP estará indexando um número inteiro o qual representa o número de acessos feitos pelo usuário ao servlet.

Passo 4: Verificar se existe na hashtable o endereço IP como chave. Se não

existir então adicionar na tabela esta chave associada a um número inteiro 1. Caso já exista a chave você deve pegar o valor associado a ela e incrementar em um.

Passo 5: Depois de atualizar a hashtable você deve exibir em uma tabela HTML os endereços IP e o número de acessos que cada um fez ao servlet..

Page 21: Artigo Interessante WEB

SESSÕES

essões 3-4 Utilizando Sessões

O processo de tentar manter o estado através de múltiplas solicitações HTTP é chamado de gerenciamento de sessão, cuja idéia é que todas as solicitações de um usuário por páginas de um servidor durante um certo período de tempo, são na verdade parte da mesma sessão interativa.

A API Servlet fornece um objeto com controles de identificação, tempo de vida e outros detalhes para monitorar a sessão, oHtt pSession. O objeto HttpSession monitora a sessão de forma transparente. O Servlet abaixo faz o controle de sessão utilizando um objetoHttpSes si on

import java.io.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;

public class TesteSessao extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter();

out.println("<html><head>");out.println("<title>Teste de Sessão</title>");out.println("</head>");out.println("<body>");out.println("<h3>Teste de Sessão</h3>");

HttpSession session = request.getSession(true);

out.println("Identificador: " + session.getId() +"<br>");out.println("Data: " + ( new Date(session.getCreationTime()) + "<br>"));out.println("Último acesso: " +( new Date(session.getLastAccessedTime())));

String nomedado = request.getParameter("nomedado"); String valordado = request.getParameter("valordado"); if (nomedado != null && valordado != null) { session.setAttribute(nomedado, valordado); }out.println("<P>"); out.println("Dados da Sessão:" + "<br>"); Enumeration valueNames = session.getAttributeNames();

Page 22: Artigo Interessante WEB

while (valueNames.hasMoreElements()) {String name = (String) valueNames.nextElement();String value = (String) session.getAttribute(name);out.println(name + " = " + value+"<br>");

}out.println("<P>");

out.println("<form action=/contexto/testeSessao method=POST>");out.println("<h3>Nome: <input type=text size=20 name=nomedado></h3>");out.println("<h3>Valor: <input type=text size=20 name=valordado></h3>");out.println("<input type=submit value=Enviar>");out.println("</form>");out.println("</body></html>");

} }Código 3-1: Servlet para lidar com Sessões.

Para controlar a sessão é necessário obter um objetoHttpSess ion por meio

do métodogetSes si on( ) do objetoHttpServ l etR e ques t. Opcionalmente, o método

getSession() recebe como argumento um valor bool ean que indica se é para

criar o objetoHt tpSess ion se ele não existir (argumentot rue) ou se é para retorna

null caso ele não exista (argumento false). Para se associar um objeto ou

informação à sessão usa-se o métodoset Att ribute() do objetoHt tpSess ion, passando para o método um St ri ng e um objeto que será identificado peloSt ring. Note que o método aceita qualquer objeto e, portanto, qualquer objeto pode ser associado à sessão. Os objetos associados a uma sessão são recuperados com o uso métodogetA ttri but e() do objetoHttpSess ion, que recebe como argumento o nome associado ao objeto. Para se obter uma enumeração dos nomes associados à sessão usa-se o método getAttributeNames() do objeto

HttpSession. A figura 3-1 mostra o resultado da execução do código 3-1.

Os atributos de uma sessão são mantidos em um objetoHttpSes sion referenciado pela variávels ess ion. Pode-se armazenar valores em uma sessão por meio do métodose tAt tribute() e recuperá-los por meio do método

getAttribute(). O tempo de duração def aul t de uma sessão inativa (sem o

Page 23: Artigo Interessante WEB

recebimento de requisições do usuário) é 30 minutos mas esse valor pode ser alterado por meio do métodosetMaxInac tiveI nterval (). Você pode utilizar o métodoi nv ali date( ) para apagar as informações da sessão.

Abaixo temos exemplos de como armazenar valores na sessão através do métodoset Attr ibu te( ) e recuperar esses valores através do métodogetAt tri bute( ) . Note que utilizamos um cast para converter o objeto retornado em uma instância da classe desejada, quando utilizamos o métodogetAttribute (), porque ele retorna um objeto da classeO bject.

Adicionando um objeto UsuarioBean na sessão:

HttpSession session = request.getSession(true);

UsuarioBean usr = new UsuarioBean();

usr.setNome("João da Silva");

usr.setSalario(1500f);

session.setAttribute("usuario",usr);

Código 3-2: Exemplo de adição de dados na sessão.

Recuperando um objeto UsuarioBean da sessão:

HttpSession session = request.getSession(true);

UsuarioBean usr = (UsuarioBean)session.getAttribute("usuario");

if ( usr != null ) {

// achou o bean na sessão

}else {

// não achou o bean na sessão

}Código 3-3: Exemplo de busca de dados na sessão

Page 24: Artigo Interessante WEB

Sessões

3-8

Exercícios

Exercício 1: Agora que você estudou o mecanismo de Session, descreva o que é

a sessão e para que ela pode ser utilizada em uma aplicação web.

Exercício 2: Neste exercício você irá criar um servlet e mostrar dados da sessão,

como visto no decorrer do estudo do capítulo. Siga os passosa abaixo para isto.

Passo 1: Crie um servlet chamado SessionInfoServlet no pacote

com.targettrust.exemplos e neste servlet declare o método service. Neste método declare um objeto do tipo HttpSession chamado session para representar a sessão. Pegue a sessão do objeto request e atribua a mesma a ele.

Passo 2: Logo depois de ter capturado a sessão, mostre algumas

informações da mesma que você julgar interessante, tais como: id da sessão, tempo de expiração, data de criação da mesma e nome dos atributos que existem na sessão.

Exercício 3: Neste exercício você irá criar uma página HTML para chamar três

servlets, um que adiciona um java bean à sessão, outro que possa ler este java

bean e um terceiro que possa invalidar a sessão.

Passo 1: Crie uma página HTML na região onde podem ser armazenadas as

páginas HTML do seu projeto. Esta página deve conter três links, um para cada

servlet a ser chamado. Utilize o seguinte código para fazer o link entre os servlets:

...

out.println("<br>");

out.println("<a href=/contexto/gravarSessao> Gravar Bean</a>");

out.println("<br>");

Page 25: Artigo Interessante WEB

out.println("<a href=/contexto/lerSessao>Ler Bean</a>");

out.println("<br>");

out.println("<a href=/contexto/invalidaSessao>Invalidar Sessão</a>");

...

Passo 2: Crie uma classe para representar um Curso e nesta classe declare

dois atributos privados para armazenar o nome do curso e a carga horária. Gere para esta classe os métodos de leitura e gravação dos atributos bem como um construtor que possa receber os o nome e a carga horária e já inicializar os mesmos.

Passo 3: Crie uma classe servlet com nome GravarBeanServlet dentro do

pacote com.targettrust.exemplos e para o servlet-mapping deste servlet coloque

o nome gravarSessao conforme o link no arquivo HTML

Passo 4: No servlet GravarBeanServlet dentro de seu método service()

capture a sessão e adicione nela um objeto da classe Curso criada anteriormente. Lembre-se de dar um nome para este atributo que você estará adicionando na sessão. Este nome deverá ser utilizado posteriormente para capturar o objeto.

Passo 5: Crie uma classe servlet com nome LerBeanServlet dentro do

pacote com.targettrust.exemplos e para o servlet-mapping deste servlet coloque

o nome lerSessao conforme o link no arquivo HTML.

Passo 6: Na classe LerBeanServlet dentro do método service() capture o

bean da sessão e mostre o nome e a carga horária do curso. Lembre-se de verificar com um if se o bean foi achado na sessão, caso não tenha sido encontrado, informe isto para o usuário.

Passo 7: Crie agora uma outra classe para representar um servlet

chamada InvalidarSessionServlet dentro do pacote com.targettrust.exemplos.

Passo 8: Na classe que invalida a sessão, declare o método service() e

Page 26: Artigo Interessante WEB

dento deste método capture a sessão. Para invalidar a sessão basta chamar o método invalidate() no objeto. Observe que a sessão só deverá ser invalidada se não for nova. Caso a mesma seja uma sessão nova deve ser informado para o usuário e não deverá ser invalidada a mesma.

FORMULÁRIOS

Formulários

4-3

Lidando com Formulário

Os formulários são ferramentas úteis e muito usadas em diversas aplicações, tais como, cadastro registros em um banco de dados, validação de um login ou senha, envio de e-mail, envio de dados de uma 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 Web.

Ser capaz de lidar com as informações contidas em formulários HTML é

fundamental para qualquer tecnologia de desenvolvimento de aplicações para

Web. É por meio de formulários que os usuários fornecem dados, preenchem

pedidos de compra e (ainda mais importante) digitam o número do cartão de crédito. As informações digitadas no formulário chegam até o Servlet por meio do objetoHttpSer vle tRequest e são recuperadas por meio do método

getParameter() deste objeto. Todo item de formulário HTML possui um nome e

esse nome é passado como argumento para o métodogetParamet er() que

retorna na forma deString o valor do item de formulário.

Page 27: Artigo Interessante WEB

O Servlet do código 4-1 exibe o valor de dois itens de formulários do tipo

text. Um denominado nome e o outro denominado de sobrenome. Em seguida o

Servlet cria um formulário contendo os mesmos itens de formulário. Note que um formulário é criado por meio dotag<form >. Como parâmetros opcionais deste tag temos método da requisição (method), é a URL para onde será submetida à requisição (action). No caso do exemplo, o método adotado é oPOST e a requisição será submetida ao próprio servletF o r mu lar io.

import java.io.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class Formulario extends HttpServlet {

public void service(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<html>");

out.println("<head><title>Trata formulário</title></head>");

out.println("<body bgcolor=\"white\">");

out.println("<h3>Trata formulário</h3>");

String nome = request.getParameter("nome")

Formulários

4-4

Page 28: Artigo Interessante WEB

String sobreNome = request.getParameter("sobrenome");

<< Continua na próxima página >>

if (nome != null || sobreNome != null) {

out.println("Nome = " + nome + "<br>");

out.println("Sobrenome = " + sobreNome);

}out.println("<form action=/contexto/form method=POST>");

out.println("<h3>Nome :

<input type=text size=20 name=nome></h3>");

out.println("<h3>Sobrenome: <input type=text size=20 name=sobrenome></h3>");

out.println("<input type=submit value=Enviar>");

out.println("</form>");

out.println("</body></html>");

}

}Código 4-1: Servlet para lidar com um formulário simples

Apresentamos abaixo códigos para mostrar o formato de um formulário HTML e de seus objetos. Antes de vermos os elementos que fazem parte dos formaulários, vamos ver como deve ser representado um formulário.

<html>

<body>

<!-- cabeçalho do formulário -->

<form name="nomeDoFormulario" action="/contexto/cadastroServlet" method="get">

<!-- Colocar os objetos do formulário -->

...

<!-- final do formulário -->

</form>

Page 29: Artigo Interessante WEB

</body>

</html>

Código 4-2: Formato de formulário

Formulários

4-6

Campos de texto

Os campos de texto representam componentes que podem receber textos do usuário e os enviar para um servlet ou página JSP. Cada caixa de texto representará um parâmetro a ser enviado no request.

Veja abaixo o código para uma caixa de texto:

<!-- caixa de texto -->

<inputtype="text" name="parametro" value="Texto" size=20 maxlength=20>

Esta caixa de texto ficará exibida da seguinte maneira quando a página

for renderizada.

Figura 4-1: Exemplo de objeto do tipo caixa de texto.

Type = tipo do objeto

Name = nome do parâmetro a ser enviado

Value = Se existir exibe um valor na caixa de texto

Size = Tamanho visual da caixa de texto

Maxlength = número máximo de caracteres comportados pela caixa de

Texto

Page 30: Artigo Interessante WEB

Campos de texto escondidos

Os campos de texto escondidos são utilizados para passar parâmetros da página para os servlets ou jsps que estão sendo chamados pelo formulário. A sua sintaxe é muito semelhante ao campo de texto normal, porém o tipo muda e não há alguns atributos.

Veja abaixo o código para uma caixa de texto:

<!-- caixa de texto -->

<inputtype="hidden" name="acao" value="gravar" >

Este código não irá gerar componente visual para ser exibido na página.

Type = tipo do objeto

Name = nome do parâmetro a ser enviado

Value = Se existir exibe um valor na caixa de texto

Campos de senha

Estes campos representam caixas de texto que podem receber senhas. Elas não exibem a senha digitada. Isto não significa que a senha estará sendo enviada de forma criptografada e protegida para o servidor. Nunca utilize estes campos em formulários que enviar os dados via o método get do protocolo http.

Veja o código exemplo abaixo:

<!-- caixa de texto para senha -->

<inputtype="password" name="variavel2" value="Senha" size=20 maxlength=20>

Figura 4-2: Exemplo de objeto do tipo caixa de senha.

Type = tipo do objeto

Name = nome do parâmetro a ser enviado

Page 31: Artigo Interessante WEB

Value = Se existir exibe um valor na caixa de texto

Size = Tamanho visual da caixa de texto

Maxlength = número máximo de caracteres comportados pela caixa de

Texto

Botões de radio

Os botões re rádio são utilizados para expor ao usuário uma quantidade de opções e o mesmo pode selecionar somente uma das mesmas. Para isto quando tivermos estes campos o nome dos mesmos deve sempre o mesmo a fim de proposrcionar que somente um possa estar selecionado.

Veja o código abaixo:

<!-- objeto do tipo radio -->

<inputtype="radio" name="opcao" value="sim"> Aceitar

Figura 4-3-a: Exemplo de objeto do tipo radio

<!—um grupo de objetos do tipo radio -->

<inputtype="radio" name="info" value="S" selected> Desejo receber informações

<inputtype="radio" name="info" value="N"> Não gostaria de receber informações

Campos de escolha

Estes campos são semelhanes aos de radio, porém o objetido dos mesmos é permitir a seleção de mais de uma opção. Neste caso os nomes dos campos não pode ser o mesmo.

Veja abaixo o código exemplo:

<!-- objeto do tipo checkbox -->

<inputtype="checkbox" name="parametro" value="valor"> Aceitar

Page 32: Artigo Interessante WEB

Figura 4-4-a: Exemplo de objeto do tipo checkbox.

<!-- objetos do tipo checkbox para mais de uma escolha -->

<inputtype="checkbox" name="tipo" value="pesquisar" checked> Pesquisar

<inputtype="checkbox" name="tipo" value="solicitar"> Solicitar revisão

<inputtype="checkbox" name="tipo" value="cadastrar"> Cadastrar

<inputtype="checkbox" name="tipo" value="excluir">

Excluir da base de dados

Listas

As listas permitem exibir um conjunto de valores e permitir que o usuário

possa os selecionar um valor. Veja abaixo um código de exemplo:

<!-- objeto do tipo select -->

<select name="parametro">

<option value="valor1" selected>Valor 1</option>

<option value="valor2">Valor 2</option>

<option value="valor3">Valor 3</option>

</select>

Áreas de texto

As áreas de texto permitem ao usuário digitar um volume maior de texto

sendo que o mesmo pode ter múltiplas linhas.

Veja abaixo o exemplo:

<!-- área de texto -->

<textarea name="parametro " cols=40 rows=2>

Page 33: Artigo Interessante WEB

Contrato de utilização do software...

</textarea>

Botão reset

Este botão é utilizado para limpar os campos do formulário. O usuário ao clicar neste botão fará com que os campos tenham os seus conteúdos todos apagados.

Normalmente temos um destes botões presentem nos formulários HTML.

Veja abaixo o exemplo de código:

<!-- botao de limpar informações do formulário -->

<inputtype="reset" value="Limpar">

Botão de envio

Este é um componente muito importante pois ;e com ele que os dados são enviados para o servidor. Este botão quando for clicado irá chamar o método submit do formulário provocando o envio dos dados para o servidor através do request.

Veja exemplo abaixo:

<!- botao de enviar formulário -->

<inputtype="submit" value="Enviar dados">

Seleção de arquivos

Page 34: Artigo Interessante WEB

Este tipo de componente é utilizado para que o usuário possa selecionar na sua máquina um arquivo para, por exemplo, ser enviado ao servidor. Quando for clicado no otão ao lado do campo de texto será exibida uma caixa de seleção de arquivos onde o usuário poderá seleciona um arquivo.

Veja exemplo abaixo:

<!- objeto para anexar arquivo -->

<inputtype="file" name="arquivo">

Formulários

4-16

Sobre os formulários...

É importante fazermos algumas observações à cerca do formulário:

No cabeçalho do formulário, indicamos através deaction = "pagina.jsp" o

arquivo JSP ou servlet 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:

<inputname="variavel1" type="text" value="">

<inputname="Variavel1" type="text" value="">

Código 4-3: Exemplo de case sensitive com html.

São objetos diferentes porque receberam nomes diferentes (variavel1 e

Page 35: Artigo Interessante WEB

Variavel1).

Será mostrado mais um exemplo (bastante simples) de como enviar dados

a partir de um formulário a uma página JSP.

<html>

<body>

<div align=center>

<h1> <%= request.getParameter("param") %> </h1>

<form action="teste.jsp" method=GET>

<input type="text" name="param" size=40 maxlength=40><br>

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

</form>

</div>

</body>

</html>

Código 4-4: Exemplo de uso de formulários. Página teste.jsp.

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 foi feito 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>

Código 4-5: Trecho da jsp teste.jsp

Page 36: Artigo Interessante WEB

O nome do objeto caixa de texto caixa de texto ("param") é usado na

expressão re ques t.getP aram eter( " param" ).

Note que se usássemosre quest .get P aram eter( "Para m") (com P 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 conter

apenas códigos HTML e o segundo contém códigos HTML e JSP.

<html>

<body>

<h3>Qual o mês do seu aniversário?</h3>

<form action="recebeMes.jsp" method=GET>

<select name="mesNasceu">

<option value="1">Janeiro</option>

<option value="2">Fevereiro</option>

<option value="3">Março</option>

<option value="4">Abril</option>

<option value="5">Maio</option>

<option value="6">Junho</option>

<option value="7" selected>Julho</option>

<option value="8">Agosto</option>

<option value="9">Setembro</option>

<option value="10">Outubro</option>

<option value="11">Novembro</option>

<option value="12">Dezembro</option>

Page 37: Artigo Interessante WEB

</select>

<br>

<input type="submit" value="enviar">

</form>

</body>

</html>

Código 4-6: Arquivo enviaMes.jsp.

<%@page import="java.util.*" %>

<%

String msg = "";

String mesString = request.getParameter("mesNasceu");

int mes = Integer.parseInt(mesString);

Calendar hoje = Calendar.getInstance();

int monthNow = hoje.get(hoje.MONTH) + 1;

<< Continua na próxima página >>

mes -= monthNow

Formulários

4-18

if (mes == 1) {

msg = "Falta apenas "+ mes +" mês para o seu aniversário.";

} else if (mes == -1) {

msg = "Seu aniversário foi no mês passado";

Page 38: Artigo Interessante WEB

} else if (mes > 1) {

msg = "Faltam "+ mes +" meses para o seu aniversário.";

} else 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>

<h3> <%= msg %> </h3>

</body>

</html>

Código 4-7: Arquivo recebeMes.jsp

O exemplo acima é um pouco mais complexo que o primeiro. O arquivo "enviaMes.jsp" contém um formulário com um objetosel ect 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 "recebeMes.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 primeiras linhas utilizamos as tags "page import" para indicar quais

classes iremos utilizar em nossa página:

<%@page import=”java.util.*” %>

Código 4-8: Utilizando a tag page.

Page 39: Artigo Interessante WEB

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");

Código 4-9: Exemplo de uso do getParameter()

O valor passado através de um formulário ou através da URL da página é sempre do tipoString. Ao ser inicializado o terceiro objeto, o método "Integer.parseInt(variavelString)" transformou o valor contido na variável

mesString em Inteiro.

int mes = Integer.parseInt(mesString);

Código 4-10: Conversão de valores. String para inteiro.

O penúltimo objeto criado é do tipo Calendar (importância de importar a classejava.util.Calendar na primeira linha de nossa página). Ele é inicializado com a hora local do servidor.

Calendar hoje = Calendar.getInstance();

Código 4-11: Inicialização de um atributo do tipo Calendar.

Na inicialização do último objeto utilizamos o método "get()" que retorna um inteiro indicando o valor da variável da posição indicada por hoje.MONTH. É somado 1 ao valor retornado a partir desse método porque ele retorna 0 para janeiro, 1 para fevereiro e assim por diante.

Page 40: Artigo Interessante WEB

int monthNow = hoje.get(hoje.MONTH) + 1;

Código 4-12: Como pegar o valor do mês do atributo hoje.

Cinco testes são efetuados dentro de umscript (<% e %>). Eles são usados para definir o valor que a variável "msg" terá, ou seja, a partir dos testes, será decidida qual mensagem será exibida na tela.

Após efetuar os testes, o texto HTML é inserido na página.

Uma expressão (<%= %>) é usada para exibir o valor da variável "msg":

<%= msg %>

Exercícios

Exercício 1:Neste exercício você irá criar uma página de login para o usuário

fornecer seu login e senha de acesso ao sistema. Para isto crie uma página HTML e nesta página declare um formulário sem nome e sem ação deixando estes atributos ainda sem valor. Utilize para este formulário o método POST.

Passo 1: Crie uma página JSP com o nome login.jsp dento do seu projeto

Passo 2: Para o usuário fornecer o login crie um campo de texto e para

fornecer a senha um campo de senha como strados abaixo.

Login:

<input type="text" name="login" size="20" maxlength="20">

Senha:

<input type="password" name="senha" size="8" maxlength="8">

Passo 3: Adicione neste formulário um campo checkbox para solicitar se o

Page 41: Artigo Interessante WEB

usuário quer que o seu login e senha sejam lembrados. Veja código abaixo:

Lembrar login e senha:

<input type="checkbox" name="lembrar" value="S" >

Passo 4: Adicione agora um botão para acessar o sistema. Veja o código

abaixo:

Botão Acessar:

<input type="submit" value="Acessar">

Sua página deverá se parecer com a figura abaixo

Exercício 2: Construa uma página jsp, em um arquivo chamado

cadastraCurso.jsp, que contenha um formulário para fazer o cadastro de um curso. Este formulário fará uso de alguns tipos de campos mostrados abaixo. Observe que é muito importante manter o nome para os campos como mostrado abaixo.

Código do curso:

<input type="text" name="codigo" size="8" maxlength="8">

Código do centro de treinamento:

<input type="text" name="codigoCentro" size="5" maxlength="5">

Nome:

<input type="text" name="nome" size="50" maxlength="200">

Unidade de treinamento:

<select name="unidadeTreinamento">

<option value=""> Selecione uma unidade </option>

</select>

Descrição resumida do curso:

<textarea name="descricaoResumida" cols=40 rows=5>

</textarea>

Page 42: Artigo Interessante WEB

Preço:

<input type="text" name="preco" size="7" maxlength="7">

Carga Horária:

<input type="text" name="cargaHoraria" size="3" maxlength="3">

Em sala de aula?

<select name="salaAula">

<option value="S" selected>Sim</option>

<option value="N">Não</option>

</select>

In Company?

<select name="inCompany">

<option value="S">Sim</option>

<option value="N" selected>Não</option>

</select>

Tem material didático?

<select name="material">

<option value="S" selected>Sim</option>

<option value="N">Não</option>

</select>

Botão Cadastrar:

<input type="submit" value="Cadastrar">

Botão Limpar:

<input type="reset" value="Limpar">

A sua página deverá se parecer com esta

Page 43: Artigo Interessante WEB

Exercício 3: Construa agora uma página JSP, chamda defineResponsavel.jsp, que

contenha um formulário para definir o responsável pela entrega do material

didático didático. Abaixo você encontra o código para lhe auxiliar nesta tarefa.

Curso:

<select name="curso">

<option value=""> Selecione um curso </option>

</select>

Instrutor

<select name="instrutor">

<option value=""> Selecione um instrutor </option>

</select>

Data prevista de entrega:

<input type="text" name="dia" size="2" maxlength="2"> <input type="text" name="mes" size="2" maxlength="2"> <input type="text" name="ano" size="4" maxlength="4">

Percentual de Royalty:

<input type="text" name="royalty" size="2" value="">

Botão Salvar:

<input type="submit" value="Salvar" >

Botão Limpar:

<input type="reset" value="Limpar">

A sua página deve se parecer assim depois de pronta:

Page 44: Artigo Interessante WEB

JSP

SP – Como Funciona ?

Servlets é uma boa idéia, mas dá para imaginar montar uma página complexa usandoprintln() ? Muitas vezes o desenvolvimento de um sit e é uma tarefa complexa que envolve vários profissionais. A tarefa de projeto do l ayo ut da página fica a cargo do Web Designer, incluindo a diagramação dos textos e imagens, aplicação de cores, tratamento das imagens, definição da estrutura da informação apresentada nosite e doslinks para navegação pela mesma. Já o DesenvolvedorWe b é responsável pela criação das aplicações que vão executar em um site. O trabalho destes dois profissionais é somado na criação de um único produto, mas durante o desenvolvimento a interferência mutua deve ser a mínima possível. Ou seja, um profissional não deve precisar alterar o que é foi feito pelo outro profissional para cumprir sua tarefa. A tecnologia Servlet não nos permite atingir esse ideal. Por exemplo, suponha que um Web Designer terminou o desenvolvimento de uma página e a entregou para o Desenvolvedor

Web codificar em um Servlet. Se após a codificação o Web Designerde sej ar

realizar uma alteração na página será necessário que ele altere o código do Servlet (do qual ele nada entende) ou entregar uma nova página para o DesenvolvedorWeb para que ele a codifique totalmente mais uma vez. Quaisquer umas dessas alternativas são indesejáveis e foi devido a esse problema a Sun desenvolveu uma tecnologia baseada em Servlets chamada de JSP.

Java Server Pages são páginas HTML que incluem código Java e outros

tags especiais. Desta forma as partes estáticas da página não precisam ser

geradas porpri ntl n( ). Elas são fixadas na própria página. A parte dinâmica é gerada pelo código JSP. Assim a parte estática da página pode ser projetada por um Web Designer que nada sabe de Java.

A primeira vez que uma página JSP é carregada pelocont ai n er JSP o código Java é compilado gerando um Servlet que é executado, gerando uma página HTML que é enviada para o navegador. As chamadas subseqüentes são enviadas diretamente ao

Page 45: Artigo Interessante WEB

Servlet gerado na primeira requisição, não ocorrendo mais às etapas de geração e compilação do Servlet.

A figura 5-1 mostra um esquema das etapas de execução de uma página JSP na primeira vez que é requisitada. Na etapa (1) a requisição é enviada para um servidor Web que reencaminha a requisição (etapa 2) para oc ont ain er Servlet/JSP. Na etapa (3) o container verifica que não existe nenhuma instância de Servlet correspondente à página JSP. Neste caso, a página JSP é traduzida para código fonte de uma classe Servlet que será usada na resposta à requisição. Na etapa (4) o código fonte do Servlet é compilado, e na etapa (5) é criada uma instância da classe. Finalmente, na etapa (6) é invocado o método

service() da instância Servlet para gerar a resposta à requisição

Escopo de Objetos

Diversas páginas JSP podem estar envolvidas no processamento de um

request. Durante este processamento, diversos objetos podem ser criados, tanto

usando diretivas JSP, como por ações definidas na página JSP ou ainda por

trechos de código Java embutido na página JSP.

Qualquer objeto criado pode ser associado com um atributo de escopo, que define onde existe uma referência ao objeto e quando a referência é removida. O diagrama da figura 5-2 mostra os escopos que podem ser associados com um objeto recém criado:

Figura 5-2: Escopos dos objetos.

Cada escopo mostrado na figura 5-2 tem um significado. A visibilidade do escopo está, em ordem crescente, de baixo para cima na figura. Abaixo estão os significados de cada escopo:

Page: objetos acessíveis somente nas páginas em que foram criados;

Request: objetos acessíveis nas páginas que processam o mesmorequ est;

Session: objetos acessíveis nas páginas que pertençam à mesma sessão em

que os objetos foram criados

Page 46: Artigo Interessante WEB

Application: objetos acessíveis nas páginas que pertençam à mesma

Aplicação

Diretivas

Existem dois tipos principais de diretivas. Diretiva page que permite situações como importação de classes, customização de super classes servlet entre outras. Diretiva include que permite que seja inserido o conteúdo de um arquivo no servlet no momento em que o arquivo JSP é traduzido para servlet.

Diretiva Page

A diretiva page tem a seguinte sintaxe:

<%@page atributo1=valor1 atributo2=valor2 atributo3=valor3 ... %>

Código 5-1: Como criar a diretiva page.

Abaixo relacionamos os atributos mais utilizados nas diretivaspage:

Atributo contentType

Este atributo indicará qual o tipo de conteúdo que a página JSP estará

gerando e enviando para o browser.

<%@page contentType="text/html" %>

Código 5-2: Como criar a diretiva page.

O valor deste atributo pode variar, text/html indica que o conteúdo a ser enviado para o browser será HTML. Se trocarmos por text/plain indicará que o conteúdo é texto puro e o browser não deverá interpretar o mesmo.

Atributo import

O atributo tem a seguinte sintaxe :

import="package.class" ou import = "package.class1,...,package.class"

Page 47: Artigo Interessante WEB

Código 5-3: Como usar o atributo import.

Permite que seja especificado qual o pacote a ser importado. Por exemplo,

veja o código 5-4.

<%@page import="java.util.*" %>

Código 5-4: Exemplo do uso do atributo import.

O atributo “import” é o único que pode aparecer várias vezes.

Atributo isThreadSafe

isThreadSafe = "true|false"

Código 5-5: Como usar o atributo isThreadSafe.

O valor detrue (default) indica o processamento normal do servlet quando múltiplas requisições podem ser acessadas simultaneamente na mesma instância de servlet. O valor f al se 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. Como SingleThreadModel foi depreciado na API Servlet 2.4, deve-se evitar utilizar esse atributo como false.

Atributo session

session = "true|false"

Código 5-6: Como usar o atributo session.

O valor detrue (default) indica que a variável predefinidasession (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 f al se indica que sessões

não devem ser usadas.

Atributo buffer

buffer = "sizekb|none"

Código 5-7: Como usar o atributo buffer.

Especifica o tamanho do buff e r para oJs pWri tero ut. O buffer padrão é

Page 48: Artigo Interessante WEB

definido pelo servidor.

Atributo autoFlush

autoFlush = "true|false"

Código 5-8: Como usar o atributo autoflush.

O valor detrue (default) indica se ob uffer deve ser esvaziado quando estive cheio. O valor f al se, indica que uma exceção deve ser mostrada quando ocorrero ver flo ws.

Atributo extends

extends = "package.class"

Código 5-9: Como usar o atributo extends.

Define se a super classe do Servlet deve ser gerada.

Atributo info

info = "message"

Código 5-10: Como usar o atributo info.

Define umaSt rin g que pode ser recuperada pelo métodoget Se rvl etI nfo( ). Com esse atributo o autor pode adicionar uma cadeia de documentação à página que sumariza sua funcionalidade. O valor padrão para o atributoin fo é a cadeia vazia.

Atributo errorPage

errorPage = "url"

Código 5-11: Como usar o atributo errorPage.

Especifica que a página JSP deve processar algumThro w ables, mas não

carregá-lo na página corrente

Atributo isErrorPage

isErrorPage = "true|false"

Page 49: Artigo Interessante WEB

Código 5-12: Como usar o atributo isErrorPage.

Define se uma página pode atuar como uma página de erro para uma

outra página JSP. Odef ault éf al se.

Atributo language

language = "java"

Código 5-13: Como usar o atributo language.

Especifica a linguagem que está sendo usada. Por enquanto o JSP suporta

somente Java

Diretiva include

A diretiva include permite que sejam incluídos arquivos na hora em que a

página JSP é traduzida no servlet.

O uso da diretivainclude é algo como:

<%@include file="url" %>

Código 5-14: Como usar a diretiva include.

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 uma tabela repetindo o código HTML em cada página do site. Esta diretiva supre essa necessidade de minimizar os esforços de manutenção conforme os códigos que seguem (códigos 5-15, 5-16 e 5-17).

<html><body>

<%@include file="navegadorInclude_2.html" %>

<!-- Parte específica da página -->

</body></html>

Código 5-15: Exemplo de um arquivo jsp de nome “include_2.jsp”.

Page 50: Artigo Interessante WEB

<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_03.jsp">SEÇÃO 03</a>

</font>

Código 5-16: Exemplo de um arquivo html de nome “navegadorInclude_2.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_03.jsp">SEÇÃO 03</a>

</font>

<!-Parte específica da página ... -->

</body></html>

Código 5-17: Exemplo do código do arquivo “include_2.jsp” interpretado pelo browse

Simbologia – JSP Tags

JSP fornece cinco categorias detags : diretivas, declarações, expressões, scriptlets e comentários. Declarações, expressões, scriptlets e comentários, têm sintaxes e usos similares, mas têm diferenças importantes

Declarações

Page 51: Artigo Interessante WEB

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 referenciados por outros elementos de criação descriptlets na mesma página. A cada declaração deve ser finalizada ou separada por "ponto-e-vírgula" e pode assumir a seguinte sintaxe:

<%! Declaração %>

Código 5-18: Como criar uma declaração.

Alguns exemplos:

<%! Circle a = new Circle(2.0); %>

<%! int i = 0; %>

<%! int a, b; double c; %>

Código 5-19: Exemplo de como criar declaração

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 i ncl ude, o escopo se expande para oco ve r do arquivo incluído, isto é, passa a fazer parte de uma única JSP

Expressões

Podem conter alguma expressão válida da linguagem descript usada

nessa página, no caso a linguagem é Java, mas sem ponto-e-vírgula.

A sintaxe para este elemento de criação descripts é a seguinte:

<%= Expressão %>

Código 5-20: Como criar uma expressão.

Veja alguns exemplos:

<%= new String() %>

Page 52: Artigo Interessante WEB

<%= aux1 + aux2 + aux3 %>

<%=array[i] %>

<%=Math.sqrt(2) %>

Código 5-21: Exemplo de como criar expressão.

A expressão Java é avaliada (da esquerda 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

criptlets

Permitem você escrever trechos de código da Linguagem usada na

página. A sintaxe para este elemento é a seguinte, veja o exemplo abaixo:

<% Scriptlets %>

Código 5-22: Como criar um scriptlet.

Veja o exemplo:

<html><body>

<%

Page 53: Artigo Interessante WEB

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>

Código 5-23: Exemplo de como criar scriptlets

Lembre-se que em um sc ri pt você deve finalizar as expressões através do uso de ponto-e-vírgula. Quando você escreve um sc ri pt, você pode usar algum dos objetos implícitos do JSP ou das classes importadas através da diretivapage, variáveis ou métodos (declarados entre astags <%! e %> ou objetos nomeados através datag< jsp :us eB ean >.

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: <!-- comentário --> .

Aqueles familiarizados com HTML percebem que é a mesma sintaxe de comentário para essa linguagem de marcação. Tais comentários não produzem qualquero ut put visível, mas podem ser visualizados pelo usuário final através do item "view source" do navegador.

Page 54: Artigo Interessante WEB

Comentários JSP não são enviados para o cliente e são visíveis apenas nos arquivos fontes JSP originais. O corpo do comentário é ignorado peloco nt ainer JSP. Os comentários JSP podem assumir duas sintaxes:

<%-- comentário jsp --%>

E / OU

<% /* comentário scriptlet */ %>

Código 5-24: Como criar comentário.

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

Ações

Ações permitem que você execute tarefas sofisticadas como instanciação de objetos, comunicação com recursos do lado do servidor como Servlets e páginas JSP, sem que para isto seja necessária codificação Java. Entretanto o mesmo pode ser obtido usando código Java dentro dos scriptlets como visto anteriormente. Todas as tags de ação são construídas com a sintaxe XML.

<jsp:include>

A tag<jsp:include> pode ser utilizada para redirecionar o pedido para qualquer recurso estático ou dinâmico a partir de uma página JSP principal. Os recursos podem ser desde um servlet, um arquivo HTML e também outra JSP. A página principal pode enviar ou

Page 55: Artigo Interessante WEB

não parâmetros para o recurso incluído, o qual irá processar o pedido retornando o conteúdo de saída junto com a saída da página que realizou a chamada. Esta por sua vez ao término da ação retorna o controle.

A sintaxe para a tag sem parâmetros é a seguinte:

<jsp:include page =”url” flush=”true” />

Código 5-25: Sintaxe da tag <jsp:include> sem parâmetros.

A sintaxe para a tag com parâmetros é a seguinte:

<jsp:include page=”url” flush=”true” >

<jsp:param name=”parametro1” value=”valor1” />

<jsp:param name=”parametro2” value=”valor2” />

</jsp:include>

Código 5-26: Sintaxe da tag <jsp:include> com parâmetros.

A tag possui dois atributospage ef lu sh. O atributo page informa a URL para onde irá ocorrer a chamada. O atributo flush serve para informar a página JSP principal que o seu buffer de conteúdo de saída será descarregado antes de se passar o controle para a página referenciada na tag, permitindo que a página incluída possa adicionar seu conteúdo de saída corretamente. Por esse motivo ele deve sempre ser utilizado com o valor true

<jsp:forward>

A tag < j sp :f o r war d> serve para redirecionar pedidos para qualquer JSP, Servlet ou página HTML estática, dentro do mesmo contexto o qual a página que disparou a ação se encontra. A página que realiza o desvio tem seu processamento finalizado exatamente no ponto onde o redirecionamento acontece embora todo o processamento até este ponto ainda aconteça, se houverem dados no buffer de saída colocados por esta página, estes serão apagados antes do desvio de controle.

A sintaxe para a tag é a seguinte:

<jsp:forward page=”url” />

Código 5-27: Sintaxe da tag <jsp:forward> sem parâmetros

Page 56: Artigo Interessante WEB

<jsp:forward page=”url” >

<jsp:param name=”parametro1” value=”valor1” />

<jsp:param name=”parametro2” value=”valor2” />

</jsp:forward>

Código 5-28: Sintaxe da tag <jsp:forward>

Exercícios

Exercício 1: JSP define quatro escopo para objetos, nestes escopos podem

portanto ser armazenados objetos que posteriormente possam ser recuperados.

Descreva, brevemente, cada um destes escopos.

Exercício 2: Neste exercício você irá criar duas páginas home, uma para o

administrador e outra para o instrutor.

Passo 1: Crie uma página JSP com o nome admHome.jsp dentro de seu

projeto. Nesta página crie três links como mostrado no código abaixo:

<a href= "/contexto/controller?action=formCurso"> Cadastrar curso </a>

<a href= "/contexto/controller?action=formInstrutor"> Cadastrar instrutor </a>

<a href= "/contexto/controller?action=formResponsavel"> Definir responsável </a>

Esta página deverá ficar semelhante a figura abaixo

Passo 2: Crie uma página JSP com o nome instHome.jsp dentro de seu

projeto. Nesta página crie dois links como mostrado no código abaixo:

<a href= "/contexto/controller?action=formUpload">

Upload do material </a>

<a href= "/contexto/controller?action=formDownload"> Download do material </a>

Esta sua página deverá se parecer como a da figura abaixo

Page 57: Artigo Interessante WEB

Exercício 3: Agora vamos iniciar a construção de um servlet que irá atuar como

controller no nosso sistema. Este servlet terá papel de redireciondor e avaliador

de algumas questões ligadas ao sistema. Para isto siga os passos abaixo:

Passo 1: Crie uma classe para conter um servlet com o nome

ControllerProjeto. No servlet-mapping defina o nome deste servlet como

controller.

Passo 2: Este servlet deverá conter os métodos init() e service(). Declare

então estes métodos na classe. Abaixo um código para você utilizar como guia

na criação de seu servlet controller.

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class ControllerProjeto extends HttpServlet {

public void init( ServletConfig config ) {

}public void service(HttpServletRequest request,HttpServletResponse response)

throws ServletException, IOException {

}

}

Passo 3: Declare agroa neste servlet controller as seguintes constantes e

atributos:

// Constantes

Page 58: Artigo Interessante WEB

private final String URL_USO_INCORRETO = "/contexto/projeto/usoIncorreto.html";

private final String URL_ADM_HOME

= "/projeto/admHome.jsp";

private final String URL_INST_HOME

= "/projeto/instHome.jsp";

private final String URL_FORM_CURSO

= "/projeto/cadastraCurso.jsp";

private final String URL_FORM_RESPONSAVEL = "projeto/defineResponsavel.jsp";

private final String URL_FORM_UPLOAD

= "/projeto/uploadMaterial.jsp";

private final String URL_FORM_DOWNLOAD

= "/projeto/downloadMaterial.jsp";

// Atributos

private String usuarioInit, senhaInit;

private ServletContext contexto;

Passo 4: Dentro do método init agora você irá capturar dois parâmetros de

inicialização que serão passados para o controller através do arquivo web.xml. Defina então o seguinte código dentro do método init(), bem como configure estes parâmetros no arquivo web.xml. Caso não lembre-se de como fazer isto chame seu instrutor.

usrInit

= config.getInitParameter("usuario");

pwdInit

= config.getInitParameter("senha");

contexto = config.getServletContext();

Passo 5: Agora dentro do método service() você deverá “validar” a ação

Page 59: Artigo Interessante WEB

que o usuário está executando quando chamar o controller e de acordo com a ação redirecionar este usuário para um dos endereços das páginas JSP que estão atribuídas as constantes.Abaixo você tem o código para lhe guiar nesta tarefa.

String action = request.getParameter("action");

if ( action == null ) {

response.sendRedirect( URL_USO_INCORRETO );

return;

}if ( action.equalsIgnoreCase("logar") ) {

String login = request.getParameter("login");

String senha = request.getParameter("senha");

// Verificar se é administrador

if (login.equalsIgnoreCase(usrInit) && senha.equalsIgnoreCase(pwdInit) ) { contexto.getRequestDispatcher(URL_ADM_HOME).forward(request, response); return;

}else {

contexto.getRequestDispatcher(URL_INST_HOME).forward(request, response);

return;

}} else if ( action.equalsIgnoreCase("formCurso") ) {

contexto.getRequestDispatcher( URL_FORM_CURSO ).forward(request,

response);

return;

} else if ( action.equalsIgnoreCase("formResponsavel") ) {

contexto.getRequestDispatcher( URL_FORM_RESPONSAVEL ).forward( request,

response);

Page 60: Artigo Interessante WEB

return;

} else if ( action.equalsIgnoreCase("formUpload") ) {

contexto.getRequestDispatcher( URL_FORM_UPLOAD ).forward(request,

response);

return;

} else if ( action.equalsIgnoreCase("formDownload") ) {

contexto.getRequestDispatcher( URL_FORM_DOWNLOAD ).forward(request,

response);

return;

}

JAVABEANS

JavaBeans são componentes de software 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 tecnologia java.

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 material. Também não falaremos sobre todos os conceitos de JavaBeans, daremos mais atenção e ênfase àqueles conceitos que mais são utilizados nas páginas JSP

Page 61: Artigo Interessante WEB

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 componentes.

import java.io.Serializable;

public class MyBean implements Serializable {

private int property1;

private boolean property2;

public MyBean() { }

public void setProperty1(int property1) {

this.property1 = property1;

}public void setProperty2(boolean property2) {

this.property2 = property2;

}public int getProperty1() {

return property1;

}public boolean isProperty2() {

return property2;

}

}Código 6-1: Código fonte exemplificando um JavaBean.

Esta classe é um exemplo do que devemos seguir para tornar uma classe um bean, ou seja, o conjunto de regras que devemos obedecer para tornar o componente reconhecível e usável por ferramentas.

Page 62: Artigo Interessante WEB

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 parâmetros (construtor default).

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(){ ... }

Código 6-2: Exemplo de como construir um método de leitura.

Como mostrado no código 6-1 a propriedade chamada property1 tem o método de acesso getProperty1 . Note que a primeira letra da propriedade deve ser minúscula enquanto a primeira letra depois do get deve ser em maiúscula. A palavra TipoDaPropriedade deve ser substituída pelo tipo da propriedade. Para variáveis booleanas vale o mesmo conceito, mas, ao invés do get usamos a palavrais. No exemplo temos o acesso a propriedade property2 que é booleana como:public boolean isProperty2() { ... }

Código 6-3: Exemplo de como construir um método de leitura booleano.

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.

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){ ... }

Page 63: Artigo Interessante WEB

Código 6-4: Exemplo da terminologia de métodos de escrita.

Nos métodos de escrita não há caso especial para variáveis booleanas

que também podem ser modificadas através de métodosset.

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 dainterface

Serializable. A implementação destai nterf ac e 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

ai nt erf aceSer ial izable 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.

Page 64: Artigo Interessante WEB

Indexadas: Propriedades indexadas representam coleções de

valores acessados por índices, como array s. A seguinte regra deve

ser seguida por propriedades indexadas:

Para as propriedades indexadas temos:

Métodos de leitura do array inteiro:

public TipoDaPropriedade[] getNomeDaPropriedade() { ... }

public void setNomeDaPropriedade(TipoDaPropriedade[] value) { ... }

Código 6-5: Exemplo de métodos de leitura de arrays.

Métodos de leitura de elementos individuais:

public TipoDaPropriedade getNomeDaPropriedade(int index) { ... }

public void setNomeDaPropriedade(int index, TipoDaPropriedade value){ ... }

Código 6-6: Exemplo de métodos de leitura individuais, de uma parte do array.

Ações

Existem três tags definidas pela especificação JSP para o uso dos Beans:

• <jsp : useBean >

• <jsp : se tProperty>

• <jsp : ge tProper ty>

<jsp:useBean>

A tag<jsp:useBean> permite que você possa acessar métodos de um JavaBean em sua página JSP. A tag<jsp:useBean> vem em duas formas, uma tag vazia única e um par correspondente de tag(s) inicial e final, que contém o corpo da tag que pode ser usado

Page 65: Artigo Interessante WEB

para especificar informações de configuração adicionais(inicialização do Bean). Na forma mais simples, a tag < j sp:use Be an > necessita apenas de dois atributos,id e class. Assim como todas as tag(s) JSP, você deve colocar entre aspas cada valor de atributo.

A sintaxe básica das duas formas da tag é a seguinte:

<jsp:useBean id=”myBeanInstance” class=”package.myBeanClass” scope=”page” />

OU

<jsp:useBean id=”myBeanInstance” class=”package.myBeanClass” >

O <b> Bean </b> está sendo inicializado ...

</jsp:useBean>

Código 6-7: Sintaxe da tag <jsp:useBean>.

O código acima indica que será gerada uma instância do bean definida na classepackage. my Bean Cla ss e o nome dela serámyB ea nI nst ance na página. Esta instância existirá durante o ciclo de vida de uma única solicitação HTTP para a página.

Mais detalhadamente, o atributoi d especifica qual o nome da instância do bean dentro da aplicação. O atributosco pe possui um dos valores de escopo já vistos anteriormente: page,reque st,se ssi o n ou appli c at i o n. E por último o atributo class que define o nome da classe a qual o bean será instanciado.

É importante observar que o atributo scope é opcional, porém não deve ser ignorado. Ele tem a função de determinar o tempo de vida de um componente JavaBean em uma página JSP. Isto é, quanto tempo ele irá existir como variável de programa. Para que um bean possa ser instanciado não poderá existir objetos anteriores com mesmo identificador em id e scope. Do contrário se já existir uma instância para o objeto esta será usada.

<jsp:setProperty>

Page 66: Artigo Interessante WEB

A tag<jsp:setProperty> é utilizada para setar os valores das propriedades dos componentes JavaBeans em uma página JSP. Existem quatro formatos para a utilização desta tag.

property = “nomePropriedade”

Usando este formato a propriedade especificada será setada com o valor

que será passado como parâmetro no pedido HTTP(request).

<jsp:setProperty name=”nomeBean” property=”nomePropriedade” />

Código 6-8: Sintaxe 1 da tag <jsp:setProperty>.

property = “*”

Usando esta forma cada parâmetro enviado no pedido HTTP request será avaliado a fim de se encontrar um método correspondente combinando com seu nome, caso isto aconteça o método set é invocado com o valor do parâmetro recebido no pedido HTTP.

<jsp:setProperty name=”nomeBean” property=”*” />

Código 6-9: Sintaxe 2 da tag <jsp:setProperty>.

property = “nomePropriedade” param=”nomeParametro”

Usando esta forma a propriedade do bean será setada com o valor do parâmetro do pedido especificado na tag, invocando-se o método set apropriado com o valor do parâmetro como argumento. Imagine uma situação em que o nome do parâmetro no pedido HTTP, para representar o nome de um cliente sejano me P ara met ro, para atribuir o valor deste parâmetro na propriedade do objetono meP r o prie dad e deve-se usar a sintaxe abaixo.

<jsp:setProperty name=”nomeBean” property=”nomePropriedade”

param = “nomeParametro”

/>

Código 6-10: Sintaxe 3 da tag <jsp:setProperty>.

property = “nomePropriedade” value =”novoValor”

Page 67: Artigo Interessante WEB

Usando esta forma o valor especificado será atribuído a propriedade do bean em questão. Este valor poderá ser uma cadeia de caracteres ou até mesmo o resultado de uma expressão JSP (<%= ... %>).

<jsp:setProperty property=”nomePropriedade”

value = “String|<%= ... %>” />

Código 6-11: Sintaxe 4 da tag <jsp:setProperty>.

<jsp:getProperty>

A tag<jsp:getProperty> é utilizada para recuperar valores de uma propriedade de um componente JavaBean, converte o valor recuperado em uma cadeia de caracteres(String), e insere no conteúdo de saída. Os dois atributos necessários para esta tag são o nome do Bean(name) já referenciado anteriormente na tag < jsp :use B ean> , e o que indica a propriedade (property) que se deseja recuperar o valor. O atributo property deve possuir um método get correspondente no Bean.

<jsp:getProperty name=”nomeBean” property=”nomePropriedade” />

Código 6-12: Sintaxe da tag <jsp:getProperty>

O Uso de JavaBeans

A medida que o código Java dentro do HTML torna-se cada vez mais complexo o desenvolvedor pode-se perguntar: Java em HTML não é o problema invertido do HTML em Servlet? O resultado não será tão complexo quanto produzir uma página usandoprintln()? Em outras palavras, está novamente misturando conteúdo com forma?

Para solucionar esse problema a especificação de JSP permite o uso de JavaBeans para manipular a parte dinâmica em Java. Podemos encarar um JavaBean como sendo apenas uma classe Java que obedece a uma certa padronização de nomeação de métodos, formando o que é denominado de

propriedade. As propriedades de um bean são acessadas por meio de métodos

Page 68: Artigo Interessante WEB

que obedecem a convençãogetXxxx esetXxxx. , onde X xx x é o nome da propriedade. Por exemplo,getItem() é o método usado para retornar o valor da propriedade item. A sintaxe para o uso de um bean em uma página JSP é:

<jsp:useBean id="nome" class="com.targettrust.Curso" />

Código 6-13: Exemplo do uso da sintaxe do Bean.

Onde nome é o identificador da variável que conterá uma referência para uma instância do JavaBean. Você também pode modificar o atributo scope para estabelecer o escopo do bean além da página corrente.

<jsp:useBean id="nome" scope="session" class="com.targettrust.Curso" />

Código 6-14: Exemplo do uso de scope na tag bean.

Para modificar as propriedades de um JavaBean você pode usar o

jsp:setProperty ou chamar um método explicitamente em um sc r i pt l et. Para

recuperar o valor de uma propriedade de um JavaBean você pode usar o

jsp:getProperty ou chamar um método explicitamente em um sc ri pt l et. Quando é

dito que um bean tem uma propriedade prop do tipo T significa que o bean deve prover um métodogetP rop( ) e um método do tipo set Pro p(T) . Os códigos 6- 15 e 6-16 mostram uma página JSP e um JavaBean. A página instancia o JavaBean, altera a propriedade mensagem e recupera o valor da propriedade, colocando-o na página.

<%@page contentType="text/html"

import = "cap06.*"%>

<HTML>

<HEAD>

<TITLE>Uso de JavaBeans</TITLE>

</HEAD>

<BODY>

<jsp:useBean id="teste" class="cap06.BeanSimples" />

Page 69: Artigo Interessante WEB

<jsp:setProperty name="teste" property="mensagem" value="Olá mundo!" />

<H1> Mensagem: <I><jsp:getProperty name="teste" property="mensagem" /> </I></H1>

</BODY>

</HTML>

Código 6-15: Exemplo de javaBean. Arquivo jspBean.jsp.

import java.io.*;

public class BeanSimples implements Serializable {

private String mensagem = "Nenhuma mensagem";

public String getMensagem() {

return(mensagem);

}

public void setMensagem(String mensagem) {

this.mensagem = mensagem;

}

}Código 6-16: Exemplo de javaBean. Arquivo beanSimples.java.

A figura 6-1 mostra o resultado da requisição dirigida à página jspBean.jsp.

Figura 6-1: Resultado da requisição a página jspBean.jsp.

Se na tagsetProperty usarmos o valor “* ” para o atributopro pert y então todos os valores de elementos de formulários que possuírem nomes iguais à propriedades serão transferidos para as respectivas propriedades no momento do processamento da requisição. Por exemplo, seja uma página jsp contendo um formulário com uma caixa de texto com nome mensagem, como mostrado no código 6-17. Note que, neste caso, a propriedade mensagem do JavaBean tem seu valor atualizado para o valor digitado na caixa de texto, sem a necessidade de uma chamada explícita no t agset Prope rty. Os valores são

automaticamente convertidos para o tipo correto no bean.

Page 70: Artigo Interessante WEB

<HTML> <HEAD><TITLE>Uso de JavaBeans</TITLE> </HEAD>

<BODY> <CENTER>

<TABLE BORDER=5> <TR><TH CLASS="TITLE"> Uso de JavaBeans </TABLE>

</CENTER> <P>

<jsp:useBean id="teste" class="BeanSimples" />

<jsp:setProperty name="teste" property="*" />

<H1> Mensagem: <I>

<jsp:getProperty name="teste" property="mensagem" />

</I></H1>

<FORM method="POST" action="Bean2.jsp">

Texto: <input type="text" size="20" name="mensagem" ><br>

<INPUT TYPE=submit name=submit value="envie">

</FORM>

</BODY> </HTML>

Código 6-17: Exemplo de atualização automática da propriedade. Código jspBean2.jsp.

A figura 6-2 mostra o resultado da requisição dirigida à página jspBean2.jsp

após a digitação do texto Bom Dia!

Figura 6-2: Resultado da requisição à página jspBean2.jsp

Como as ferramentas lêem os Beans ?

JavaBeans são desenvolvidos para 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?

Page 71: Artigo Interessante WEB

Para a realização desta tarefa, que chamamos introspecção, é usada uma API disponível no AmbienteRu nti me 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 classej ava .beans .In tros pector 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 interfaceB e anIn fo.

É 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 dos outros métodos de qualquer outra classe em Java.

Exercícios

Exercício 1: Neste exercício você irá criar um java bean para representar um

instrutor. Este java bean será posteriormente utilizado nas suas páginas JSP.

Passo 1: Crie uma classe chamada InstrutorBean e para esta classe defina

as seguintes propriedades/atributos:

private int codigo;

private String nome, email, login, senha;

Passo 2: Crie para esta classe os métodos de leitura e gravação dos

atributos bem como o construtor default.

Exercício 2: Construa uma página jsp, em um arquivo chamado

cadastraInstrutor.jsp, que contenha um formulário para fazer o cadastro de um instrutor. Este formulário fará uso de alguns tipos de campos mostrados abaixo. Observe que é muito importante manter o nome para os campos como mostrado abaixo.

Código:

Page 72: Artigo Interessante WEB

<input type="text" name="codigo" size="8" maxlength="8">

Nome:

<input type="text" name="nome" size="50" maxlength="100">

Email:

<input type="text" name="email" size="50" maxlength="150">

Senha:

<input type="password" name="senha" size="10" maxlength="10">

Botão Cadastrar:

<input type="submit" value="Cadastrar">

Botão Limpar:

<input type="reset" value="Limpar">

Exercício 3: Crie agora uma pequena aplicação usando JSP para cadastrar

um instrutor no banco de dados. Utilize a classe InstrutorDB para fazer a inserção do instrutor no banco. Observe que na classe InstrutorDB há operações para isto. Nesta página JSP você terá um código que faz uso do java bem criado anteriormente para representar um instrutor. Este java bean será populado automaticamente com os valores enviados pelo formulário acima criado. A página JSP fará uso do método :

public static String insert(InstrutorBean instrutor)

Código para fazer o cadastro do instrutor a ser adicionado na nova JSP:

<jsp:useBean id="cadastro" scope="page" class="pacote.InstrutorBean" />

<jsp:setProperty name="cadastro" property="*" />

<% String msg = InstrutorDB.insert(cadastro); %>

Observe acima o código e ajuste o mesmo para o seu projeto caso

necessário.

Objetos Implícitos

Page 73: Artigo Interessante WEB

Pode-se criar, dentro descriptlets na página JSP, instâncias de uma classe Java e manipulá-las a fim de produzir conteúdo dinâmico. Por exemplo, 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, oco nt ai ner 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 ouinterface 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

javax.servlet.jsp.HttpJspPage

Instância de servlet da

página.

config

javax.servlet.ServletConfig

Dados de configuração

de servlet.

request

javax.servlet.http.HttpServletRequest Dados de solicitação,

Page 74: Artigo Interessante WEB

incluindo parâmetros.

response

javax.servlet.http.HttpServletResponse Dados de resposta.

out

javax.servlet.jsp.JspWriter

Fluxo de saída para

conteúdo da página..

session

javax.servlet.http.HttpSession

Dados

de

sessão

específicos de usuário.

application

javax.servlet.ServletContext

Dados

compartilhados por todas as páginas de aplicação.

pageContext javax.servlet.jsp.PageContext

Dados de contexto para

execução da página.

exception

javax.lang.Throwable erros não capturados ou exceção

Os nove objetos implícitos fornecidos por JSP podem ser classificados da

seguinte forma:

Page 75: Artigo Interessante WEB

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.

objetos contextuais (application, session, request, pageContext):

Os objetos implícitos dessa categoria fornecem à 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.

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

Page 76: Artigo Interessante WEB

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.

Exemplo utilizando o objeto implícito page:

<%@page info="Página de Teste" %>

<%= ((javax.servlet.jsp.HttpJspPage)page).getServletInfo() %>

Código 7-1: Código fonte exemplificando o padrão de fontes

Objeto config

O objetoco nfi g 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 objetoco nf i g é uma instância da interfaceja vax .s ervl et. Servl etC onf ig. Os métodos fornecidos por esta interface para recuperar parâmetros de inicialização de servlet estão listados na tabela 7-2:

Métodos

Descrição

Enumeration getInitParameterNames() Recupera os nomes de todos os

Page 77: Artigo Interessante WEB

parâmetros de inicialização.

String getInitParameter(String name)

Recupera o valor do parâmetro de

inicialização a partir de um nome.

Tabela 7-2: Descrição resumida dos objetos implícitos

Objetos de O ut Put eInP ut da Página

Os objetos classificados nessa categoria se concentram noinput (entrada de dados) eo ut put (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 objetorequ est representa a solicitação que requisitou a página. O objeto request implementa ai nt erf acejav ax .servl et.h ttp. HttpServ let Requ est (subinterface dejavax.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

Page 78: Artigo Interessante WEB

Descrição

void setAttribute(String key, Object value) Associa um valor de atributo com um

nome.

Enumeration getAttributeNames()

Recupera os nomes de todos os

atributos associados com o objeto.

Object getAttribute(String key)

Recupera o valor de atributo

associado com a chave.

void removeAttribute(String key)

Remove o valor de atributo

associado com a chave.

Tabela 7-3: Métodos de input/output para atributos do objeto request.

Recuperar parâmetros de solicitação e cabeçalho de HTTP:

Método

Descrição

Enumeration getParameterNames()

Retorna os nomes de todos os

parâmetros de solicitação.

String getParameter(String name)

Retorna os primeiro valor (principal) de um único parâmetro de solicitação.

String[ ] getParameterValues(String name) Recupera todos os valores para um

único parâmetro de solicitação.

Page 79: Artigo Interessante WEB

Tabela 7-4: Métodos de input/output para recuperar parâmetros de solicitação e cabeçalhos

http.

Recuperar cabeçalhos de solicitação e cabeçalhos de HTTP:

Método

Descrição

Enumeration getHeaderNames()

Recupera os nomes de todos os cabeçalhos associados com a solicitação.

String getHeader(String name)

Retorna o valor de um único cabeçalho de solicitação, como uma cadeia.

Enumeration getHeaders(String name) Retorna todos os valores para um único

cabeçalho de solicitação.

int getIntHeader(String name)

Retorna o valor de um único cabeçalho de solicitação, com um número inteiro.

long getDateHeader(String name)

Retorna o valor de um único cabeçalho de solicitação, como uma data.

Cookies[ ] getCookies()

Recupera todos os cookies associados

com a solicitação.

Tabela 7-5: Métodos de input/output para recuperar cabeçalho da solicitação.

Diversos métodos da interface que

javax.servlet.http.HttpServletRequest:

Método

Page 80: Artigo Interessante WEB

Descrição

String getMethod()

Retorna o método de HTTP (e.g, POST,

GET, etc) para a solicitação.

String getRequestURI()

Retorna o URL de solicitação (não inclui a

cadeia de consulta).

String getQueryString()

Retorna a cadeia de consulta que segue

o URL de solicitação, se houver algum.

HttpSession getSession()

Recupera os dados da sessão para a

solicitação (i.e, o objeto implícito session).

HttpSession getSession(boolean flag) 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.

RequestDispatcher

getRequestDispatcher(String path)

Cria um dispatcher de solicitação para o

URL local indicado.

String getRemoteHost()

Retorna o nome totalmente qualificado

do host que enviou a solicitação.

String getRemoteAddr()

Page 81: Artigo Interessante WEB

Retorna o endereço de rede (IP) do host

que enviou a solicitação.

String getRemoteUser()

Retorna o nome do usuário que enviou a

solicitação, se conhecido.

Tabela 7-6: Métodos da interface httpServletRequest.

Exemplo utilizando o objeto implícito request:

Seu IP é :<%= request.getRemoteAddr() %><br>

Seu Host é :<%= request.getRemoteHost() %><br>

Código 7-2: Exemplo de uso do objeto implícito Request

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 implementa a interface javax.servlet.http.HttpServletResponse que é uma subinterface de javax.servlet.ServletResponse . Podemos dividir os métodos desse objeto em quatro funcionalidades:

void setContentType(String type)

Define o tipo MIME e, opcionalmente, a codificação de caracteres do conteúdo da resposta.

String getCharacterEncoding()

Retorna o conjunto de estilos de codificação de caracteres para o conteúdo da resposta

Page 82: Artigo Interessante WEB

void setStatus(int code)

Define o código de status para a resposta

(para circunstâncias sem erro).

void sendError(int status, String msg) Define o código de status e mensagem

de erro para a resposta.

void sendRedirect(String url)

Envia uma resposta para o navegador indicando que ele deveria solicitar um URL alternativo (absoluto).

String encodeRedirectURL(String url) Codifica um URL para uso com o método sendRedirect() para incluir informações de sessão.

O código 7-3 ilustra uma das utilidades desse objeto. Vários cabeçalhos são definidos para evitar que a página seja armazenada emcache por um navegador.

<%

response.setHeader("Expires", 0);

response.setHeader("Pragme”, "no-cache");

if(request.getProtocol().equals("HTTP/1.1")){

response.setHeader("Cache-Control", "no-cache");

}%>

Código 7-3: Código fonte exemplificando o padrão de fontes

Este script primeiro define o cabeçalhoExpires 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 emcache.

Page 83: Artigo Interessante WEB

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 instância da classejav ax. serv le t.j sp.Js pWri ter.

Esse objeto implementa todos os métodosprint() epri nt ln () definidos por

java.io.Writer.

Por exemplo, o objetoout pode ser usado dentro de umscript para

adicionar conteúdo à página gerada. Veja o código 7-4 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!");

}%>

Código 7-4: Código fonte exemplificando o padrão de fontes

Esse objeto é muito utilizado 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étodosprint() ouprintln() para inserir cadeias de caracteres muito grandes. No próximo caso, é mais aconselhável fechar osc ri pt e inserir o conteúdo estático. Veja o exemplo a seguir:

Exemplo de um uso não Aconselhável:

<%

if(i == 1){

out.print("<h6><font face='verdana'>Guga viaja nesta sexta para a Suíça

Page 84: Artigo Interessante WEB

para jogar</font></h6>”);

}%>

Código 7-5: Código fonte exemplificando o padrão de fontes

Exemplo de um uso aconselhável:

<% if(i == 1) {%>

<h6>

<font face='verdana'>

Guga viaja nesta sexta

para a Suíça para

jogar

</font>

</h6>

<% } %>

Código 7-6: Código fonte exemplificando o padrão de fontes

Objetos Contextuais

Os objetos implícitos dessa categoria fornecem à página JSP acesso ao contexto dentro do qual ela está respondendo. Os quatro objetos implícitos contextuais são:

Page 85: Artigo Interessante WEB

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 objetorequest , 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 objetose s si o n , duram enquanto o usuário continuar a interagir com o servidor da web. Os atributos de aplicação, armazenados no objetoappl icati on, são mantidos enquanto oco ntain er JSP mantiver uma ou mais páginas de uma aplicação carregada na memória - enquanto o container JSP estiver rodando. A tabela 7-11 a seguir traz os métodos comuns aos quatro objetos e que são usados para armazenar e recuperar valores de atributos:

void setAttribute(String key, Object value) Associa um valor de atributo com um

nome.

Enumeration getAttributeNames()

Recupera os nomes de todos os

atributos associados

com o objeto.

Object getAttribute(String key)

Recupera o valor de atributo

associado com a chave.

Page 86: Artigo Interessante WEB

void removeAttribute(String key)

Remove o valor de atributo

associado com a chave

Tabela 7-11: Os métodos comuns a esses quatro objetos e que são usados para armazenar e

recuperar valores dos atributos.

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 objetoses sio n armazena informações a respeito da sessão. Um dos principais usos para o objetoses si o n é 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);

%>

Código 7-7: Exemplo de uso do objeto session.Inserindo informação na sessão.

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 7-8 abaixo ilustra a recuperação do objeto armazenado

no código anterior:

<%

Page 87: Artigo Interessante WEB

Usuario u = (Usuario)session.getAttribute("usuario");

%>

Código 7-8: Exemplo de uso do objeto session. Recuperando valores da sessão.

Perceba que o métodogetAt tri bute( ) retorna um objeto da classeObject, portanto, é necessário fazermos um c ast para converter o objeto retornado em uma instância da classe desejada. O objeto session implementa ain t erface

javax.servlet.http.HttpSession.

A tabela 7-12 traz os principais métodos utilizados por esse objeto, além

daqueles descritos anteriormente na tabela 7-11

Object getAttibute(String nome)

Recupera o objeto identificado por

"nome".

String getId()

Retorna o Id da sessão.

long getCreationTime()

Retorna a hora na qual a sessão foi

criada.

long getLastAccessedTime()

Retorna a última vez que uma solicitação associada com a sessão foi recebida.

int getMaxInactiveInterval()

Retorna o tempo máximo (em segundos) entre solicitações pelo qual a sessão será mantida.

void setMaxInactiveInterval(int time)

Define o tempo máximo (em segundos) entre solicitações pelo qual a sessão será mantida.

Page 88: Artigo Interessante WEB

boolean isNew()

Retorna se o navegador do usuário ainda não tiver confirmado o ID de sessão.

boolean invalidate()

Descarta a sessão, liberando quaisquer

objetos armazenados como atributos

Tabela 7-12: Métodos do objeto HttpSession

Objeto application

Este objeto representa a aplicação à qual a página JSP pertence. Ele é uma instância dainterfacejava x.servlet .Servlet Context. Oscontainers JSP tipicamente tratam do primeiro nome de diretório em um URL como uma aplicação.

Além dos métodos descritos na tabela 7-11, 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()

Retorna o nome e versão do container

servlet.

int getMajorVersion()

Retorna a versão principal da API do servlet

para o container servlet.

int getMinorVersion()

Page 89: Artigo Interessante WEB

Retorna a versão secundária da API do

servlet para o container servlet.

Tabela 7-13: Métodos de recuperação de informação.

Interagir com arquivos e caminhos no servidor:

Método

Descrição

String getMimeType(String filename)

Retorna o tipo M IME para o arquivo

indicado, se conhecido pelo servidor.

URL getResource(String path)

Traduz o path em um objeto que acessa os conteúdos dos URLs, localmente ou na rede.

InputStream

getResourceAsStream(String path)

Traduz uma cadeia especificando um URL em um fluxo de entrada para ler seu conteúdo.

String getRealPath(String path)

Traduz um URL local em um nome de

caminho no sistema de arquivo local.

ServletContext getContext(String path) Retorna o contexto de aplicação para

o URL local especificado.

RequestDispatcher

getRequestDispatcher(String path)

Cria um dispacher de solicitação para

o URL local indicado.

Page 90: Artigo Interessante WEB

Tabela 7-14: Métodos para interação com arquivos e servidor

Suporte para log de mensagens:

Método

Descrição

void log(String message)

Grava a mensagem no arquivo de log.

void log(String message, Exception e)

Grava a mensagem no arquivo de log, junto com a trilha de pilha para a exceção especificada.

Tabela 7-15: Métodos para log de mensagem.

Acessar parâmetros de inicialização:

Método

Descrição

Enumerations getInitParameterNames() Recupera os nomes de todos os

parâmetros de inicialização.

String getInitParameter(String name)

Recupera o valor do parâmetro de

inicialização como o nome dado.

Tabela 7-16: Métodos para acessar parâmetros de inicialização

Objeto pageContext

Page 91: Artigo Interessante WEB

O objetopageC ont e xt 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 objetopageCo ntext é uma instância da classe

javax.servlet.jsp.PageContext. Além dos métodos descritos na tabela 7-11, 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()

Retorna a instância de servlet para a

página atual (objeto implícito page).

ServletRequest getRequest()

Retorna a solicitação que iniciou o processamento da página (objeto implícito request).

ServletResponse getResponse()

Retorna a resposta para a página

(objeto implícito response).

JspWriter getOut

Retorna o fluxo de saída atual para a

página (objeto implícito out).

HttpSession getSession()

Retorna a sessão associada com a solicitação da página atual, se houver alguma (objeto implícito session).

ServletConfig getServletConfig()

Retorna o objeto de configuração de

servlet (objeto implícito config).

Page 92: Artigo Interessante WEB

ServletContext getServletContext()

Retorna o contexto no qual o servlet da

página

roda

(objeto

implícito

application).

Exception getException()

Para páginas de erro, retorna a

exceção passada para a página

(objeto implícito exception).

Tabela 7-17:Métodos para acessar outros objetos implícitos.

Envio de solicitações de uma página JSP para outra:

Método

Descrição

void forward(String path)

Encaminha o processamento para um

outro URL local dado pela String path.

void include(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,

Page 93: Artigo Interessante WEB

int scope)

Associa o valor do atributo "obj" com

a chave "key" no escopo "scope".

Enumeration

getAttributeNamesInScope(int scope)

Recupera os nomes de todos os

atributos associado com "key" no

escopo "scope".

Object getAttribute(String name,

(int scope)

Recupera o valor de tributo

associado com "name" no escopo

"scope"

removeAttribute(String name, int scope) Remove o valor de atributo

associado com "name" no escopo

"scope"

Object findAttribute(String name)

Procura em todos os escopos pelo

atributo associado com "name".

int getAttributesScope(String name)

Retorna o escopo no qual o atributo

associado com "name" está

armazenado.

Page 94: Artigo Interessante WEB

Tabela 7-19:Métodos de acesso através de vários escopos.

Os últimos dois métodos listados na tabela 7-19 permitem a procura, através de todos os escopos definidos, por um atributo associado com umaSt ri ng passada como parâmetro. Nos dois casos, o objetopageCon tex t irá realizar uma busca através dos escopos na seguinte ordem:pageContext, request, session e

application.

A tabela 7-19 traz métodos que recebe parâmetros para especificar o escopo. A classejavax.se rvl et. jsp. Page Cont ext fornece variáveis estáticas para representar estes quatro escopos diferentes. A tabela a seguir resume estas variáveis:

Método

Descrição

PAGE_SCOPE

Escopo para atributos armazenados no objeto

pageContext.

REQUEST_SCOPE

Escopo para atributos armazenados no objeto

request.

SESSION_SCOPE

Escopo para atributos armazenados no objeto

session.

APPLICATION_SCOPE

Escopo para atributos armazenados no objeto

application.

Tabela 7-20: Variáveis estáticas de escopo.

O exemplo a seguir ilustra o uso do método "getAttribute" e das variáveis

Page 95: Artigo Interessante WEB

estáticas descritas na tabela anterior:

<%

//Recupera o object "usuario" do escopo pageContext

User uPag=(User)pageContext.getAttibute("user",pageContext.PAGE_SCOPE)

//Recupera o object "usuario" do escopo request

User uReq=(User)pageContext.getAttibute("user",pageContext.REQUEST_SCOPE)

//Recupera o object "usuario" do escopo session

User uSes=(User)pageContext.getAttibute("user",pageContext.SESSION_SCOPE)

//Recupera o object "usuario" do escopo application

User uApp=(User)pageContext.getAttibute("user",pageContext.APPLICATION_SCOPE)

%>

Código 7-9: Exemplo do uso do método getAttibute() com variáveis estáticas

Tratamento de Erros

Esta última categoria dos objetos implícitos tem apenas um membro, o objetoexce pt ion. Este objeto implícito é fornecido com o propósito de tratamento de erros dentro de uma página JSP.

Objeto Exception

O objetoexcept ion 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

Page 96: Artigo Interessante WEB

erro, usando o atributoi sEr rorPage configurado com true na diretiva page. O objetoexception é 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 7-21 abaixo.

Método

Descrição

String getMessage()

Retorna a mensagem de erro descritiva

associada com a exceção quando ela foi

lançada.

void printStackTrace(PrintWriter out) 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.

String toString()

Retorna uma cadeia combinando o

nome da classe da exceção com sua

mensagem de erro, se houver alguma.

Tabela 7-21: Principais métodos da classe Throwable.

O exemplo no código 7-10 abaixo, ilustra o uso do objeto exception em

uma página de erro JSP:

Page 97: Artigo Interessante WEB

<@ page isErrorPage=true %>

<h1>Erro Encontrado</h1>

O seguinte erro foi encontrado:<br>

<b><%= exception %></b><br>

<% exception.printStackTrace(out); %>

Objetos Implícitos

7-27

Criando funções que manipulam objetos implícitos

É possível definir funções na própria página JSP através das tags <%! e %>.

Veja o exemplo abaixo:

<%!

String jogueMoeda(){

String retorno = "";

int i = (int)(Math.random()*10); //um número entre 0 e 10

i = i%2; //resto da divisão de i por 2

if(i==0){

retorno = "cara";

} else {

Page 98: Artigo Interessante WEB

retorno = "coroa";

}return retorno;

}%>

<html>

<body>

<h1>Deu <%= jogueMoeda() %>!</h1>

</body>

</html>

Código 7-11: Exemplo de criação de métodos dentro de JSP.

Nesse trecho de código, código 7-11, uma função é definida dentro de uma página JSP. Essa função é bastante simples, ela simula o “lançamento de uma moeda para cima” e escolhe, aleatoriamente, entre cara ou coroa.

Imagine agora que queremos que a função simule o “lançamento da moeda” várias vezes seguidas. Podemos alterar o código anterior e chamarmos a função várias vezes:

<html>

<body>

<h1>Deu <%= jogueMoeda() %>,

<%= jogueMoeda() %>

<%= jogueMoeda() %>!</h1>

</body>

</html>

Código 7-12: Exemplo do uso de varias chamadas ao método criado

Essa, solução, apresentada no código 7-12, apesar de funcionar, não é a mais adequada. Podemos reescrever a função para receber como parâmetros a quantidades de jogadas

Page 99: Artigo Interessante WEB

que deverão ser efetuadas e fornecer um meio para que a função possa escrever o conteúdo na página JSP:

<%!

void jogueMoeda(int numeroJogadas, JspWriter o){

try{

for(int k=1; k <= numeroJogadas; k++){

//número entre 0 e 10

int i = (int)(Math.random()*10); i = i%2;

if(i==0){

o.print("cara");

} else {

o.print("coroa");

}if (k==numeroJogadas){

o.print("!");

} else {

o.print(", ");

}

}

} catch(Exception e){}

}%>

<html>

<body>

<h1>Deu <% jogueMoeda(10,out); %></h1>

</body>

</html>

Page 100: Artigo Interessante WEB

Código 7-13: Um uso mais adequado de método dentro da JSP.

Essa segunda versão, apesar de ter uma funcionalidade bem parecida

com a anterior traz algumas novidades:

Passamos

como

parâmetro

um

objeto

da

interface

javax.servlet.jsp.JspWriter . É através desse objeto que iremos enviar para a

página JSP o resultado da "jogada". Na chamada da função passamos, além do número de jogadas desejadas, uma referência ao objeto implícitoo ut . É através dessa referência que a função irá imprimir na saída da página JSP o resultado de sua jogada.

É importante aprender que não podemos chamar o objetoo ut (ou qualquer outro objeto implícito) diretamente em uma função declarada dentro de uma página JSP. Portanto, o seguinte código está errado e apresentará um erro em tempo de compilação:

<%!

void jogueMoeda(int numeroJogadas){

for(int k=1; k <= numerovezes; k++){

int i = Math.random();

i = i*10;

i = i%2;

if(i==0){

out.print("cara");

Page 101: Artigo Interessante WEB

} else {

out.print("coroa");

}if(k==numeroJogadas){

out.print("!");

} else {

out.print(", ");

}

}

}%>

<html>

<body>

<h1>Deu <% jogueMoeda(50) %></h1>

</body>

</html>

Código 7-14: Uso incorreto do objeto implícito out

Page 102: Artigo Interessante WEB

Exercícios

Exercício 1: Neste capítulo você estudou os objetos implícitos, agora descreva

cada um destes objetos mostrando as diferenças entre estes tipos de escopo.

Exercício 2: Neste exercício você irá utilizar o objeto implícito session. Iremos

utilizar este objeto para validar se o usuário esta logado e então permitir que as

páginas possam ser acessadas por ele. Siga abaixo os passos para isto.

Passo 1: Crie uma classe chamada UsuarioLogado e nesta classe declare

dois privados atributos, um para armazenar o ID da sessão e outro o nome do

usuário. Gere também os métodos get e set para estes atributos.

Passo 2: No controller do seu sistema quando o usuário for autenticado crie

um objeto da classe UsuarioLogado e o adicione na sessão associado com o nome de atributo “usuario_logado”. Não esqueça de setar para este objeto o nome do usuário que está logando bem como o ID da sessão. Capture o ID da sessão no controller.

Passo 3: Crie um arquivo texto chamado validarSessao.txt e dentro deste

arquivo faça uso do objeto implícito session da seguinte maneira para validar se o usuário está logado ou não, ou seja, se passou pelo controller e era um usuário válido.

<%

String idPagina = session.getId();

UsuarioLogado usr = (UsuarioLogado)session.getAttribute("usuario_logado");

String url = "/contexto/projeto/login.jsp?mensagem=Favor logar no sistema!";

if ( usr == null ) {

response.sendRedirect(url);

return;

}if ( ! usr.getId().equals(idPagina) ) {

Page 103: Artigo Interessante WEB

response.sendRedirect(url);

return;

}

%>

Exercício 3: Agora você irá contruir uma página para exibir os erros de exception

que podem ser gerados nas páginas JSP do seu sistema. Para isto construa uma página JSP que possa ter acesso ao objeto implícito exception e através do uso deste mostre a mensagem de erro de forma a informar o usuário o problema que aconteceu. Lembre-se de utilizar a diretiva page com o atributo isErrorPage e

errorPage como mostrado abaixo.

<%@page

isErrorPage="true" %> e <%@page

errorPage="error.jsp" %>

Page 104: Artigo Interessante WEB

COOKIES

Lidando com Cookies

Umcookie nada mais é que um bloco de informação que é enviado do servidor para o navegador no cabeçalho página. A partir de então, dependendo do tempo de validade docookie, o navegador reenvia essa informação para o servidor a cada nova requisição. Dependo do caso oco o kie é também armazenado no disco da máquina cliente e quando o site é novamente visitado ocooki e é enviado para o servidor, fornecendo a informação desejada.

Oscookies foram a solução adotada pelos desenvolvedores do Netscape para implementar a identificação de clientes sobre um protocolo HTTP que não é orientado à conexão. Esta solução, apesar das controvérsias sobre a possibilidade de quebra de privacidade, passou ser amplamente adotada e hoje os cookies são partes integrantes do padrão Internet, normalizados pela norma RFC 2109.

A necessidade da identificação do cliente de onde partiu a requisição e o monitoramento de sua interação com o site (denominada de sessão) é importante para o desenvolvimento de sistemas para aWeb pelas seguintes razões:

• É necessário associar os itens selecionados para compra com o usuário que deseja adquiri-los. Na maioria das vezes a seleção dos itens de compra é feita por meio da navegação de várias páginas do site e a todo instante é necessário distinguir os usuários que estão realizando as requisições.

• É necessário acompanhar as interações do usuário com o site para observar seu comportamento e, a partir dessas informações, realizar adaptações no site para atrair um maior número de usuários ou realizar campanhas demarketing.

• É necessário saber que usuário está acessando o site para, de acordo com o seu perfil, fornecer uma visualização e um conjunto de funcionalidades adequadas às suas preferências.

Todas essas necessidades não podem ser atendidas com o uso básico do

Page 105: Artigo Interessante WEB

protocolo HTTP, uma vez que ele não é orientado à sessão ou conexão. Com os

cookies é possível contornar essa deficiência, uma vez que as informações que

são neles armazenadas podem ser usadas para identificar os clientes. Existem outras formas de contornar a deficiência do protocolo de HTTP, como a codificação de URL e o uso de campos escondidos nas páginas HTML, mas o uso decookies é simples e padronizada. No entanto, o usuário pode impedir que o navegador aceitecooki es, o que torna o ato de navegar pelaWeb muito desagradável. Neste caso, é necessário utilizar as outras técnicas para controle de sessão.

A API Servlet permite a manipulação explicita decookies. Para controle de sessão o programador pode manipular diretamente os cookies, ou usar uma abstração de nível mais alto, implementada por meio do objetoHtt pSessi on , visto no capítulo 3. Se o cliente não permitir o uso decookies a API Servlet fornece métodos para a codificação de URL. O código 8-1 mostra o uso decookies para armazenar as informações digitadas em um formulário.

<html>

<head><title>Teste de Cookies </title></head>

<body>

<h3>Teste de Cookies</h3>

<%

Cookie[] cookies = request.getCookies();

if (cookies.length > 0) {

for (int i = 0; i < cookies.length; i++) {

Cookie cookie = cookies[i];

cookie.setPath("/");

%>Cookie Nome: <%=cookie.getName()%> <br>

Cookie Valor : <%=cookie.getValue()%> <br><br>

<%}

Page 106: Artigo Interessante WEB

}String cName = request.getParameter("cookienome");

String cValor = request.getParameter("cookievalor");

if (cName != null && cValor != null) {

Cookie cookie = new Cookie(cName ,cValor);

cookie.setPath("/");

response.addCookie(cookie);

}

%>

<form action="cookieTeste.jsp" method=POST>

Nome : <input type=text length=20 name=cookienome><br>

Valor : <input type=text length=20 name=cookievalor><br>

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

</body>

</html>

Código 8-1: JSP para lidar com Cookies. Arquivo cookieTeste.jsp.

Para se criar umcookie é necessário criar um objetoCo okie, passando

para o construtor um nome e um valor, sendo ambos instâncias de String. O

cookie é enviado para o navegador por meio do métodoaddC ook ie( ) do objeto

HttpServletResponse. Uma vez que oscookies são enviados no cabeçalho da

página, o métodoaddC ook i e() deve ser chamado antes do envio de qualquer conteúdo para o navegador. Para recuperar oscookies enviados pelo navegador usa-se o métodoget Cookies () do objetoHttpServle tRequ est que retorna um array deCookie. Os métodos getN ame( ) eg etVal ue() do objeto

Cookie são utilizados para recuperar o nome o valor da informação associada

Aocookie.

Page 107: Artigo Interessante WEB

Os objetos da classeCo o ki e possuem vários métodos para controle do uso decookies. É possível definir tempo de vida máximo docookie, os domínios que devem receber oco o ki e (por default o domínio que deve receber ocoo ki e é o que o criou), o diretório da página que deve receber oc o okie, se oco o ki e deve ser enviado somente sob um protocolo seguro e etc. Por exemplo, para definir a idade máxima de umcookie devemos utilizar o métodos etM axA ge(), passando um inteiro como parâmetro. Se o inteiro for positivo indicará em segundos o tempo máximo de vida docookie. Um valor negativo indica que oco o kie deve apagado quando o navegador terminar. O valor zero indica que o cookie deve ser apagado imediatamente. O trecho de código do código 8-2 mostra algumas alterações no comportamento default de umcookie.

...

Cookie cookie = new Cookie(cName ,cValor);

cookie.setDomain(“*.com.br”); // todos os domínios como targettrust.com.br mas

não *.instrutor.targettrust.com.br

cookie.setMaxAge (3600); // uma hora de tempo de vida

...

Código 8-2: Mudanças no comportamento default do cookie.

Também é importante definir qual o caminho URL do qual o cookie pode ser acessado, através do métodosetPath (), em geral é utilizado na forma: cookie.setPath(“/”). Este comando indica que todas as páginas neste servidor devem receber o cookie de volta.

Gerenciando Cookies

Oscookies são definidos por um servidor da web. Quando um usuário solicita um URL cujo servidor e diretório correspondam àqueles de um ou mais de seuscookies armazenados, oscookies correspondentes são enviados de volta para o servidor. As páginas JSP acessam os seus cookies associados através do métodogetC ook i es() do objeto implícitor equest. De forma similar, as páginas JSP podem criar ou alterarcookies através do métodoaddCook ie () do objeto implícitore spo n se. Esses métodos são resumidos na tabela abaixo:

request

Page 108: Artigo Interessante WEB

getCookies()

retorna uma matriz de cookies

acessíveis da página

response

addCookie()

envia um cookie para o navegador para armazenagem/modificação

A classe Cookie

Manipulamos um cookie através de instâncias da classe

javax.servlet.http.Cookie calma, não é preciso se preocupar com isso. É que o

container JSP insere o comando "import javax.servlet.http.*;" automaticamente

no servlet associado que é gerado na compilação da página JSP.

Essa classe fornece apenas um tipo de construtor que recebe duas variáveis do tipo String, que representam o nome e o valor do cookie. O cookie tem a seguinte sintaxe:

Cookie cookie = new Cookie ("nome","valor");

Código 8-3: Sintaxe de criação de Cookie.

Na tabela 8-2 apresentamos os métodos fornecidos pela classe Cookie:

Método

Descrição

String getName()

retorna o nome do cookie.

String getValue()

retorna o valor armazenado no cookie.

String getDomain()

retorna o servidor ou domínio do qual o

Page 109: Artigo Interessante WEB

cookie pode ser acessado.

String getPath()

retorna o caminho de URL do qual o

cookie pode ser acessado.

boolean getSecure()

indica se o cookie acompanha

solicitações HTTP ou HTTPS.

void setValue(String newValue)

atribui um novo valor para o cookie.

void setDomain(String pattern)

define o servidor ou domínio do qual o

cookie pode ser acessado.

void setPath(String url)

define o caminho de URL do qual o

cookie pode ser acessado.

void setMaxAge(int expiry)

define o tempo restante (em segundos)

antes que o cookie expire.

void setSecure(Boolean flag)

retorna o valor de um único cabeçalho de solicitação como um número inteiro.

Tabela 8-2: Métodos pertencentes a classe Cookie.

Depois de construir uma nova instância, ou modificar uma instância

recuperada através do métodogetC ookies(), é necessário usar o método

addCookie() do objeto response, com a finalidade salvar no navegador do

Page 110: Artigo Interessante WEB

usuário as alterações feitas no cookie. Para apagar um cookie utilizamos a seguinte técnica: chamamos o método "setMaxAge(0)" com valor zero e depois mandamos gravar chamando o método "addCookie()". Isso faz com que o

cookie seja gravado e imediatamente (após zero segundos) expira.

Definindo um cookie

O primeiro passo, então, ao usar um cookie dentro de uma página, é defini-lo. Isto é feito criando uma instância da classe Cookie e chamando os métodos "sets" para definir os valores de seus atributos.

Vamos ver o seguinte exemplo:

<%

String email = request.getParameter("email");

String cookieName = "cookie";

Cookie cookieJSP = new Cookie(cookieName, email);

//define o tempo de vida como 7 dias (604800 segundos)

cookieJSP.setMaxAge(7 * 24 * 60 * 60);

//versão 0 da especificação de cookie

cookieJSP.setVersion(0);

//indica que o cookie deve ser transferido pelo protocolo HTTP padrão

cookieJSP.setSecure(false);

//insere um comentário para o cookie

cookieJSP.setComment("Email do visitante");

// define o caminho URL do qual o cookie pode ser acessado

cookieJSP.setPath("/");

Page 111: Artigo Interessante WEB

//grava o cookie na máquina do usuário

response.addCookie(cookieJSP);

%>

<html>

<head>

<title>Grava Cookie</title>

</head>

<body>

<h1>Grava Cookie</h1>

Esta página grava um cookie na sua máquina.<br>

<a href='readCookie.jsp'>Lê conteúdo do cookie</a>

</body></html>

Código 8-4: Código do arquivo addCookie.jsp.

Vamos criar uma página html com um formulário que irá fornecer um e-

mail que será gravado pela página "addCookie.jsp":

<html>

<body>

<form action="addCookie.jsp">

<input type="text" name="email">

<input type="submit" value="ok">

</body>

</html>

Código 8-5: Código do arquivo mailToCookie.jsp

No exemplo usado (códigos 8-4 e 8-5) o cookie é identificado pelo nome

cookieJSP e recebe o valor passado pelo usuário através de um formulário.

Page 112: Artigo Interessante WEB

Recuperando um Cookie

A página jsp vista anteriormente tem a finalidade de receber um valor (e-

mail) passado através de um formulário de uma página jsp. Este valor é

armazenado de forma persistente em umcookie, e pode ser acessado pelas outras páginas JSP que compartilham o domínio e o caminho originalmente atribuídos ao cookie.

Os cookies são recuperados através do métodoget Cook ies () do objeto implícitorequest. O código 8-6 mostra um exemplo de recuperação do valor de umcookie.

<%

String cookieName = "cookie";

Cookie listaPossiveisCookies[] = request.getCookies();

Cookie cookieJSP = null;

//quando não existe cookies associados o método getCookies() retorna um valor

//null

if (listaPossiveisCookies != null) {

int numCookies = listaPossiveisCookies.length;

for (int i = 0 ; i < numCookies ; ++i) {

//procura pelo cookie

if (listaPossiveisCookies[i].getName().equals(cookieName)) {

cookieJSP = listaPossiveisCookies[i];

cookieJSP.setPath("/");

break;

Page 113: Artigo Interessante WEB

}

}

}%>

<html>

<body>

<h1>Lê Cookie</h1>

<% if (cookieJSP != null) { %>

A pagina "addcookie" gravou o seguinte email: <%= cookieJSP.getValue() %>

<% } else { %>

O cookie não gravou ou o prazo do cookie expirou.

<% } %>

</body>

</html>

Código 8-6: Código do arquivo "readCookie.jsp"

O primeiroscri ptl et nesta página recupera oscookies associados aquela

página e depois tenta encontrar umcookie identificado pelo nome "cookie".

Caso ocooki e não esteja presente a página JSP exibirá o seguinte

resultado:

Figura 8-1: Cookie não presente na página

Porém, caso o cookie tenha sido encontrado, a página exibirá a seguinte

Tela

Figura 8-2: Cookie presente na página

Considerações finais sobre cookies

Apesar da praticidade de se utilizar os cookies oferecidos pelo protocolo

Page 114: Artigo Interessante WEB

HTTP, devemos fazer algumas considerações quanto a sua utilização:

O tamanho dos dados armazenado (nome e valor) não deve

ultrapassar 4K.

O navegador pode armazenar múltiplos cookies, contanto obedece a um certo limite. Um navegador armazena até 20 cookies por configuração de domínio. O navegador armazena também 300 cookies em geral. Se quaisquer uns destes dois limites forem alcançados, espera-se que o navegador exclua cookies menos utilizados.

Exercícios

Exercício 1: Uma vez estudado o mecanismo de cookies, vamos agora adicionar

este recurso a nossa aplicação. Para isto você deve seguir os seguintes passos:

Passo 1: No controller do sistema você deverá, quando o usuário for válido,

criar dois cookies e adicionar os mesmos no response. Veja o código abaixo de

exemplo que pode servir de guia:

// Criar cookies

String lembrar = request.getParameter("lembrar");

if (lembrar != null && lembrar.equalsIgnoreCase("S") ) {

Cookie cLogin = new Cookie("login", login);

Cookie cSenha = new Cookie("senha", senha);

cLogin.setPath("/");

cSenha.setPath("/");

cLogin.setMaxAge(60 * 60 * 5); // 5 horas de vida

cSenha.setMaxAge(60 * 60 * 5); // 5 horas de vida

Page 115: Artigo Interessante WEB

response.addCookie( cLogin );

response.addCookie( cSenha );

}

Passo 2: Na página de login do seu sistema você deve “procurar” no

request se há estes cookies, caso existam você deve exibir os valores dos mesmos nos campos de login e senha. O código abaixo mostra como os cookies podem ser procurados no request:

<%

String login = ""; // string para armazenar o valor do cookie login

String senha = ""; // string para armazenar o valor do cookie senha

Cookie[] cookies = request.getCookies();

if (cookies != null && cookies.length > 0) {

for (int i = 0; i < cookies.length; i++) {

Cookie c = cookies[i];

if (c.getName().equalsIgnoreCase("login")) {

login = c.getValue();

}if (c.getName().equalsIgnoreCase("senha")) {

senha = c.getValue();

}

}

}

%>

Page 116: Artigo Interessante WEB

OUTROS EXERCÍCIOS

Exercícios

Nestes exercícios iremos terminar a aplicação web para a entrega do material didático. A partir dos exercícios realizados nos capítulos anteriores, implemente as funcionalidades ainda não realizadas como:

Exercício 1: Neste exercício você deverá realizar o cadastro de um curso. O

cadastro do curso é feito de maneira semelhante ao cadastro de um instrutor

que você realizou no decorrer do capítulo 6. Para isto siga os passos abaixo:

Passo 1: Crie um JavaBean de curso com os seguintes campos:

private String codigo;

private int codigoCentro;

private String nome;

private int unidadeTreinamento;

private String descricaoResumida;

private double preco;

private int cargaHoraria;

private String salaAula;

private String inCompany;

private String material;

Passo 2: No campo unidade de treinamento do formulário, utilize as

classes UnidadeTreinamentoBean e UnidadeTreinamentoDB para buscar os

valores no banco de dados. Abaixo exemplo de código para você utilizar.

<select name="unidadeTreinamento">

<% Vector unidades = UnidadeTreinamentoDB.getUnidades();

Page 117: Artigo Interessante WEB

for (int i = 0; i < unidades.size(); i++) {

UnidadeTreinamentoBean un = (UnidadeTreinamentoBean)unidades.get(i);

%>

<option value="<%= un.getNumero() %>"><%=un.getDescricao() %></option>

<% } %>

</select>

Passo 3: Utilize a classe CursoDB para fazer a inserção do curso no

banco. Veja o código abaixo que faz uso do método

public String

insert(CursoBean curso)

<jsp:useBean id="curso" scope="page" class="com.targettrust.beans.CursoBean" />

<jsp:setProperty name="curso" property="*" />

<%

String msg = CursoDB.insert(cadastro);

%>

Exercício 2: Agora faremos a página JSP que pode gravar o responsável pelo

material didático. Esta página não fará uso de java beans. Siga os passoa abaixo

para isto:

Passo 1: No campo curso do formulário, utilize as classes CursoBean e

CursoDB para buscar os valores no banco de dados. Utilize a mesma estrutura

para o campo instrutor.

...

<select name="curso">

Page 118: Artigo Interessante WEB

<% Vector cursos = CursoDB.getCursos();

for (int i = 0; i < cursos.size(); i++) {

CursoBean curso = (CursoBean)cursos.get(i);

%>

<option value="<%= curso.getCodigo() %>"><%=curso.getNome() %></option>

<% } %>

</select>

...

<select name="instrutor">

<% Vector instrutores = InstrutorDB.getInstrutores();

for (int i = 0; i < instrutores.size(); i++) {

InstrutorBean inst = (InstrutorBean)instrutores.get(i);

%>

<option value="<%= inst.getCodigo() %>"><%=inst.getNome() %></option>

<% } %>

</select>

...

Passo 2: Utilize a classe MaterialDidaticoDB para definir o responsável pela

entrega do material didático. Você irá utilizar o método abaixo, observe que

o mesmo retorna uma String informando o resultado da operação.

public static String definirResponsavel(String codigoCurso,

int codigoInstrutor,

java.sql.Date dataPrevista,

float royalty)

Veja abaixo o código exemplo para isto que você deverá ter em uma

Page 119: Artigo Interessante WEB

página JSP:

<%

...String msg = "";

msg = MaterialDidaticoDB.definirResponsavel(curso, instrutor, date, royalty);

Exercício 3: Neste exercício você irá fazer o upload e download do material para

dentro do banco de dados. O seu instrutor irá fornecer dois arquivos com as páginas JSP e seus formulários para que este processo possa ser feito. Os arquivos são uploadMaterial.jsp e downloadMaterial.jsp. Abaixo as figuras que mostram como estes arquivos serão exibidos no browser. Siga abaixo os passos para realizar este exercício:

Passo 1: Ajuste no controller o redirecionamento do mesmo quando

chegar uma action solicitando estes formulários para que a mesma

redirecione para as páginas mostradas acima.

Passo 2: Realize a instalação dos servlets DownloadServlet e

UploadServlet no arquivo web.xml para que os mesmos possam ser reconhecidos pelo TomCat como servlets. Estes servlets serão fornecidos pelo seu instrutor. Veja o mapeamento (servlet-mapping) dos mesmos para que no formulário das páginas acima você os chame corretamente.

Exercício 4: Neste exercício você irá validar o usuário para saber se ele é um

instrutor ou não. Até o momento não foi feita esta validação. Agora vamos realizar modificações no controller para podermos então diferenciar entre um administrador, um instrutor e um usuário inválido. Para isto altere o seu controller fazendo uso do método localizado na classe InstrutorDB com a seguinte assinatura:

public static InstrutorBean validaUsuario(String usuario, String senha)

Observe que este método retorna um objeto da classe InstrutorBean, aquel bean que você criou. Este objeto contém informações sobre o instrutor, como, por exemplo, o seu

Page 120: Artigo Interessante WEB

nome. Você deve utilizar estas informações para o objeto a ser adicionado na sessão e que identifica o usuário logado. O código abaixo pode ser utilizado como modelo:

// Verificar se é instrutor

InstrutorBean inst = InstrutorDB.validaUsuario(login, senha);

if ( inst != null ) {

UsuarioLogado usr = null;

usr = new UsuarioLogado(inst.getNome(), "Bem vindo instrutor",

session.getId() );

session.setAttribute("usuario", u);

contexto.getRequestDispatcher(URL_INST_HOME).forward(request, response);

return;

} else {

// Usuário inválido. Não é administrador nem instrutor.

response.sendRedirect( URL_LOGIN );

return;

}