Baixe o app para aproveitar ainda mais
Prévia do material em texto
COMPUTAÇÃO E TI CONTEÚDO Java nas tecnologias JPS- Servlet JSP Copyright © Portal Educação 2013 – Portal Educação Todos os direitos reservados R: Sete de setembro, 1686 – Centro – CEP: 79002-130 Telematrículas e Teleatendimento: 0800 707 4520 Internacional: +55 (67) 3303-4520 atendimento@portaleducacao.com.br – Campo Grande-MS Endereço Internet: http://www.portaleducacao.com.br Dados Internacionais de Catalogação na Publicação - Brasil Triagem Organização LTDA ME Bibliotecário responsável: Rodrigo Pereira CRB 1/2167 Portal Educação P84j Java nas tecnologias JSPservlet JSP / Portal Educação. - Campo Grande: Portal Educação, 2013. 156p. : il. Inclui bibliografia ISBN 978-85-8241-513-9 1. Programa de computação - Java. I. Portal Educação. II. Título. CDD 005 SUMÁRIO 1 FUNDAMENTOS PARA PROGRAMAÇÃO NA WEB 1.1 INTRODUÇÃO 1.2 HISTÓRICO E EVOLUÇÃO DAS LINGUAGENS WEB 1.3 SERVLETS? 1.4 JSP? 1.5 SERVLET X JSP 1.6 SERVIDOR DE APLICAÇÃO WEB: TOMCAT 1.7 ANTES, UMA PALAVRA SOBRE JEE 2 INFRAESTRUTURA 2.1 JAVA 2.2 AMBIENTE DE DESENVOLVIMENTO: ECLIPSE 2.3 TOMCAT: ESTRUTURA DE DIRETÓRIOS 2.4 TOMCAT: INICIANDO 2.5 TOMCAT: ENCERRANDO 2.6 TOMCAT: LOGS 2.7 INCLUINDO BIBLIOTECAS NECESSÁRIAS NO ECLIPSE 3 CONSTRUINDO A PRIMEIRA APLICAÇÃO 3.1 MONTANDO A ESTRUTURA DE DIRETÓRIOS 3.2 CRIANDO O PRIMEIRO SERVLET 3.3 CRIANDO O ARQUIVO WEB.XML 3.4 MONTANDO UM MAPEAMENTO NO WEB.XML 3.5 GERANDO E DISPONIBILIZANDO COM O ANT 3.6 O EMPACOTAMENTO WAR 3.7 EXECUTANDO A APLICAÇÃO 4 SERVLETS 4.1 HIERARQUIA DE ENTIDADES 4.2 A CLASSE HTTPSERVLET 4.3 UMA PALAVRA RÁPIDA SOBRE REQUISIÇÕES GET E POST 4.4 DEFININDO UMA QUERY STRING 4.5 FORMULÁRIOS HTML, UMA REVISÃO 4.6 REQUISIÇÕES E RESPOSTAS 4.7 RECUPERANDO INFORMAÇÕES PASSADAS COMO PARÂMETRO 4.8 ESCREVENDO CONTEÚDO NA SAÍDA PADRÃO 4.9 ARMAZENANDO OBJETOS NA REQUISIÇÃO 4.10 CONFIGURANDO INFORMAÇÕES INICIAIS 5 A TECNOLOGIA JSP 5.1 CRIANDO UM ARQUIVO JSP 5.2 TRADUÇÃO DE JSP PARA UM SERVLET 5.3 TRABALHANDO COM SCRIPTLETS 5.4 SÍMBOLO DE RETORNO DIRETO 5.5 A DIRETIVA PAGE 5.6 OBJETOS PADRÃO EM UM ARQUIVO JSP 5.7 REDIRECIONANDO A RESPOSTA 5.8 EXPRESSION LANGUAGE (EL) 6 USANDO TAGS ESPECIAIS DENTRO DO JSP 6.1 JSTL 6.2 INCLUINDO UMA REFERÊNCIA PARA OS DESCRITORES 6.3 ESCREVENDO NA SAÍDA PADRÃO USANDO O <C:OUT> 6.4 ESCREVENDO CONDIÇÕES COM O <C:IF> 6.5 PERCORRENDO UMA COLEÇÃO USANDO O <C:FOREACH> 6.6 COMO EXPLORAR MAIS ESSE UNIVERSO 7 TAGS CUSTOMIZADAS 7.1 CRIANDO O ARQUIVO DESCRITOR 7.2 VINCULANDO O ARQUIVO DESCRITOR AO PROJETO 7.3 USANDO A TAG DEFINIDA EM UM ARQUIVO JSP 7.4 DEFININDO A CLASSE QUE REPRESENTA UMA TAG 8 TRABALHANDO COM A SESSÃO DO USUÁRIO E FILTROS 8.1 SESSÃO 8.2 CRIANDO E USANDO UMA SESSÃO 8.3 ALTERANDO A CONFIGURAÇÃO DE UMA SESSÃO 8.4 FINALIZANDO UMA SESSÃO 9 FILTROS 9.1 CRIANDO O CÓDIGO DE UM FILTRO 9.2 MAPEAMENTO DE UM FILTRO 9.3 UMA PALAVRA A MAIS SOBRE O PADRÃO DE PROJETO FILTER 10 REUNINDO TODOS OS CONCEITOS EM UMA APLICAÇÃO DE EXEMPLO 10.1 APLICAÇÃO DE EXEMPLO PROGRAMADA EM CAMADAS 10.1.1 Definindo os requisitos 10.2 TELA INICIAL DE LOGIN 10.3 CONFIGURANDO O WEB.XML 10.4 O PADRÃO DE PROJETO MVC 10.5 CONTROLANDO O FLUXO EM UMA SERVLET 10.6 CAMADA DE NEGÓCIO E DESTINO DA REQUISIÇÃO 10.7 RECUPERANDO O USUÁRIO DO BANCO DE DADOS 10.8 IMPEDINDO O ACESSO COM FILTROS 10.9 PERMITINDO AO USUÁRIO SAIR REFERÊNCIAS 1 FUNDAMENTOS PARA PROGRAMAÇÃO NA WEB 1.1 INTRODUÇÃO Com o surgimento e crescimento da Internet, esta passou de exclusividade da academia e defesa e passou a fazer parte do dia a dia do grande público, oferecendo entretenimento, serviços e comunicação a um baixo custo e velocidades cada vez maiores. Inicialmente os aplicativos disponíveis restringiam-se a sites de conteúdo fixo, estático, em que pouca ou nenhuma interação era possível ou se fosse, o custo e tempo de desenvolvimento eram muito grandes. Tendo essa necessidade cada vez maior de construir sistemas e páginas que oferecessem conteúdo dinâmico e personalizado para o usuário, unindo a facilidades de desenvolvimento e curvas de aprendizado cada vez menores, é que todo um conjunto de linguagens de programação e paradigmas de desenvolvimento de software foi surgindo. Neste ponto, o HTML não era mais suficiente para atender a todas as necessidades, ficando com o papel de exibição de conteúdo e deixando a lógica de negócio para o servidor. Desta forma, o servidor deixou de ser apenas uma entidade que recebe requisições e devolve alguma página (ainda que ele continue também com esse papel), mas passou a conter módulos que quando invocados realizavam algum processamento e devolviam um resultado, o que na maioria das vezes era HTML para ser exibido no navegador do usuário, mas poderia ser também um arquivo ou imagem para download, por exemplo. Programar para a web significa ter esses princípios muito bem delimitados, saber onde uma determinada programação vai afetar e como unir as diversas tecnologias em torno de um objetivo. Sempre teremos um servidor em algum lugar que será o responsável por interceptar uma requisição, invocar algum código que faz um processamento, montar uma resposta e devolver o resultado a quem o invocou, tendo sempre em mente que essa exibição será feita na máquina do usuário, sofrendo todas as restrições tecnológicas ou impactos que esse aspecto possa ter. 1.2 HISTÓRICO E EVOLUÇÃO DAS LINGUAGENS WEB Inicialmente, a programação do lado servidor estava restrita à plataforma CGI (Common Gateway Interface), que possui acesso ao sistema servidor, podendo acessar diversos recursos e memória do ambiente. O aspecto negativo dela é que todo esse poder, caso seja mal usado, impacta diretamente no computador como um todo, pois se algum erro for inserido no código, ainda que involuntariamente, ele poderia derrubar o computador inteiro e não somente a aplicação, trazendo prejuízo para outras aplicações e nem sempre conseguindo se restabelecer sozinho. Em geral, esse código era escrito na linguagem C, compilada e gerando executáveis específicos para a arquitetura em que seria executado. Passados alguns anos e observando-se a necessidade cada vez maior de se ter linguagens de programação que suportassem o desenvolvimento do lado do servidor, que fossem mais seguras para o desenvolvimento e cuja curva de aprendizado fosse menor, outras linguagens de programação foram surgindo, como é o caso do PHP e Perl, duas linguagens interpretadas, em que a compilação não é necessária e cuja curva de aprendizado é bem menos inclinada. O problema destas linguagens estava mais no campo da escalabilidade, imaginando que os sistemas estavam cada vez maiores. Ainda que existam sistemas grandes usando essas duas tecnologias, poucos são de missão crítica ou que possuam muitos acessos concorrentes. Entrando em sequência neste mercado aparece a Microsoft com a sua linguagem ASP, com um comportamento próximo do encontrado nas linguagens Perl e PHP e a Sun com a plataforma Java e as primeiras versões do seu JSP/Servlet. 1.3 SERVLETS? A tecnologia Servlet é como se programa na web utilizando a tecnologia Java, a partir de alguns adendos e complementos que a linguagem principal oferece, com suporte a requisições e demais elementos necessários para se programar nesta perspectiva. Existem alguns padrões e regras a serem seguidas para se programar usando esta perspectiva, mas a tendência é que ao seguir esses padrõestoda a programação se torne mais estruturada e fácil de dar manutenção que em outras tecnologias, como PHP ou ASP. Diferente das páginas JSP, aqui o foco está nos objetos que irão fazer parte das regras de negócio do sistema do usuário, ainda que possa ser escrito também o HTML resultante diretamente nestes elementos. Em geral, sistemas web escritos em Java fazem uso desta e da tecnologia de JSP para se alcançar ao objetivo de escrever páginas de conteúdo dinâmico. 1.4 JSP? Ainda que em uma primeira vista JSP e Servlets sejam diferentes, elas são apenas distintas formas de escrever um código buscando alcançar um mesmo objetivo. O termo JSP é a sigla para Java Server Page, outra maneira de escrever código Java para se programar na perspectiva web, só que neste momento o elemento principal é o HTML e não os objetos da página, facilitando a escrita de interfaces gráficas inteligentes e adaptáveis ao universo do usuário. Na tecnologia central de uma página JSP está a linguagem de marcação HTML (Hypertext Markup Language) que serve para formatar o conteúdo que está sendo exibido na tela, só que ela quando usada sozinha não oferece qualquer recurso de lógica ou regras de negócio, servindo apenas para formatação baseada em marcas (também chamadas de tags), daí a necessidade de inserir algum recurso, do lado do servidor, que ofereça esses recursos que faltam a ela. Desta forma, ao juntar o HTML para formatação com a tecnologia Java, o recurso de montar uma tabela dinâmica ou escrever alguma informação de objetos do lado servidor fica facilitado. Como juntar as duas tecnologias, mas tendo o foco principal o HTML, é papel das páginas JSP, serão traduzidos e reduzidos a um Servlet, que trata as requisições feitas para um servidor de aplicação e em seguida tratadas para oferecer algum recurso de volta ao cliente, que normalmente é representado por um navegador (como o Microsoft Internet Explorer ou o Mozila Firefox). 1.5 SERVLET X JSP É praticamente impossível escrever qualquer sistema que faça uso de uma abordagem e não da outra, pois elas caminham juntas, cada qual com seu foco. Pode-se resumir o papel de cada uma da seguinte forma: Servlets JSP Foco principal: controle de fluxo Foco principal: apresentação HTML escrito em código Java Código Java escrito em HTML Sintaxe Java completa Sintaxe Java e mais elementos específicos Ambas as tecnologias fazem uso principal da sintaxe Java encontrada em qualquer programa que possamos ter, com a diferença de que será necessário fazer uso de todo o conjunto específico de classes e interfaces que foram projetadas para oferecer suporte à programação web. No caso específico do JSP, existem ainda algumas variações de sintaxe que buscam facilitar a posterior manutenção de códigos escritos, tendo como foco a interface gráfica do usuário. 1.6 SERVIDOR DE APLICAÇÃO WEB: TOMCAT Durante todo o treinamento precisaremos usar um servidor de aplicações web para testar nossos programas de exemplo. Para a tecnologia JSP/Servlets, o servidor mais utilizado hoje no mundo é o Apache Tomcat, que deriva do projeto do servidor web Apache, só que escrito para oferecer suporte à tecnologia da Sun, seguindo toda a especificação escrita. Neste ponto, vale dizer que a Sun no momento da criação da tecnologia JSP/Servlets definiu um documento contendo a especificação dela, significando a maneira como a Sun entendia tecnologia e como ela deveria ser implementada pelas empresas que quisessem oferecer suporte a ela. Em seguida, ela passou a certificar os servidores que foram surgindo como seguidores ou não da sua especificação, garantindo uma visão padronizada da sua tecnologia. Neste caso, o Tomcat é o chamado servidor de referência, por seguir toda a especificação e ser reconhecido pela Sun como tal. Ele pode ser obtido gratuitamente do site da Apache e por ser um software livre, seu código-fonte pode ser obtido e alterado livremente. Além disso, ele é usado em servidores de aplicação que oferecem suporte à tecnologia JEE (Java Enterprise Edition) como o JBoss, que o utilizam como servidor para o tratamento de requisições web. Antes de prosseguir, portanto, vá até o site da Apache (http://tomcat.apache.org/) baixe o arquivo compactado na versão 5.x (no momento da confecção deste material, a versão de produção mais atual era a 5.5.29), descompacte-o em um diretório em que você tenha acesso para posterior acesso e manipulação, pois ele será muito utilizado durante todo o treinamento para que possamos testar nossos programas. Dentre as várias opções de executáveis que ele oferece na página de download, deve ser baixada a versão que aponta para a opção Core, que significa todo o necessário para nossas execuções. Obtenha o arquivo zipado (existem as opções em tar.gz e instalador para Windows), pois esta acaba sendo a mais simples de ser manipulada. O arquivo não tem mais que nove megabytes de tamanho. 1.7 ANTES, UMA PALAVRA SOBRE JEE O termo JEE que surgiu no capítulo anterior merece uma explicação, pois ele representa um dos três caminhos ou divisões que hoje existem dentro das tecnologias Java. Ele se refere à Java Enterprise Edition ou de forma geral e bem aberta à programação usando servidores. Neste aspecto, a programação web é apenas uma das possibilidades, pois o termo JEE acaba sendo mais amplo, pois traz também os componentes de negócio, os EJB (Enterprise Java Beans). Esses EJBs são componentes Java que possuem basicamente regras de negócio que servem para executar alguma tarefa específica sem estar ligada diretamente a uma interface gráfica, seja ela Web, Desktop ou móvel, podendo interagir com qualquer uma delas. O Tomcat, como servidor de aplicações web, não oferece suporte aos EJBs, mas apenas à tecnologia JSP/Servlets. Para a execução desses objetos de negócio é necessário o uso de um servidor de aplicações, em um contexto mais amplo. Atualmente, o servidor JBoss é o mais utilizado no mundo para oferecer suporte aos EJBs e este traz dentro de si um servidor Tomcat para tomar conta da parte web. Disso, podemos concluir que a especificação JEE engloba a especificação web, gerando uma solução muito mais ampla para estas soluções completas. Além do JBoss, outros servidores que possuem relevância e alcance do mercado são o Glassfish, que é da própria Sun e é utilizado como implementação de referência para servidores JEE, o Weblogic, que era da BEA até que esta foi comprada pela Oracle, fazendo parte da família de produtos Oracle (e como a Sun foi comprada pela Oracle, então esta acabou trazendo para si os dois servidores) e o Geronimo, que é do projeto Apache. Dito tudo isso, neste momento o que nos importa é apenas a parte web da especificação de programação para servidores, portanto será necessário baixar e rodar apenas o Tomcat para nossos futuros testes. 2 INFRAESTRUTURA 2.1 JAVA Ainda que o servidor de aplicações que iremos utilizar seja o Tomcat, para que este funcione e possa executar nossos arquivos ou mesmo para compilar nossos arquivos (lembrando que todo o código, ainda que tenha bibliotecas especiais é Java) é preciso ter instalado na máquina de trabalhar uma versão do Java igual ou superior à versão 5.0, que já traz uma série de novos recursos e facilidades. Ele pode ser obtido diretamente do site da Sun (http://java.sun.com/javase/downloads/widget/jdk6.jsp) e não possui custo. Vale lembrar que é necessário baixar o JDK (Java Development Kit), pois é com ele que conseguiremos compilar e não somente executar programas em Java. Será necessário fazer toda a configuração para que os demais programas possam ser executados corretamente. Para testar se esta instalação ocorreu corretamente, abra uma janela command (isso pode ser feito digitandocmd em Iniciar > Executar) e digite o comando javac, conforme a figura abaixo: FIGURA 1 - INSTRUÇÕES PARA UM COMANDO JAVAC FONTE: Disponível em: <http://java.sun.com/javase/downloads/widget/jdk6.jsp>. Acesso em: 02/07/2010 Ainda que o comando executado não receba nenhum argumento, será mostrada uma série de instruções de ajuda para a execução correta posterior, mas isso indica que o programa foi corretamente instalado, pois se ocorreu algum problema na instalação, será mostrada a mensagem de comando não encontrado. 2.2 AMBIENTE DE DESENVOLVIMENTO: ECLIPSE Para se desenvolver sistemas comerciais, possuir alguma ferramenta que facilite o processo é fundamental. Para Java, existem diversas, mas uma que ganha cada vez mais destaque é a ferramenta chamada Eclipse, que traz enormes benefícios ao desenvolvimento. Atualmente ela está em sua versão 3.5, chamada Galileo. Ela pode ser obtida gratuitamente do site do projeto (http://www.eclipse.org/downloads/) e para começar o seu uso, basta descompactá-la e dar um duplo clique no executável principal, que fica dentro da página principal criada. Ao iniciar a execução do mesmo, deve-se aparecer a seguinte tela: FIGURA 2 - TELA DE ABERTURA DA IDE ECLIPSE FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Sendo que o nome que aparece do termo Eclipse pode variar conforme a versão obtida. Em seguida, será pedido para o usuário informar onde deseja que seja definido o chamado workspace, que é o diretório onde os arquivos dos projetos deverão ser salvos. No momento, pode ser escolhida qualquer pasta do sistema de arquivos do usuário. O Eclipse é um dos exemplos de IDE (Integrated Development Environment) que poderia ser traduzido para Ambiente de Desenvolvimento Integrado, por integrar todas as ferramentas necessárias para facilitar o desenvolvimento das aplicações. Talvez atualmente ela seja a mais famosa e utilizada no mundo para desenvolvimento Java, mas existem diversas outras muito boas que também podem ser utilizadas, como o Netbeans da própria Sun ou o JBuilder da CodeGear. No caso do Eclipse existe um conjunto de empresas que mantém o projeto, liderados pela IBM. O importante de tudo isso é escolher alguma ferramenta para este tipo de desenvolvimento para tornar todo o processo mais simples para a equipe. FIGURA 3 - ESCOLHA DO WORKSPACE PARA ESTA EXECUÇÃO FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Repare na figura acima que é possível navegar na estrutura de diretórios utilizando o botão Browse da interface gráfica. Uma vez escolhido o caminho e apertado o botão “OK”, chega-se à seguinte tela: FIGURA 4 - TELA INICIAL SEM PROJETOS DO ECLIPSE FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 O ambiente principal reúne todas as facilidades para o desenvolvimento de projetos em Java. Essa interface gráfica pode variar de acordo com as extensões (chamadas plugins) que foram baixadas ou instaladas no ambiente. De forma geral, na esquerda ficam os projetos e a navegação pelos seus arquivos, no topo, os botões de ação, no centro, o código-fonte que está sendo editado e abaixo informações gerais e de execução de programas. Codificação usando o Eclipse funciona orientada a projetos, então antes de escrever qualquer código é necessário criar algum projeto Java com toda a sua infraestrutura mínima. Isso pode ser feito por meio de assistentes que o conduzem durante todo o processo. Iremos criar um projeto que posteriormente será utilizado para os exemplos de JSP/Servlets. Vá em “File > New > Java Project”. FIGURA 5 - CRIANDO UM NOVO PROJETO FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Será aberto o seguinte assistente: FIGURA 6 - DEFININDO UM NOME PARA O PROJETO FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Neste caso, o nome do projeto dado foi PortalEducacao, mas poderia ter sido qualquer termo que trouxesse significado para o projeto em questão. Todas as demais configurações são mantidas, inclusive o caminho de onde o projeto deve ser salvo e que corresponde ao workspace originalmente escolhido. Finalizado este preenchimento, clica-se no botão “Next”, para ir para a próxima página do assistente. FIGURA 7 - TELA DE CONFIGURAÇÃO DO PROJETO FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Na página seguinte existe uma série de outras configurações que no momento serão mantidas como estão. O próximo passo é apertar o botão “Finish” para a conclusão do assistente. FIGURA 8 - NOVO PROJETO CRIADO NA ABA DA ESQUERDA FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Na aba da esquerda aparece agora o projeto que acabamos de criar, com o nome e arquivos básicos necessários para a compilação e execução de qualquer projeto em Java. Vale destacar que todo o arquivo Java que for criado deve ser colocado dentro da pasta src. Para fins de teste, vamos criar um arquivo para verificar se tudo está funcionando corretamente. Clicando com o botão direito sobre a pasta src, escolha “New > Class”. FIGURA 9 - CRIANDO UMA NOVA CLASSE PELO ASSISTENTE FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Será aberto o seguinte assistente: FIGURA 10 - DADOS PARA A NOVA CLASSE FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Foi dado um nome para a classe e em seguida apertado o botão “Finish”. FIGURA 11 - EXIBINDO OS DADOS DA NOVA CLASSE FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Uma vez criado o arquivo ele aparece na parte da esquerda, dentro do diretório src, no pacote padrão (já que nenhum foi informado) e com a listagem dos métodos que devem fazer parte dele. Ao abrir o arquivo criado, o seu conteúdo aparece no centro, no editor principal, já com as palavras reservadas destacadas, facilitando o desenvolvimento. Foi escrito o comando System.out.println(), que imprime algum texto no terminal e ao mandar executar o comando, o resultado é mostrado na parte inferior, na aba chamada Console. Uma das grandes facilidades do uso de um ambiente como esse é concentrar em um mesmo lugar todas as informações necessárias para o desenvolvimento. Outro recurso muito interessante que esses ambientes trazem é a compilação on-line, ou seja, caso algum erro de compilação seja identificado, ele já é mostrado durante a edição do arquivo. Veja a próxima imagem, que força um erro: FIGURA 12 - MOSTRANDO COMO OS ERROS SERÃO MOSTRADOS FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 No exemplo acima, o erro foi forçado ao remover o ponto e vírgula do final do comando. Imediatamente, o compilador acusou o erro e o ambiente de desenvolvimento marcou a linha como errada e indicou o erro que o compilador encontrou para ela. Com isso, eventuais correções não precisam esperar até que a compilação efetivamente seja disparada, ganhando em muito o tempo de desenvolvimento. 2.3 TOMCAT: ESTRUTURA DE DIRETÓRIOS Uma vez descompactado o conteúdo do arquivo baixado para o Tomcat, deve-se ter uma estrutura diretórios parecida com a seguinte: Diretório Significado bin Possui os executáveis necessários para disparar a execução e demais tarefas do servidor. common Armazena todos os componentes comuns às diversas aplicações que serão instaladas no sistema. conf Diretório com as configurações do servidor e das aplicações neleinstalados. logs Guarda os arquivos de log. server Arquivos que servem para o sistema funcionar. shared Arquivos compartilhados por todo o servidor para ele funcionar. temp Arquivos temporários criados durante a execução. webapps Diretório em que as aplicações web devem ser instaladas para poderem ser executadas. É o diretório principal para o nosso treinamento e onde iremos gastar a maior parte do tempo. work Arquivos temporários criados durante a execução. Como já mencionado acima, o diretório de nosso maior interesse vai ser o chamado webapps, pois todas as aplicações web (web applications) ficarão localizadas ali dentro. Outro diretório de interesse para o treinamento vai ser o diretório bin, pois é lá que ficam os executáveis para iniciar o funcionamento do servidor. Posteriormente, caso seja necessário referenciar o diretório de instalação do Tomcat, ele será chamado de {TOMCAT_HOME}. 2.4 TOMCAT: INICIANDO Para começar o servidor de aplicações é necessário chamar o executável startup.bat no Microsoft Windows (num ambiente Linux existe o equivalente startup.sh, esse é o único ponto que varia de sistema operacional para sistema operacional, pois todo o resto é comum). Dar um duplo clique nele faz com que o servidor de aplicações seja iniciado. FIGURA 13 - INFORMAÇÕES DE INICIALIZAÇÃO DO TOMCAT FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Ao clicar duas vezes no arquivo statup.bat, inicia-se uma tela prompt onde é escrito tudo que está acontecendo com o servidor. A linha final mostra que o servidor subiu e gastou próximo de dois segundos para isso. Uma das características do Tomcat é a sua velocidade para inicialização. Para verificar se a inicialização ocorreu corretamente e o servidor está funcional, pode-se digitar o endereço padrão para invocar a página inicial http://localhost:8080, resultando na seguinte página: FIGURA 14 - PÁGINA INICIAL DO TOMCAT QUANDO INICIADO FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Esta é a página inicial do console, onde se pode obter outras informações do servidor e acessar os ambientes de auxílio ao desenvolvimento. Para tanto, usa-se como endereço para o navegador o endereço de acesso local, utilizando o protocolo HTTP, acessando a máquina local (o termo localhost é comum e utilizado mesmo em outras plataformas) e em uma porta específica, a 8080, que vem configurada por padrão e que eventualmente pode ser alterada para outro valor, caso seja desejado ou necessário, conforme a instalação em produção. 2.5 TOMCAT: ENCERRANDO Para finalizar a execução do Tomcat na plataforma Microsoft Windows, basta fechar a tela prompt aberta, que o processo será finalizado automaticamente (tentar abrir o endereço anterior faz com que um erro 404 de página não encontrada seja retornado). Já para um ambiente Linux, uma das maneiras mais diretas de encerrar o servidor é executar os seguintes comandos, nesta ordem: ps –ef | grep tomcat kill -9 <pid> O comando ps –ef retorna todos os processos rodando na máquina naquele momento. Em seguida, o comando grep filtra os comandos retornados, mantendo apenas aquele que tenha no nome tomcat. Os dois comandos são unidos pelo símbolo | (pipe). A linha mostrada traz um número inteiro que identifica o processo que o sistema operacional subiu na máquina. Já o comando kill -9 finaliza qualquer processo, assim, passando o código desejado, o processo é encerrado. 2.6 TOMCAT: LOGS Em qualquer aplicação, seja durante o desenvolvimento, seja durante sua utilização em produção, é fundamental o acompanhamento de como os arquivos de log estão se comportando, pois diversos erros ou situações de exceção podem estar sendo gravados ali ou ainda, caso algum erro aconteça, as razões para o problema podem estar sendo gravadas e trazem indícios de como resolvê- los. Por padrão, o Tomcat traz seus arquivos para esta finalidade no diretório logs. Para nossos propósitos, o arquivo mais importante que deve ser monitorado sempre e mais ainda quando algum comportamento não esperado acontece é o chamado catalina. Seu padrão de nome é catalina.AAAA- MM-DD.log, sendo alterado sempre que passamos de um dia para outro. É nele que todos os erros e saídas padrão (incluindo o System.out.println()) são gravados. 2.7 INCLUINDO BIBLIOTECAS NECESSÁRIAS NO ECLIPSE Já foi mencionado anteriormente que para o desenvolvimento de aplicações web na perspectiva Java são necessárias algumas bibliotecas especiais, que trazem as classes e interfaces indispensáveis para este desenvolvimento. Para fazer isso, precisamos incluí-las no Eclipse, pois todo o desenvolvimento acontece lá e a ferramenta precisa estar preparada para reconhecer esses componentes especiais. Como o Tomcat também vai precisar dessas bibliotecas para executar os programas, ele já traz, dentro das suas bibliotecas comuns que todas as aplicações usam, essas bibliotecas, empacotadas em forma de arquivos.jar, uma extensão criada pela plataforma Java para facilitar a disponibilização de componentes, mas que nada mais é que um arquivo compactado que segue algumas regras e padrões. Para este material, faremos uso das bibliotecas servlet-api.jar e jsp-api.jar, sendo que ambas ficam dentro do diretório common/lib da instalação padrão do Tomcat. Para fazer a vinculação com o Eclipse, é necessário alterar a configuração padrão do projeto criado, clicando com o botão direito sobre a pasta raiz do projeto e escolhendo a opção Properties (última opção do menu). FIGURA 15 - ALTERANDO AS PROPRIEDADES DE UM PROJETO FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Será aberta uma tela de propriedades gerais do projeto. Deve-se procurar em seguida o item “Java Build Path” e depois a aba “Libraries”, como mostrado na próxima figura: FIGURA 16 - INCLUINDO NOVAS BIBLIOTECAS NO CLASSPATH DO PROJETO FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Na aba aberta, ao apertar o botão “Add External Jars...” será disponibilizado um assistente em que será possível encontrar, dentro do sistema de arquivos, os jars mencionados acima. FIGURA 17 - ESCOLHENDO OS .JAR DO PRÓPRIO TOMCAT FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Uma vez que o botão Abrir tenha sido selecionado, as bibliotecas aparecerão na lista de componentes disponíveis e prontos para serem utilizados pelo projeto como um todo. FIGURA 18 - INDICAÇÃO DE COMO AS BIBLIOTECAS APARECERÃO NO ECLIPSE FONTE: Disponível em: <http://www.eclipse.org/downloads>. Acesso em: 02/07/2010 Para finalizar o processo, basta apertar o botão “OK”. Feito isso, todas as classes que estão dentro das bibliotecas poderão ser utilizadas. Esse procedimento pode ser utilizado para qualquer futura outra biblioteca que se desejar incluir no projeto. 3 CONSTRUINDO A PRIMEIRA APLICAÇÃO 3.1 MONTANDO A ESTRUTURA DE DIRETÓRIOS Para se construir aplicações web usando Java deve-se seguir uma estrutura bem definida de diretórios, com cada peça colocada em um determinado lugar, pois no momento em que a aplicação for colocada para rodar, no servidor de aplicação, este servidor irá buscar cada uma das peças nos locais predefinidos, verificando se tudo foi feito corretamente, para em seguida disponibilizar tudo para uso e funcionamento correto da aplicação. Isso vale tanto para os diretórios quanto para os arquivos que vão dentro de cada um desses diretórios, pois existem alguns arquivos de configuração que precisam estar em locais bem definidos. Por hora, iremos nos preocupar apenas com a estrutura de diretórios e como eles devem ser montados na aplicação.A imagem a seguir mostra uma estrutura básica deles: FIGURA 19 - DIRETÓRIOS BÁSICOS CRIADOS FONTE: Disponível em: <http://java.sun.com/javase/downloads/widget/jdk6.jsp>. Acesso em: 02/07/2010 Veja que na imagem acima, que reflete o projeto criado anteriormente, mostra a alteração que o projeto sofreu. Foram criados três diretórios novos: jsp: Para armazenar arquivos de interface que tanto podem ser escritos com simples HTML, como arquivos JSP que podem trazer lógica de programação na sua constituição. Esse diretório é opcional e existe apenas para dar maior organização ao projeto como um todo. WEB-INF: Diretório obrigatório, inclusive com a escrita sendo feita toda em maiúscula e com um traço separando as palavras. É dentro dele que todo o código compilado e arquivos de configuração da aplicação ficarão localizados. classes: Diretório obrigatório, inclusive com a escrita sendo feita toda em minúsculas. Dentro dele que serão colocados os arquivos Java compilados (relembrando, com a extensão .class). Vale lembrar que é dentro do diretório src que todo o código-fonte, com extensão .java, deve ficar. Dentro deste diretório foi criada uma estrutura de pacotes para também facilitar a organização do projeto. Internamente, essa estrutura de pacotes é refletida em um conjunto de pastas e subpastas em que o código-fonte deverá permanecer. 3.2 CRIANDO O PRIMEIRO SERVLET A construção básica de qualquer aplicação web em Java reside no conceito de Servlet. Ele representa uma classe Java responsável por tratar uma requisição feita por um cliente, montar uma resposta e devolvê-la ao usuário. De forma geral, ele é uma classe Java que possui um comportamento especial que lhe dará a funcionalidade necessária para fazer os devidos tratamentos. Considere o exemplo abaixo de um pequeno Servlet: package br.com.pe.curso; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PrimeiroServlet extends HttpServlet { @Override protected void doGet( HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { System.out.println("olah mundo..."); } } Ainda que simples, esse código traz muitas informações. Primeiro, a definição do pacote, na primeira linha, indica a localização, dentro da estrutura de diretórios do projeto, onde o código-fonte está localizado. O nome das pastas são separados por pontos e sem considerar o diretório raiz, src. Abaixo, segue uma série de classes importadas de outros pacotes (todos internos da linguagem Java ou das bibliotecas de Servlets) que servirão para compor os objetos básicos necessários para a funcionalidade. Abaixo dessas declarações segue a criação da classe propriamente dita. Ela foi chamada de PrimeiroServlet, seguindo o padrão de nomenclatura Java e um ponto importante é ela estender a class HttpServlet, ou seja, significa dizer que ela é um tipo de Servlet que trata requisições do tipo HTTP, que durante todo o treinamento e vida de desenvolvimento, é o que vai ser importante. Ao usar herança, significa dizer que todos os métodos que foram definidos na classe pai estão também definidos na classe filha que acabamos de criar. Usando um dos conceitos de orientação, podemos sobrescrever algum método herdado para alterar o comportamento de acordo com a nossa necessidade. A anotação @override faz isso ser explícito, pois obriga o compilador a procurar na classe pai algum método que case exatamente com aquele que estamos redefinindo. E o método em questão é de extrema importância, pois é ele que será chamado quando a requisição chegar ao servidor e este a repassar para o programa que irá tratá-la. Em aplicações web não existe um método main() como em aplicações normais que rodam diretamente na máquina do usuário, fazendo esse papel os chamados métodos de serviço, que neste caso está representando pelo doGet(), que poderá tratar requisições que forem enviadas utilizando o método GET. A assinatura do método (lembrando que a assinatura é composta pelo nome e lista de parâmetros de entrada do método) considera dois parâmetros de entrada: um objeto do tipo HttpServletRequest, representando a requisição e um outro objeto do tipo HttpServletResponse, representando a posterior saída, após o processamento do método. Esses dois objetos são específicos para tratarem requisições do tipo HTTP, possuindo uma série de métodos de interesse para o funcionamento da aplicação. Ao longo do material eles serão revisitados. A visibilidade do método é proteced, significando que apenas objetos no próprio pacote ou classes que sejam suas filhas podem acessá-lo, e tipo de retorno void, indicando que nada será retornado por este método. Além disso, ele possui uma marcação que indica a possibilidade de lançar dois tipos de exceção: ServletException específica para problemas encontrados durante a execução do Servlet e IOException, pois como estaremos trabalhando com a escrita de informações por um canal, eventualmente esse canal pode ter algum problema. Ainda que eles indiquem os erros, eles não necessariamente irão ocorrer, tudo dependendo do comportamento do código que será implementado. O código em si não traz nenhum benefício direto, apenas testar se toda a infraestrutura necessária está pronta para funcionar, pois esta linha de código simplesmente irá imprimir nos logs do servidor de aplicação o termo “olah mundo...”, não refletindo nada na interface gráfica do usuário ou em qualquer outro ponto. 3.3 CRIANDO O ARQUIVO WEB.XML Apenas implementar a classe do Servlet que irá tratar requisições não é suficiente, pois em Java, a URL invocada (ou formulário enviado) é totalmente desacoplado de qual trecho de código será chamado. Em outras linguagens, como PHP e Perl, os nomes dos arquivos e diretórios representam o que está sendo chamado, o que torna menos segura a aplicação, pois de alguma forma possui-se conhecimento da estrutura de arquivos em questão. Existem alguns componentes e projetos que minimizam isso, mas no fundo, tudo continua sendo uma questão de mapeamento. No mundo dos Servlets, o mapeamento é feito num arquivo especial, chamado web.xml e que deve ficar localizado dentro do diretório WEB-INF. Importante, o nome deve ser exatamente esse e o ele deve ser colocado exatamente no diretório WEB-INF, pois é ali que o servidor de aplicação fará uma busca tentando encontrar o arquivo de mapeamento para disponibilizar a aplicação. A propósito, falar que o web.xml é apenas um arquivo de mapeamento é não lhe dar o devido crédito, pois ele é responsável por configurar toda a aplicação, nos seus diversos aspectos, sendo o mapeamento de URLs e Servlets apenas um deles. Por se tratar de um arquivo XML, ele deve seguir toda a padronização de escrita de arquivos XML. Dentre os principais pontos, podemos destacar: Arquivos XML são baseados em marcações, também conhecidas como tags. Maiúsculas e minúsculas fazem diferença na escrita deles. Toda marcação que abre deve ter seu correspondente fechando. Além disso, ele deve seguir a definição existente na especificação JEE para a parte web, indicando quais marcações podem existir, em que ordem e com quais atributos. Ao longo do treinamento passaremos pelos principais itens deste documento, de momento, o importante é criar um documento simples como será demonstrado no próximo item. 3.4 MONTANDO UM MAPEAMENTO NO WEB.XML Dentro do diretório WEB-INF onde foi criado o arquivo web.xml, altere o arquivo para ter o conteúdo parecido com o do próximo exemplo: <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Portal Educacao</display-name> <servlet> <servlet-name>Primeiro</servlet-name> <servlet-class>br.com.pe.curso.PrimeiroServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Primeiro</servlet-name> <url-pattern>/teste</url-pattern> </servlet-mapping> </web-app> Neste arquivo, usa-se a versão 1.0 do XML, com padrão de codificação UTF-8. Essa primeira linha não é uma tag propriamente dita, mas apenas uma forma de indicar para quem for ler esse arquivo de que forma deve ser feita. A primeira marcação é a indicada por <web-app> (repare que ela tem um correspondente </web-app> no final do arquivo, indicando o seu fechamento, sendo que colocar uma barra na frente da tag é uma maneira de indicar que ela é o seu fechamento). Ela engloba todas as demais marcações (outra característica de arquivos XML) e possui uma série de atributos que servem para indicar qual o formato que o arquivo deve seguir. Dentro das tags principais aparece a tag que indica qual o nome que o servidor de aplicações deve usar para referenciar a aplicação como um todo. Os dois outros blocos são a parte importante do arquivo. A tag <servlet> serve para definir quais os Servlets irão existir na aplicação, podem existir qualquer quantidade de blocos definindo Servlets no arquivo. Dentro dele deve ser escrito, no mínimo, um nome para referenciá-lo e para qual classe ele está mapeado. No nosso exemplo, devemos colocar o caminho completo, incluindo a estrutura de pacotes e mais o nome da classe, só que sem a extensão. Abaixo, segue o mapeamento da URL propriamente dita. Em seguida, a tag <url-pattern> deve ser entendida como qualquer URL que o usuário digitar que casar exatamente com o termo, deve ser tratado pelo Servlet definido pela tag <servlet-name>. Assim, é possível que URLs totalmente diferentes sejam tratadas por uma mesma classe. No momento em que a aplicação for instalada e preparada para executar, o servidor irá verificar se todos os Servlets que foram declarados estão efetivamente mapeados corretamente para uma classe Java que seja filha da classe HttpServlet. 3.5 GERANDO E DISPONIBILIZANDO COM O ANT Da forma como está, a aplicação mínima necessária para rodar já está pronta, só que faltam algumas aplicações a respeito de como disponibilizar (outro termo bastante usado para essa ação é deploy). Como já mencionado anteriormente, todas as aplicações web que forem instaladas no servidor devem ficar no diretório webapps do servidor de aplicação Tomcat. Mas esse é um requisito geral e superficial, que não menciona todos os detalhes necessários. Por exemplo, todo código compilado obrigatoriamente deve ficar dentro do diretório WEB-INF/classes, o que no momento não está acontecendo. Uma maneira de se cumprir essas últimas premissas seria manualmente posicionar (copiando e colando) os elementos faltantes, o que seria demorado e propenso a erros. Por sua vez, existem diversas ferramentas que auxiliam e automatizam procedimentos recorrentes e que são geralmente os mesmos. Por exemplo, a ferramenta Ant que já vem com o Eclipse e que baseado num arquivo XML executa tarefas com o objetivo de gerar uma aplicação completa, pronta para ser instalada. Para tanto, devemos criar um arquivo build.xml (este é o nome padrão para essa funcionalidade, mas não é mandatório que seja esse nome exatamente) e incluir nele o código necessário para compilar, gerar, empacotar e copiar nossa aplicação para o local correto: <!DOCTYPE project []> <!-- O atributo default indica <target> deve --> <!-- executar primeiro. --> <project basedir="." default="copiar" name="PortalEducacao"> <target name="init"> <echo>INICIALIZACAO DE VARIAVEIS</echo> <!-- Raiz do projeto. Onde o buil.xml estah. --> <property name="root.dir" value="." /> <!-- Onde o codigo-fonte fica salvo. --> <property name="fontes.dir" value="${root.dir}/src" /> <!-- Diretorio da instalacao do Tomcat. Alterar para a sua realidade. --> <property name="tomcat.dir" value="C:/Projetos/PortalEducacao/JSPServlets/apache-tomcat-5.5.29" /> <!-- Diretorio onde o codigo JSP ficarah salvo. --> <property name="web.dir" value="${root.dir}/jsp" /> <!-- Diretorio auxiliar para realizar as compilacoes. --> <property name="build.dir" value="${root.dir}/dirGeracao" /> <!-- Diretorio WEB-INF para a geracao. --> <property name="webinf.dir" value="${build.dir}/WEB-INF" /> <!-- Diretorio onde o codigo compilado ficarah. --> <property name="classes.dir" value="${webinf.dir}/classes" /> <!-- Diretorio em que o pacote gerado ficarah. --> <property name="dist.dir" value="${root.dir}/dist" /> <!-- Nome do arquivo resultante. --> <property name="arquivoWAR" value="portalEducacao.war"/> <!-- Diretorios que devem ser levados em consideracao na compilacao. --> <!-- Como usamos bibliotecas do tomcat, elas precisam entrar neste ponto. --> <path id="classpath"> <fileset dir="${tomcat.dir}/common/lib" /> </path> </target> <target name="clean" depends="init"> <echo>RECRIANDO DIRETORIOS DE GERACAO</echo> <!-- Apago os diretorios auxiliares, caso existam. --> <delete dir="${build.dir}" /> <delete dir="${dist.dir}" /> <!-- Recrio os diretorios auxiliares. --> <mkdir dir="${build.dir}"/> <mkdir dir="${dist.dir}"/> </target> <target name="war" depends="clean"> <echo>GERANDO PACOTE WEB</echo> <!-- Copia para o diretorio auxiliar todo o conteudo do diretorio JSP. --> <copy todir="${build.dir}/jsp"> <fileset dir="${web.dir}" /> </copy> <!-- Cria o diretorio onde o codigo compilado ficarah. --> <mkdir dir="${classes.dir}"/> <!-- Executa a compilacao, indicando de onde pegar os arquivos --> <!-- e para onde eles deverao ser colocados. Levando em consideracao --> <!-- as bibliotecas definidas pela variavel classpath. --> <javac srcdir="${fontes.dir}" destdir="${classes.dir}" includes="**" debug="true"> <classpath refid="classpath" /> </javac> <!-- Copiar o arquivo web.xml para o lugar correto. --> <copy todir="${webinf.dir}" file="${root.dir}/WEB-INF/web.xml" /> <!-- Compactar o diretorio auxiliar criando um arquivo unico --> <!-- e coloca-lo no diretorio dist, para poder ser manuseado. --> <jar destfile="${dist.dir}/${arquivoWAR}"> <fileset dir="${build.dir}" /> </jar> <delete dir="${build.dir}" /> </target> <target name="copiar" depends="war"> <echo>COPIANDO ARQUIVO (FAZENDO DEPLOY)</echo> <!-- Copia o arquivo gerado e que estah no dist para o --> <!-- diretorio webapps do tomcat. --> <copy file="${dist.dir}/${arquivoWAR}" todir="${tomcat.dir}/webapps" /> </target> </project> O que cada trecho do código faz já está explicado dentro dele mesmo. De forma geral, ele serve para recuperar todos os arquivos Java da aplicação, compilando-os em seguida. Caso algum erro seja encontrado durante a compilação, todo o processo para e o erro é informado. Depois de compilado, o script recupera os arquivos necessários montando-os nos pontos corretos. O penúltimo passo é empacotar todo o diretório temporário de geração criando um arquivo único para facilitar o processo de instalação, sendo o último passo mover o arquivo gerado para o diretório {TOMCAT_HOME}/webapps. Para executar esse script de dentro do próprio Eclipse, basta clicar com o botão direito sobre ele, ir até a opção Run As e em seguida escolher Ant Build. O console do próprio Eclipse irá mostrar a evolução da execução, indicando eventuais erros ou então mostrandoao final que o processo foi corretamente realizado. Para verificar se tudo está certo, vá até o diretório em que o Tomcat está instalado e veja se no subdiretório webapps o arquivo gerado foi corretamente copiado para lá. FIGURA 20 - COMO EXECUTAR O ANT FONTE: Disponível em: <http://java.sun.com/javase/downloads/widget/jdk6.jsp>. Acesso em: 02/07/2010 A imagem acima mostra como disparar a execução do script diretamente de dentro do Eclipse. O resultado pode ser acompanhado pela aba “Console” do próprio Eclipse. O resultado da execução do script pode ser vista na próxima figura: FIGURA 21 - RESULTADO DA EXECUÇÃO DO ANT FONTE: Disponível em: <http://java.sun.com/javase/downloads/widget/jdk6.jsp>. Acesso em: 02/07/2010 Veja que ao final da execução é mostrada uma mensagem de sucesso “BUILD SUCCESSFUL” e o tempo total que a soma das operações levou. Além disso, na aba da esquerda deve aparecer um novo diretório chamado dist e dentro dele o arquivo .war gerado. 3.6 O EMPACOTAMENTO WAR O resultado do passo anterior, da geração do projeto no Eclipse, resultou num arquivo de extensão .war, mas o que viria a ser esse arquivo. A sigla remete à Web Archive, ou seja, um arquivo que trata de uma aplicação voltada para a Internet. O seu principal objeto é facilitar o transporte e instalação do sistema inteiro no servidor, pois é necessário mover apenas um arquivo que toda a aplicação será levada junto. Em relação ao formato do arquivo (que foge dos tradicionais formatos que encontramos dos sistemas operacionais), ele utiliza de algoritmos de compactação para criar um arquivo que ocupe pouco espaço em disco. Na prática, ele nada mais é que um arquivo .zip cuja extensão foi renomeada para .war para fins de padronização de nomenclatura. Para este material, sempre será considerada a instalação de um arquivo neste formato no servidor. 3.7 EXECUTANDO A APLICAÇÃO Uma vez que a aplicação foi instalada no servidor (o arquivo portalEducacao.war foi copiado para o diretório {TOMCAT_HOME}/webapps) a aplicação está pronta para ser iniciada. Isso é feito iniciando o servidor conforme explicado no tópico “Tomcat: iniciando”. O resultado é mostrado na tela a seguir: FIGURA 22 - RESULTADO DA DISPONIBILIZAÇÃO DE UMA APLICAÇÃO FONTE: Disponível em: <http://java.sun.com/javase/downloads/widget/jdk6.jsp>. Acesso em: 02/07/2010 A imagem em questão pode parecer a mesma que mostrada anteriormente, mas repare na linha indicada pela flecha vermelha. Nela aparece a indicação que a aplicação que instalamos no servidor foi corretamente disponibilizada (“INFO: Deploying web application archive portalEducacao.war”) e está pronta para ser utilizada. A aplicação em questão é web, então o modo natural de acessá-la é por meio de um navegador, como o Microsoft Internet Explorer ou o Mozilla Firefox, aliás, durante todo o restante do treinamento será utilizando como ferramenta de acesso algum navegador para disparar a requisição. Devemos então, de alguma forma, escrever uma URL que ao ser disparada chegue em nosso Servlet. Observe a figura abaixo: FIGURA 23 - URL QUE FAZ A INVOCAÇÃO DO SERVLET FONTE: Disponível em: <http://java.sun.com/javase/downloads/widget/jdk6.jsp>. Acesso em: 02/07/2010 No navegador foi digitado o endereço que desejamos requisitar. O protocolo usado será sempre o HTTP. Como estamos usando o Tomcat instalado em nossa própria máquina, podemos acessá-lo por intermédio do nome e porta padrão: localhost:8080. Até este ponto, nada de novo. O trecho a seguir que nos é importante. Ele é o chamado contexto da aplicação e é dado pelo nome do arquivo .war instalado, sem a sua extensão. Como em um mesmo servidor podem ser instalados diversos sistemas, é necessário conhecer o contexto para acessar uma aplicação específica. Depois do contexto vem a informação da URL que desejamos acessar dentro da aplicação avisada. Essa é a URL que deve estar mapeada no arquivo web.xml e que é o contato com o mundo externo. Uma vez que o servidor mapeie para uma aplicação válida e dentro dela encontre o texto corretamente mapeado, então o objeto Servlet a ele associado é invocado e o método correspondente disparado. Lembrando que foi invocado o método doGet() pois foi gerada uma requisição do tipo get (toda URL dispara uma requisição do deste tipo). FIGURA 24 - OBSERVANDO A MENSAGEM GRAVADA NO LOG DO TOMCAT FONTE: Disponível em: <http://java.sun.com/javase/downloads/widget/jdk6.jsp>. Acesso em: 02/07/2010 O resultado não é mostrado na tela, mas simplesmente no terminal aberto em que o Tomcat está rodando, conforme mostrado na figura acima, em que o texto definido no Servlet é mostrado. Eventuais erros ou exceções serão igualmente mostrados neste terminal, o que servirá principalmente para depurar a aplicação atrás de eventuais problemas ou erros de comportamento, que são infinitamente mais complexos de se encontrar que aqueles localizados em tempo de compilação, que basta corrigir o que o compilador identificou como erro para que o programa passe a funcionar corretamente e sem maiores problemas. 4 SERVLETS 4.1 HIERARQUIA DE ENTIDADES O objetivo dos próximos tópicos é aprofundar os conceitos por trás de toda a estrutura de classes e interfaces existentes na especificação para aplicações web no contexto da tecnologia Java. Em seguida, é mostrar maneiras de como usar essa estrutura na construção de aplicações práticas. Para começar, veja como as classes e pacotes estão estruturados: FIGURA 25 - ESTRUTURA DE CLASSES PARA O SERVLET Fonte: Arquivo pessoal do autor. Pelo diagrama de classes, vemos que no topo da hierarquia está a interface Servlet. Relembrando os conceitos de orientação a objetos e Java, uma interface pode ser definida como o estabelecimento de um contrato entre duas partes, pois de um lado está uma entidade que se compromete a implementar os métodos definidos na interface usando determinada assinatura e do outro estão as classes que a vão utilizar obrigadas a fazer as invocações de determinada forma. Não confundir o conceito de interface com o de interface gráfica, que são tópicos completamente diferentes, pois neste momento não estamos falando de telas que o usuário interage, mas de entidades que definem assinaturas de métodos que serão mais tarde implementados por classes que lhes darã o comportamento específico para cada situação. Nesta interface estão definidos três métodos (existem diversos outros, mas esses são os mais importantes agora e no futuro) que serão utilizados em todas as demais definições: init: Sempre que uma instância de um Servlet for criado, esse método será invocado, mas apenas na primeira vez, ficando o objeto que representa o Servlet armazenado para ser posteriormente utilizado em outras requisições. Toda inicialização deve ser colocada dentro dele e lembrando que ele será executado apenas uma vez. destroy: Executado também apenas uma vez, momentos antes que o objeto for coletado pelo coletor de lixo, pois não será mais utilizado. Pouco utilizado, mas pode ser de grande utilidade para liberar recursos que foram obtidos para a execução da funcionalidade. service: É o método responsável por tratar a requisição que chegar ao Servlet. Esse código será executado diversas vezes, sempre que uma nova requisição chegar. Essa funcionalidade já foi vista, mas com outro nome: doGet(), que é a maneira como classes-filhas concretas implementam este método. Repare que nenhum deles possui qualquer tipo de corpo, pois o código que irá dizer como eles funcionam fica a cargo das classes que vierem a programar essa interface. O item que vem abaixo é a classe GenericServlet, que é abstrata (portanto, não pode ser instanciada) e que implementa a maioriados métodos definidos na interface, oferecendo uma implementação ao mesmo tempo genérica e padrão. Como estamos interessados em tratar requisições do tipo HTTP, esta classe raramente será utilizada diretamente. Por fim, uma classe já vista anteriormente, a HttpServlet, que representa a implementação de um Servlet que trata requisições do tipo HTTP, que é onde todo o trabalho de desenvolvimento ficará. Foi ela que utilizamos como pai da classe que definimos acima e que merece maior destaque da nossa parte, que será dado no próximo tópico. 4.2 A CLASSE HTTPSERVLET A classe HttpServlet é abstrata (não pode criar objetos diretamente) e possui seus métodos codificados para tratar requisições do tipo HTTP, aquelas mesmas que são geradas nas requisições de páginas da Internet. Como ela é filha da classe GenericServlet (que por sua vez implementa a interface Servlet) todos os métodos que foram definidos anteriormente também estão presentes nela, eventualmente alterados para suportar situações específicas ao mundo HTTP. Nela já aparece o método service() sobrecarregado (mesmo nome, lista de parâmetros diferentes), pois além de receber como argumentos objetos do tipo ServletRequest e ServletResponse, ela passa a receber também objetos um pouco mais específicos, que tratam requisições do tipo HTTP. Mais que isso, é nesta classe que aparecem métodos específicos e separados para tratar cada tipo de requisição que pode chegar pela Internet, como GET ou POST. Em geral, deve-se invocar esses métodos que diretamente o service(), para se ter um controle mais preciso de como a requisição será tratada. Todas as classes do tipo Servlet que viermos a desenvolver deverão, obrigatoriamente, serem filhas desta classe, possuindo assim todos os métodos e suas respectivas implementações para a realidade de requisições HTTP. Partindo deste ponto, devemos em seguida pensar que tipo de requisição poderá chegar até ela, sendo as duas opções mais normais GET ou POST e a partir da resposta a esta pergunta sobrescrever o método doGet() ou o método doPost(). 4.3 UMA PALAVRA RÁPIDA SOBRE REQUISIÇÕES GET E POST Saber quando uma requisição que chega ao servidor é do tipo GET ou POST é fundamental para saber como ela será tratada e qual a melhor forma ou estratégia para isso. De forma resumida, as diferenças e utilizações entre uma e outra podem ser agrupadas assim: GET POST Disparada ao digitar uma URL no navegador, submissão de formulários com atributo method igual a get ou ao clicar em um link. Disparada ao submeter um formulário com atributo method igual a post. Possui limite reduzido de caracteres (cerca de 250 caracteres) que podem ser enviados. Possui um número maior de informações que podem ser enviadas, chegando próximo aos 4KB. Forma a chamada query string, na qual parâmetros de dados são enviados concatenados na própria URL. Todos os dados enviados estão armazenados dentro de campos de um formulário. Observe que são diferenças sutis, mas que podem resultar em uma página corretamente exibida ou em um erro de página não encontrada. Caso o tipo da requisição não seja importante e o tipo do tratamento seja o mesmo, pode-se buscar a codificar algo da seguinte forma: package br.com.pe.curso; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TesteGetPost extends HttpServlet { @Override protected void doGet( HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("Trata requisicao"); } @Override protected void doPost( HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } } Neste novo código foram definidos os dois métodos doGet() e doPost(), permitindo que este mesmo Servlet possa tratar tanto requisições do tipo GET quanto do tipo POST (repare que existe a notação @Override para obrigar o compilador a chegar nas classes pai se existem o método com a mesma assinatura que estamos usando, trocando apenas o seu comportamento). O destaque fica por conta de como as coisas estão sendo feitas, pois não desejamos ter comportamentos diferentes para requisições diferentes e nem manter códigos duplicados. A maneira encontrada seria colocar o código que será executado em um dos métodos e no outro fazer uma chamada para este que está implementando a funcionalidade, repassando todos os objetos necessários. Assim, imagine que chega até o servidor uma requisição do tipo POST que foi corretamente mapeada para o Servlet TesteGetPost. Ao acontecer isso, a requisição deverá ser tratada pelo método doPost(), só que tudo que esse método faz é repassar a chamada para o método doGet(), pois é nele que o comportamento foi devidamente feito e somente nele. 4.4 DEFININDO UMA QUERY STRING O assunto já foi introduzido, mas merece um pouco mais de destaque, por se tratar de um recurso muito utilizado na passagem de parâmetros entre diferentes partes de uma aplicação. Uma query string é uma forma de se concatenar, na própria URL que se está chamando, alguns valores para a área seguinte da aplicação, seja ela uma página ou Servlet (esse tipo de comportamento vale também para outras linguagens de programação). http://localhost:8080/portalEducacao/teste?id=20&nome=Marcelo O exemplo anterior mostra uma URL normal, utilizando o protocolo HTTP, referenciando um servidor em uma porta específica e acessando um contexto de aplicação chamado portalEducacao e mapeado para a URL /teste, da mesma forma que foi feito no exemplo do primeiro Servlet. Só que, além disso, foi também acrescentado o símbolo de interrogação, indicando que tudo que vier a partir daquele ponto deve ser entendido como variáveis que serão passadas para o destino. As informações que se seguem possuem o formato de chave e valor, separados pelo símbolo de igual. Cada um desses “pedaços” é ainda unido pelo símbolo &. Quando essa URL chegar ao destino dela, ela será quebrada, as chaves virarão nomes de variáveis e os valores o conteúdo que cada uma dessas variáveis deve assumir, dando maior liberdade à aplicação como um todo. 4.5 FORMULÁRIOS HTML, UMA REVISÃO Estamos prestes a entrar na parte que manuseia informações vindas da interface gráfica do usuário, que poderão ser exibidas na tela. Elas servem como parâmetro para algum cálculo ou devem ser salvas em uma tabela do banco de dados. Contudo, um item importante para se chegar a esse nível, mas que não está diretamente ligado à tecnologia dos Servlets é a construção dos formulários no que toca à parte gráfica, que fica a cargo do HTML, uma linguagem de marcação que serve para construir as páginas e que os navegadores são implementados para reconhecer e exibir os componentes de acordo com suas definições. Não é objetivo deste material se aprofundar na parte do HTML, que é extenso, ainda que simples, mas focar apenas em uma pequena revisão dos principais campos que serão usados para os exemplos. Caso apareça a necessidade de maiores explicações futuras, elas serão dadas no ponto em que forem apresentadas. Por conta disso, esse tópico será orientado em função do seguinte trecho de código: <html> <head> </head> <body> <form method="get" action="/portalEducacao/dados"> Código: <input type="text" name="codigo" /><br /> Valor: <input type="text" name="valor" /><br /> <input type="submit" name="sub" /><br /> </form> </body> </html> Nele está definido um documento simples que possui um formulário, que em HTML são sempre determinados usando a tag <form>. Dentro dele existem dois atributosque são importantes, o método de envio, determinado pelo atributo method e o destino da requisição, ou seja, qual a estrutura (ou Servlet) na aplicação que irá tratar o envio do formulário quando este for realizado, sendo que isso é informado pelo atributo action. Como a maioria das tags do HTML, existe um </form> correspondente indicando onde a definição daquele componente deve terminar. Repare que o conteúdo da propriedade action faz referência a um recurso dentro da própria aplicação, daí o nome /portalEducacao e depois para um caminho mapeado dentro do arquivo web.xml chamado /dados, que quando a requisição for disparada será tratado por um Servlet que está preparado para tratar qualquer requisição que seja mandado para este caminho. Dentro das tags <form> aparecem os campos que deverão ser enviados no momento da submissão e essa localização é importante, pois apenas os campos que estiverem definidos entre as marcas serão enviados. As primeiras estruturas definem dois campos simples, para inserção de dados textuais por parte do usuário e sempre será definido utilizando a tag <input>, com o tipo definido como text. Outro tipo de campo <input>, mas que possui um tipo diferente é o submit, que define na tela um botão que tem um comportamento especial: uma vez apertado junta todos os dados preenchidos pelo usuário na tela e os envia para o recurso definido pelo atributo action. O fluxo de controle deixou de estar na página e passou a estar no servidor, sendo que este é quem vai decidir onde o resultado da submissão deverá aparecer. Esse código definido acima pode ser copiado e colado em um arquivo chamado teste.jsp e colocado dentro do diretório jsp (ainda que o diretório tenha esse nome, não é obrigatório que apenas arquivos com extensão .jsp sejam colocados ali dentro). O resultado da exibição deve ser aberto num navegador e teria como resultado algo como: FIGURA 26 - RESULTADO DO FORMULÁRIO SIMPLES MONTADO ACIMA FONTE: Disponível em: <http://java.sun.com/javase/downloads/widget/jdk6.jsp>. Acesso em: 02/07/2010 Para o momento, conhecer esses dois campos, junto com a definição de um formulário, é suficiente para os nossos propósitos, pois nos permitirá enviar dados para o servidor e verificar como eles podem ser tratados por um Servlet. 4.6 REQUISIÇÕES E RESPOSTAS Os dois parâmetros de entrada dos métodos de serviço doGet() e doPost() representam a requisição de entrada e outro representando a resposta dada à esta requisição. Olhando para a estrutura das entidades, verifica-se que ambas são interfaces, ficando a cargo de cada servidor de aplicação a forma que os objetos serão implementados, mas como ambos seguem o contrato estabelecido pelas interfaces, os métodos continuam sendo os mesmos. Todos os cabeçalhos e informações empacotadas e enviadas para o servidor ficam localizadas no objeto HttpServletRequest, que indica a entrada dos dados. O objetivo de objetos do tipo HttpServletResponse é formatar a saída, seja ela textual usando HTML ou outro formato como um arquivo para posterior download por parte do usuário. 4.7 RECUPERANDO INFORMAÇÕES PASSADAS COMO PARÂMETRO O seguinte exemplo mostra de que forma recuperar os dados preenchidos em um formulário e submetido para um Servlet previamente configurado para tratar a requisição: package br.com.pe.curso; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Dados extends HttpServlet { @Override protected void doGet( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String cod = req.getParameter("codigo"); String val = req.getParameter("valor"); System.out.println(cod + " / " + val); } } Repare que existe um método que recupera o valor preenchido pelo usuário no campo baseado no nome dado ao campo no formulário: getParameter(“nome_campo”). Verifique também que os dados retornados são sempre do tipo String e que qualquer conversão fica por conta do próprio desenvolvedor ao saber que aquela informação pode ser convertida para número ou data/hora, por exemplo. Para facilitar esse procedimento existe um método chamado getParameterNames() que retorna um Enumeration com todas as chaves dos campos definidos no formulário, ocultos ou não. Interando-se sobre essa coleção de chaves, pode-se recuperar todos os campos definidos no formulário e montar objetos Java para serem utilizados em outras partes do sistema. Neste ponto, o objeto de resposta acaba não tendo muita utilidade, pois a impressão do conteúdo dos campos do formulário são apenas impressos na saída padrão (ou seja, são escritos no terminal onde o Tomcat iniciou), mas ele será de fundamental importância para a exibição de resultado na tela do usuário, como saída para uma página HTML. 4.8 ESCREVENDO CONTEÚDO NA SAÍDA PADRÃO O objeto HttpServletResponse representa o resultado da requisição por parte do usuário, possuindo assim um caminho para se escrever informações e estas aparecerem na página de resultado do usuário. Assim, existe o método getWriter() que retorna um objeto que escreve texto na saída padrão, que na prática é o que o usuário irá enxergar. Em exemplos, teríamos algo como o trecho a seguir: package br.com.pe.curso; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Dados extends HttpServlet { @Override protected void doGet( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getWriter(); out.print("oi"); } } O método getWriter() retorna uma referência para um objeto do tipo PrintWriter, que possui uma série de métodos que servem para escrever conteúdo que será impresso na tela do usuário. É por meio do método print() executado no objeto out que todo o HTML de resultado será exibido na tela. Um exemplo interessante juntando-se os dois exemplos vistos, de recuperar as informações do formulário e escrever HTML na saída, resultaria no seguinte trecho de código: package br.com.pe.curso; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Dados extends HttpServlet { @SuppressWarnings("unchecked") @Override protected void doGet( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getWriter(); Enumeration<String> valores = req.getParameterNames(); while (valores.hasMoreElements()) { String chave = valores.nextElement(); String valor = req.getParameter(chave); out.print(chave + "=" + valor + "<br />"); } } } Para o método em Java, todo o código HTML escrito tem significado apenas de Strings, cadeias de caracteres, sem nenhuma relação lógica com uma página da Internet, que só atingirá esse objetivo no momento em que for executado dentro de um navegador. Por outro lado, toda variável do Java pode ser inserida dentro do HTML de resultado, dando o sentido dinâmico da página, pois temos acesso a essas variáveis no momento em que a página está sendo construída (repare no uso da tag de quebra de linha usada para pular linhas entre os valores preenchidos). De possedestes recursos podemos escrever páginas de resultado com qualquer nível de complexidade, mas com poucos exemplos já será possível observar algumas dificuldades de se fazer isso de dentro dos Servlets, pois a escrita do código HTML como cadeias de caracteres no mínimo torna o código difícil de ler e em consequência, de dar manutenção. Tendo esse pano de fundo, as páginas JSP terão um papel muito importante. 4.9 ARMAZENANDO OBJETOS NA REQUISIÇÃO Em geral, uma aplicação depois de fazer algum processamento precisa exibir na interface gráfica o resultado deste processamento para notificar o usuário ou atualizar uma informação em um relatório. Isso se dá incluindo informações na requisição que será redirecionada para exibição no navegador do usuário. Na especificação dos Servlets isso se dá por intermédio da interface HttpServletRequest, que oferece métodos para inclusão e acesso das variáveis desejadas. São os métodos setAttribute() e getAttribute() (não confundir com o método getParameter()visto anteriormente). Veja como seria um exemplo: package br.com.pe.curso; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ExemploAtributos extends HttpServlet { @Override protected void doGet( HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { List<String> elementos = new ArrayList<String>(); elementos.add("laranja"); elementos.add("banana"); elementos.add("uva"); req.setAttribute("selecao_frutas", elementos); // algum outro tipo de processamento... Object o = req.getAttribute("selecao_frutas"); System.out.println(o); } } No exemplo, foi criada uma lista de objetos do tipo String. Em seguida, essa lista foi colocada no objeto que representa a requisição por meio do método setAttribute(), só que além disso ele foi nomeado com uma chave para poder ser posteriormente recuperado. Por sua vez, o método getAttribute() recebe como parâmetro uma chave do tipo String que tenta encontrar algum objeto que case com aquele nome, retornando-o caso o encontre. Vale destacar que esse retorno é do tipo Object, sendo necessário fazer uma conversão explícita para transformar esse objeto retornado em algo que possa ser mais facilmente manipulado, como a lista original. Isso acontece para dar uma maior flexibilidade ao método, podendo ser colocada qualquer informação, independente do tipo, pagando o preço no momento da recuperação, em que se deve saber para qual tipo a nova conversão deve ser realizada. Essa informação pode ser recuperada posteriormente dentro de outro Servlet ou mesmo dentro de um JSP (ponto que será visto posteriormente). 4.10 CONFIGURANDO INFORMAÇÕES INICIAIS Dentro do descritor web.xml podem ser passadas informações de inicialização para o Servlet ou para a aplicação inteira, ou seja, que estarão visíveis para todas as entidades do sistema por meio do contexto da aplicação. Essas informações são úteis para inicializar pontos diversos da aplicação, como uma conexão com o banco de dados ou sistema de logs ou então para carregar arquivos de configurações que devem ser usados em toda a aplicação (o uso do framework Struts necessita deste tipo de configuração). Essas informações devem ser colocadas em tags opcionais diretamente no arquivo web.xml. Veja os exemplos abaixo: <context-param> <param-name>x</param-name> <param-value>1</param-value> </context-param> <servlet> <servlet-name>Primeiro</servlet-name> <servlet-class>br.com.pe.curso.PrimeiroServlet</servlet-class> <init-param> <param-name>inicio</param-name> <param-value>2</param-value> </init-param> </servlet> O primeiro bloco vai direto ao corpo do arquivo web.xml, indicando que a informação estará disponível para todos os pontos da aplicação. Já o segundo, está amarrado obrigatoriamente a um Servlet, vindo sua definição dentro do corpo da Servlet. Em ambos os casos, ainda que com nomes diferentes, são definidas tags para determinar um nome de variável para posteriormente ser possível resgatá-la e o valor propriamente dito. Uma vez que a aplicação tenha sido disponibilizada, os valores estão prontos para serem usados. Veja um exemplo de como utilizá-las: package br.com.pe.curso; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PrimeiroServlet extends HttpServlet { @Override protected void doPost( HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext ctx = getServletContext(); String valor = ctx.getInitParameter("x"); System.out.println(valor); String vlrInicial = getInitParameter("inicio"); System.out.println(vlrInicial); } } No primeiro exemplo, recupera-se o contexto do Servlet por meio do método herdado da classe HttpServlet e em seguida invoca-se o método getInitParameter() passando o nome da variável que se deseja recuperar. O retorno é sempre um objeto do tipo String, pois é o único tipo de informação que pode ser colocado no arquivo web.xml. No segundo exemplo, usa-se também um método herdado da classe HttpServlet que recupera o valor definido como inicial para o Servlet em especial, associado ao nome passado como argumento. Ele igualmente retorna uma informação do tipo String. No primeiro exemplo, todo e qualquer Servlet que fizer uma invocação daquela forma, passando o mesmo nome de variável, deve recuperar o mesmo valor da informação. No segundo caso, apenas os Servlets que tiveram aquela variável definida no seu corpo. Caso busque-se uma informação não definida, será retornado o valor null para a invocação. 5 A TECNOLOGIA JSP O complemento perfeito para a tecnologia de Servlets é a chamada tecnologia JSP (Java Server Pages) que permite criar páginas de conteúdo dinâmico, voltado para interfaces, com as facilidades da escrita de uma página HTML (lembrando que escrever marcações HTML nos Servlets pode ser uma tarefa tediosa, pois é basicamente manipular cadeias de caracteres). Essa parte da especificação é a que mais se aproxima de outras tecnologias que se propõe a inserir lógica de programação na camada de interface gráfica do usuário, oferecendo conteúdo dinâmico e que varia de acordo com estados e características dos dados do usuário. O aspecto negativo desta abordagem é que caso ela não seja utilizada com consciência pode-se chegar a um arquivo muito complexo para se dar manutenção ou mesmo realizar alterações. Além disso, deve-se evitar colocar regras de negócio ou acesso a outras partes administrativas do sistema, como acesso ao banco de dados ou a objetos que realizam operações de lógica (ainda que seja possível), preferindo sempre repassar esse tipo de operação aos Servlets que irão por sua vez repassar para as camadas de negócio da aplicação. A propósito, esse é um aspecto importante e muito utilizado em diversas linguagens de programação, incluindo Java: divisão em camadas, cada uma tratando de um aspecto da aplicação e sem interferir com as demais (alguns pontos disso serão vistos ao final). Por conta de tudo isso, arquivos JSPs são responsáveis pela interface gráfica e somente isso. 5.1 CRIANDO UM ARQUIVO JSP Todo arquivo JSP deve ser colocado dentro do arquivo que representa a aplicação (seja ele compactado
Compartilhar