Java Web Ricardo Terra rterrabh [at] gmail.com Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 1 CV Nome: Ricardo Terra Email: rterrabh [at] gmail.com www: ricardoterra.com.br Twitter: rterrabh Lattes: lattes.cnpq.br/ 0162081093970868 Ph.D. (UFMG/UWaterloo), Post-Ph.D. (INRIA/Université Lille 1) Background Acadêmico: UFLA (desde 2014), UFSJ (1 ano), FUMEC (3 anos), UNIPAC (1 ano), FAMINAS (3 anos) Profissional: DBA Eng. (1 ano), Synos (2 anos), Stefanini (1 ano) Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 2 Por que utilizar Servlets e JSP? n Muitos têm adotado esta estratégia de desenvolvimento (estão na moda) n Existem diversas aplicações GUI que são utilizadas por milhões de pessoas, porém essas aplicações possuem diversos problemas de distribuição q Em uma aplicação web, você não precisará se prender aos problemas de distribuição, pois sua aplicação funcionará em qualquer computador que possua um browser, independente do S.O., memória, processador, etc Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 3 Por que utilizar Servlets e JSP? n Nesta disciplina, vamos substituir as aplicações GUI por aplicações Web n Uma aplicação web é composta de tecnologia: q q No lado do cliente: HTML, XML, CSS, JS, etc No lado do servidor: CGI, ASP, PHP, servlets, etc Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 4 Cliente e Servidor / HTTP e HTML n Quando um servidor responde a uma solicitação, ele geralmente envia algum tipo de conteúdo para o browser, para que esse possa exibí-lo q O formato HTML é o formato mais comum enviado como resposta para um cliente pelo Servidor, pois esse é facilmente lido pelo browser no cliente Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 5 Cliente e Servidor / HTTP e HTML n A maioria das conversas que ocorre na web entre clientes e servidores são mantidas através do protocolo HTTP, que possibilita conversas de requisição e resposta n O cliente envia uma requisição HTTP e o servidor retorna uma resposta HTTP q n Enfim, se você é um servidor web você fala HTTP Portanto, uma conversação HTTP é uma sequência de requisição/ resposta q Isto é, o cliente pede uma coisa, o servidor responde, o cliente pede outra coisa, o servidor responde... Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 6 Cliente e Servidor / HTTP e HTML n Requisição e resposta: Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 7 Cliente e Servidor / HTTP e HTML n O HTTP roda no topo da arquitetura TCP/IP n O HTTP é um protocolo da camada de aplicação que tem características específicas para a web, mas ele depende de toda a arquitetura TCP/IP para garantir que tanto a solicitação e quanto a resposta sejam transmitidas entre o cliente e o servidor Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 8 Cliente e Servidor / HTTP e HTML n HTTP na camada de aplicação da arquitetura TCP/IP Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 9 Requisição e resposta n Principais elementos do fluxo de requisição: q q q n método HTTP endereço da página (URL) que está sendo acessada parâmetros do formulário Principais elementos do fluxo de resposta: q cabeçalho n n n q código de status Método HTTP tipo do conteúdo (texto, imagem, HTML...) conteúdo (o texto, a imagem, o HTML...) Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 10 Requisição e resposta n Requisição HTTP q A primeira coisa que você encontrará é o nome do método HTTP n q O nome do método informa ao servidor o tipo de solicitação que está sendo feita e como o resto da mensagem será formatada. O protocolo HTTP possui diversos métodos, mas usaremos e aprenderemos os mais comuns: GET e POST Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 11 Requisição e resposta n Método GET q É o método mais simples do HTTP e seu principal trabalho é pedir um recurso n q q Pode ser qualquer tipo de recurso: uma página, uma imagem, um PDF, etc O caminho até o recurso e quaisquer parâmetros adicionados à URL serão incluídos na própria barra de endereços Podemos usar o GET para formulários, porém com desvantagens: n n O total de caracteres do GET é limitado Os dados que você envia utilizando HTTP GET são anexados à URL, portanto, seja o que for que você estiver transmitindo, ficará exposto Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 12 Requisição e resposta n Método POST q q É um método mais poderoso. É um GET++. Com o POST, você pode solicitar algo e, ao mesmo tempo, enviar os dados de um formulário para o servidor Os dados a serem enviados ao servidor estão localizados na carga útil (payload) da mensagem e podem ser bem extensos Pacote IPv4 q Por isto, o POST é considerado mais seguro que o GET Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 13 Requisição e resposta n Enfim, para acesso a recursos utiliza-se GET e aplicações que utilizam formulários utiliza-se POST Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 14 Requisição e resposta n Resposta HTTP q uma resposta HTTP é composta de um cabeçalho (header) e o corpo n n q o cabeçalho informa ao browser o método que está sendo utilizado, se a solicitação obteve êxito (código) e o tipo de conteúdo está incluído no corpo corpo possui o conteúdo (por exemplo, HTML) que o browser exibirá o código pode ser: n n n n n 1xx: Informativa: requisição recebida, processo em continuidade… 2xx: Sucesso: a ação foi recebida, entendida e aceita com sucesso 3xx: Redirecionamento: ação futura ainda deve ser tomada para completar a requisição 4xx: Erro no cliente: requisição contém sintaxe incorreta ou não pode ser resolvida 5xx: Erro no servidor: O servidor falhou ao responder uma aparente requisição válida Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 15 Páginas estáticas x Páginas dinâmicas n Servidores "amam" servir páginas estáticas q n Uma página estática é apenas um HTML que está armazenado no servidor. Quando o usuário pede a página, o servidor simplesmente busca a página e a envia do mesmo modo que está lá. Não processa ou dispende recursos para entregá-la ao cliente Porém, às vezes você precisa mais do que uma página estática q q Se você precisa de páginas dinâmicas (páginas criadas no momento da requisição, isto é, não existiam antes da solicitação) e da capacidade de escrever/salvar dados no servidor (seja em arquivos ou em SGBDs), você precisa de uma aplicação rodando no servidor Para isso, começaremos a ver aplicações web usando Java EE Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 16 Primeiro Projeto Web n Para entendermos melhor como criar uma aplicação web, observe o material "Primeiro Projeto Web" que demostra como criar uma aplicação web completa n Algumas considerações: q O principal arquivo de uma aplicação web é o Deployment Descriptor (DD) n Deployment Descriptor (descritor de implantação) é um documento XML único por aplicação chamado web.xml que fica abaixo do diretório WEB-INF e que contém as informações de como sua aplicação deve ser implantada q O Tomcat geralmente utiliza a porta 8080 para executar as aplicações n Geralmente, quando a aplicação entra em produção é executada na porta 80, que é a porta do protocolo HTTP (o protocolo da Internet) Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 17 Métodos Importantes Web n Uma aplicação web é basicamente um servlet q n Os métodos importantes de um servlet são: q q n Um servlet é uma classe que estende HttpServlet doGet à responsável por tratar requisições GET doPost à responsável por tratar requisições POST Quando criamos pelo wizard do Eclipse, a aplicação já é registrada automaticamente no DD Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 18 Métodos Importantes Web n Primeiramente devemos setar o tipo de conteúdo da resposta: q n Para escrever no cliente devemos escrever na resposta: q n PrintWriter out = response.getWriter(); Geralmente escrevemos todo o HTML: q n response.setContentType("text/html"); out.print("<html><body>"); out.print("Agora: " + new Date()); out.print("</body></html>"); Mas sempre fechamos após escrever: q out.close(); Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 19 Métodos Importantes Web n Existem alguns métodos que são indispensáveis para o desenvolvimento de servlets, pois são aqueles que manipulam os parâmetros enviados por uma requisição: q public String getParameter(String nomeParam) n Retorna o valor string de um parâmetro específico q q Exemplo: § Pegando um nome, uma idade, um peso, uma profissão, uma cidade... public String[] getParameterValues(String nomeParam) n Retorna o vetor de string de um parâmetro específico q Exemplo: § Pegando nomes de um time de futebol, notas de uma turma... Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 20 Métodos Importantes Web n A utilização trivial seria, logo após setar o tipo do conteúdo da resposta, pegar todos os parâmetros da requisição e colocá-los dentro de variáveis locais. Por exemplo: q String nome = request.getParameter("nome"); int idade = Integer.parseInt( request.getParameter("idade")); String nomes[] = request.getParameterValues("nomes"); String numeros[] = request.getParameterValues("n"); Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 21 Uma metodologia simples 1. Setar o tipo de conteúdo da resposta (setContentType) 2. Colocar os parâmetros em variáveis locais (veja slide anterior) 3. Obter a escrita na resposta (out 4. Utilizar Java SE para gerar o HTML de resposta (out.print(...)) 5. Fechar a escrita na resposta (out.close()) Ricardo Terra (rterrabh [at] gmail.com) = response.getWriter()) Java Web Outubro, 2008 22 Exemplo 01 – Exibir nome n Vamos submeter a seguinte URL, isso seria via o método GET: q /ExibirNome?nome=Carlos n Para iniciarmos a passagem de parâmetros, é inserido um ? e depois os parâmetros são separados por &. n Ou talvez submeter via formulário, usando o método POST: <form action="${pageContext.request.contextPath}/ExibirNome" method="POST"> Nome: <input type="text" name="nome" /> <br /> <input type="submit" value="Enviar" /> <input type="reset" value="Limpar" /> </form> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 23 Exemplo 01 – Exibir nome n Como seria o código interno do método doGet (caso seja via URL) ou do método doPost (caso seja via formulário)? public [doPost|doGet](...) throws ... { response.setContentType("text/html"); String nome = request.getParameter("nome"); PrintWriter out = response.getWriter(); ... out.printf("Olá %s! Seja bem vindo!", nome); ... out.close(); } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 24 Exemplo 02 – Somar n Vamos submeter a seguinte URL, isso seria via o método GET: q /Somar?x=3&y=7 n Para iniciarmos a passagem de parâmetros, é inserido um ? e depois os parâmetros são separados por &. n Ou talvez submeter via formulário, usando o método POST: <form action="${pageContext.request.contextPath}/Somar" method="POST"> X: <input type="text" name="x" size="6" /> <br /> Y: <input type="text" name="y" size="6" /> <br /> <input type="submit" name="evento" value="Enviar" /> <input type="reset" value="Limpar" /> </form> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 25 Exemplo 02 – Somar n Como seria o código interno do método doGet (caso seja via URL) ou do método doPost (caso seja via formulário)? public [doPost|doGet](...) throws ... { response.setContentType("text/html"); int x = Integer.parseInt(request.getParameter("x")); int y = Integer.parseInt(request.getParameter("y")); PrintWriter out = response.getWriter(); ... out.printf("%d + %d = %d", x, y, (x+y)); ... out.close(); } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 26 Exemplo 03a – Somar vários n Um único parâmetro pode receber diversos valores n Vamos submeter a seguinte URL, isso seria via o método GET: q q n /SomarVarios?n=3.2&n=7.1&n=3.7&n=2.7&n=5.1&n=4.7 A requisição acima envia vários valores no parâmetro n e o Servlet deve ser capaz de recuperar todos eles usando não mais o método getParameter(), mas sim, getParameterValues() Recordando: q o método getParameter() retorna uma string n q usado para recuperar parâmetros simples com apenas um valor o método getParameterValues() retornar um vetor de string n usado para recuperar parâmetros com múltiplos valores Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 27 Exemplo 03a – Somar vários n Ou talvez submeter via formulário, usando o método POST: <form action="${pageContext.request.contextPath}/SomarVarios" method="POST"> Números:<br /> <input type="text" name="n" size="6" />, <input type="text" name="n" size="6" />, <input type="text" name="n" size="6" />, <input type="text" name="n" size="6" />, <input type="text" name="n" size="6" />, <input type="text" name="n" size="6" /> <br /> <input type="submit" name="evento" value="Enviar" /> <input type="reset" value="Limpar" /> </form> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 28 Exemplo 03a – Somar vários n Como seria o código interno do método doGet (caso seja via URL) ou do método doPost (caso seja via formulário)? public [doPost|doGet](...) throws ... { ... String[] strNumeros = request.getParameterValues("n"); double soma = 0; for (String s : strNumeros){ soma += Double.parseDouble(s); } ... out.printf("SOMA: %f, soma); ... } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 29 Exemplo 03b – Exibir maior/menor n Com base na idéia da URL ou do formulário do Exemplo 3a é possível fazer a exibição do maior e do menor número. Observe: public [doPost|doGet](...) throws ... { ... String[] strNumeros = request.getParameterValues("n"); double min, max; min = max = Double.parseDouble(strNumeros[0]); for (int i = 1; i < strNumeros.length; i++) { double n = Double.parseDouble(strNumeros[i]); if (n > max) { max = n; } else if (n < min) { min = n; } } ... out.printf("O menor valor é %f e o maior valor é %f", min, max); ... } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 30 Exemplo 03c – Exibir maior/menor n Uma observação bem importante é que o botão de submissão do formulário também pode passar um parâmetro (como o evento a ser realizado) e pode ser utilizado para indicar o que deve ser realizado com os outros parâmetros passados n Por exemplo, vamos alterar o exemplo 03b para ter dois botões de submissão: n n Exibir Maior Exibir Menor Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 31 Exemplo 03c – Exibir maior/menor n Formulário do Exemplo 03a com alterações destacadas q q o action do formulário os botões de submissão <form action="${pageContext.request.contextPath}/ExibirMM" method="POST"> ... <input type="submit" name="evento" value="Exibir Maior" /> <input type="submit" name="evento" value="Exibir Menor" /> ... </form> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 32 Exemplo 03c – Exibir maior/menor n Como ficaria o Servlet: public [doPost|doGet](...) throws ... { ... String[] strNumeros = request.getParameterValues("n"); String evento = request.getParameter("evento"); if (evento.equals("Exibir Maior")){ this.exibirMaior(strNumeros,out); //Chama um método local }else if (evento.equals("Exibir Menor")){ this.exibirMenor(strNumeros,out); //Chama um método local } ... } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 33 Exemplo 03c – Exibir maior/menor n E assim ficariam os métodos exibirMaior e exibirMenor private void exibirMenor(String[] strNumeros, PrintWriter out) { double min = Double.parseDouble(strNumeros[0]); for (int i=1; i<strNumeros.length; i++){ double n = Double.parseDouble(strNumeros[i]); if (n < min){ min = n; } } out.printf("O menor elemento é %f", min); } private void exibirMaior(String[] strNumeros, PrintWriter out) { double max = Double.parseDouble(strNumeros[0]); for (int i=1; i<strNumeros.length; i++){ double n = Double.parseDouble(strNumeros[i]); if (n > max){ max = n; } } out.printf("O maior elemento é %f", max); } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 34 Exemplo 03c – Exibir maior/menor n Como se pôde observar, dependendo do botão de submissão do formulário acionado, a ação realizada será diferente n Isto é bem utilizado quando tivermos um único servlet e várias ações a serem realizadas n Por exemplo, uma tela que salva, atualiza, exclui e lista os funcionários será vinculada a um mesmo servlet e dependendo do botão de submissão acionado direcionará a ação desejada Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 35 Só Servlets? n Até agora estamos desenvolvendo aplicações somente utilizando servlets n Qual o maior problema ou dificuldade encontrada em se desenvolver um servlet? q Escrever todo o código HTML no próprio servlet n Imagina ainda se fosse um servlet cuja resposta seria uma enorme página HTML? n Como resolver esse problema? Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 36 Utilizando JSP n A solução para não ficar escrevendo todo o código HTML dentro do servlet é utilizar páginas JSP (Java Server Pages) n Muitos utilizam o servlet para fazer a lógica de negócio (query no banco de dados, inserir um registro, registrar um empréstimo) e, então, encaminham a solicitação para um JSP que apresentará o HTML de resposta n Trabalhando da maneira acima, observa-se uma separação entre a lógica de negócio que está sendo realizada pelos servlets e a apresentação que está sendo realizada pelas páginas JSP q Isso pode parecer o MVC, mas ainda não é Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 37 Utilizando JSP n Uma página JSP é muito mais ágil para a geração de um documento HTML como saída do que um servlet q n Podemos pensar em uma página JSP como um documento HTML com algumas tags especiais Porém, na verdade, uma página JSP é um servlet q É interpretada em seu primeiro acesso é traduzida em um servlet Carregado pelo container Traduzido hello.jsp Compilado hello_jsp.java Ricardo Terra (rterrabh [at] gmail.com) Servlet hello_jsp.class Java Web Outubro, 2008 38 Utilizando JSP n Uma página JSP facilita o desenvolvimento da camada de apresentação uma vez que permite que os templates em HTML possam ser reaproveitados pelo desenvolvedor n Já que é uma página JSP é um servlet e já que um servlet é uma classe Java, então uma página JSP pode conter códigos Java n Uma página JSP é composta basicamente por elementos HTML e tags que delimitam códigos Java (chamados scripts) Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 39 Utilizando JSP n São as tags JSP: q q q q <%@ %> Diretiva JSP: define parâmetros para o container (no caso para o Tomcat <% %> Scriptlet: tudo o que tiver dentro desta região é considerado código Java. Uso não recomendado, preferir EL ou JSTL <%! %> Declaração: utilizada para definir métodos e declarar variáveis. Uso não recomendado, preferir EL ou JSTL Expressão: o mesmo que chamar <% out.print(…) %>. Não tem ponto-e-vírgula (;) no final. Uso não recomendado, preferir EL ou JSTL <%= %> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 40 Tags JSP – Exemplo 01 n O exemplo abaixo utiliza diretiva JSP para passar diversas informações sobre aquela página, faz declaração de um vetor de strings com diversos nomes, faz um scriplet para iterar o vetor e utiliza expressão para exibir os nomes em caixa alta: <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> <%!String[] nomes = {"Adriana","Carlos","Evandro","Gabriel", "Marcos"};%> <html> <body> <ul> <%for(String nome : nomes){%> Resultado: <li><%=nome.toUpperCase()%></li> <%}%> </ul> </body> </html> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 41 Tags JSP – Exemplo 02 n O exemplo abaixo faz a declaração de uma função, faz um scriplet para buscar o valor de um parâmetro da requisição e depois invoca a função declarada passando o parâmetro: q Neste exemplo foi realizada a chamada ao JSP passando o parâmetro diretamente via GET: /calcularPagamento.jsp?valor=1000.00 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> <%! Resultado: double incluiTaxas(double valor){ return valor*1.1; } %> <html> <body> <%double valor = Double.parseDouble(request.getParameter("valor"));%> O valor do pagamento é <%=this.incluiTaxas(valor)%> </body> </html> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 42 Encaminhar ou redirecionar n Como já vimos que o JSP será responsável pela apresentação, devemos saber como encaminhar uma requisição ou redicionar um cliente n Portanto: q Você pode encaminhar (forward) a requisição para ser completada n q Um exemplo é depois de realizar todos os processamentos no servlet devemos encaminhar a requisição à uma página JSP para que ela apresente os dados dessa requisição Você pode redirecionar a requisição para outro lugar n Um exemplo é quando a requisição está sem autenticação e você não quer tratá-la, mas sim, redirecionar o usuário para tela de login do sistema Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 43 Encaminhar (forward) n Ao encaminhar, o controle permanece dentro do container. n Um servlet envia a requisição para o próximo servlet ou JSP e os objetos HttpServletRequest e HttpServletResponse são encaminhados juntamente n Para o usuário, ele não conhece os servlets pelo qual ele foi encaminhado, e sim, somente o que ele acessou q n A URL do navegador não é alterada Encaminhamentos (forwardings) podem ocorrer apenas dentro do contexto web da aplicação, isto é, somente entre servlets e páginas JSP Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 44 Encaminhar (forward) Servlet ou JSP Servlet ou JSP Response public [doPost|doGet](...) throws ... { ... request.getRequestDispatcher("/resultListagem.jsp") .forward(request, response); ... } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 45 Redirecionar (redirect) n O servlet envia um código HTTP 303 como resposta informando uma nova URL deve ser acessada n Redirecionamento é usado quando precisa-se sair do contexto (acessar um recurso externo como o site do google, por exemplo) q Com redirect, perde-se todas as variáveis que existiam dentro do request, sendo necessário repassá-las à nova URL Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 46 Redirecionar (redirect) Servlet ou JSP Req u e st Red i re ct Request public [doPost|doGet](...) throws ... { ... response.sendRedirect("http://www.google.com.br"); return; } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 47 Exemplo encaminhamento n JSP com formulário de submissão (formSoma.jsp) <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> <html> <body> <font type="red">${requestScope.msgErro}</font> <br /> <form action="${pageContext.request.contextPath}/Somar" method="POST"> X: <input type="text" name="x" value="${param.x}" size="6"/> Y: <input type="text" name="y" value="${param.y}" size="6"/> <input type="submit" name="evento" value="Somar"/> <input type="reset" value="Limpar"/> </form> </body> </html> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 48 Exemplo encaminhamento n Servlet com a lógica de negócio protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int x = 0, y = 0; if (this.isNumber(request.getParameter("x"))) { x = Integer.valueOf(request.getParameter("x")); } else { request.setAttribute("msgErro", "O atributo X é inválido"); request.getRequestDispatcher("/formSoma.jsp").forward(request,response); return; } if (this.isNumber(request.getParameter("y"))) { y = Integer.valueOf(request.getParameter("y")); } else { request.setAttribute("msgErro", "O atributo Y é inválido"); request.getRequestDispatcher("/formSoma.jsp").forward(request,response); return; } request.setAttribute("z", x + y); // Encaminho para a JSP de resposta request.getRequestDispatcher("/resultSoma.jsp").forward(request,response); } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 49 Exemplo encaminhamento n Além do método doPost, a classe do servlet também terá o método isNumber que verificará se é uma certa string é um número inteiro: private boolean isNumber(String str) { return str.matches("^-{0,1}[0-9]+"); } n JSP com a resposta a ser apresentada (resultSoma.jsp) <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> <html> <body> O resultado da soma de ${param.x} + ${param.y} = ${requestScope.z} </body> </html> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 50 Escopos n No último exemplo vimos códigos como: q No servlet: n q Na JSP: n q n request.setAttribute(“z”,x+y) ${requestScope.z} Porém, não sabemos exatamente o que era. Isso trata-se da utilização de escopo para armazenamento de informações Os escopos são áreas de armazenamento com propriedades específicas e podem ser de: q q q q Página (pageScope) à somente existe em páginas JSP Requisição (requestScope) Sessão (sessionScope) Aplicação (applicationScope) Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 51 Escopo de página n Escopo de página (pageScope) q q Esse escopo é o mais curto e só existe durante a renderização da página JSP Colocando variáveis neste escopo (somente dentro da página JSP): n q <%pageContext.setAttribute("nomeAtributo",valor);%> Buscando o valor de uma variável nesse escopo: n Usando EL: q ${pageScope.nomeAtributo} n Usando expressão JSP (preferir EL): q <%=pageContext.getAttribute("nomeAtributo")%> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 52 Escopo de página Escopo de página pageScope Cliente 1 n JSP A Uso comum: q Uso de variáveis temporárias usadas somente para a renderização da página JSP Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 53 Escopo de requisição n Escopo de requisição (requestScope) q q Este escopo só existe durante a requisição, isto é, seu armazenamento inicia-se no momento em que uma requisição é realizada e termina junto com o término requisição Colocando variáveis neste escopo: n q request.setAttribute("nomeAtributo",valor); Buscando o valor de uma variável nesse escopo: n Usando EL: q ${requestScope.nomeAtributo} n Usando expressão JSP (preferir EL): q <%=request.getAttribute("nomeAtributo")%> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 54 Escopo de requisição Escopo de requisição requestScope get set Cliente 1 n Servlet/JSP B Servlet/JSP A Uso comum: q Passagem de informações adquiridas em um servlet para a página JSP de resposta Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 55 Escopo de sessão n Escopo de sessão (sessionScope) q q Este escopo é único por sessão (vínculo de um usuário utilizando a aplicação), isto é, o escopo existe enquanto a sessão do usuário estiver aberta Colocando variáveis neste escopo: n q request.getSession().setAttribute("nomeAtributo",valor); Buscando o valor de uma variável nesse escopo: n Usando EL: q ${sessionScope.nomeAtributo} n Usando expressão JSP (preferir EL): q <%=request.getSession().getAttribute("nomeAtributo")%> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 56 Escopo de sessão Escopo de sessão sessionScope set Servlet/JSP A set Cliente 1 Servlet/JSP B n Uso comum: q Armazenamento das informações do usuário. Por exemplo, nome, histórico de páginas visitadas, permissões de acesso, disciplinas do aluno... Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 57 Escopo de aplicação n Escopo de aplicação (applicationScope) q Este escopo é o mais abrangente. É o escopo comum às todos os servlets/JSP independente de qual página, requisição ou sessão. Pode-se realmente dizer que é o escopo da aplicação q Colocando variáveis neste escopo: q n q this.getServletContext().setAttribute("nomeAtributo",valor); Buscando o valor de uma variável nesse escopo: n Usando EL: q ${applicationScope.nomeAtributo} n Usando expressão JSP (preferir EL): q <%=application.getAttribute("nomeAtributo")%> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 58 Escopo de aplicação Escopo de aplicação applicationScope get Cliente 1 Servlet/JSP A get Cliente 2 n Servlet/JSP B Uso comum: q Armazenamento das informações que devem ser acessadas por qualquer requisição de qualquer usuário. Por exemplo, lista de UF, lista de cidades, lista do nome dos professores... Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 59 Escopos Observação: n Usando EL (Expression Language), você pode não dizer qual o escopo que está procurando o atributo, por exemplo: q n Caso seja feito assim, o container irá procurar o atributo com o nome x a partir do escopo mais restrito até o mais amplo: q 1. 2. 3. 4. q ${x} pageScope requestScope sessionScope applicationScope Por exemplo, se existir a variável x no escopo de requisição com o valor 4 e no escopo de aplicação com valor 6, será exibido 4, pois o escopo de requisição é mais restrito que o de aplicação Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 60 MVC n O modelo MVC oferece uma forma de separar as três camadas principais de uma aplicação web: q q q n Visão (responsável pela apresentação ao usuário) Controle (responsável por gerenciar os eventos que notificam o modelo) Modelo (responsável pelas entidades e regras de negócio) Para desenvolver uma aplicação Java Web no padrão arquitetural MVC (Model View Controller), basta utilizar: q q JSPs para o HTML (visão) Servlets para controlar o comportamento da aplicação (controle) n q Geralmente possuem o sufixo Servlet Classes específicas para realizar acesso a um SGBD (modelo) n Geralmente possuem o sufixo DAO (Data Access Object) Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 61 MVC Responsável pelo acesso ao SGBD Responsável pela apresentação da resposta Busca os dados conforme solicitação indireta da Visão e os entrega ao Controle Para exibir a resposta, acessa os diversos dados disponibilizados pelo Controle Responsável por interpretar a solicitação do usuário Manipula os parâmetros, faz o pedido de dados ao Modelo e, então, os coloca acessível à Visão Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 62 MVC Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 63 MVC n Algumas são as vantagens da utilização do MVC: q Independência entre a camada de Visão e a camada de Modelo n q O que permite a troca de um sem impacto ao outro Manutenibilidade n n n Ocorre um erro na apresentação dos dados, portanto é em uma JSP Ocorre um erro de fluxo ou comportamento, portanto é em um servlet Ocorre um erro ao acesso ao SGBD, portanto é em uma classe de modelo Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 64 Aplicação usando MVC n De acordo com o diagrama de classes explicando o MVC, vamos fazer uma pequena aplicação de exemplo usando o padrão arquitetural MVC q Só será implementada a função de inserção de funcionários Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 65 Aplicação usando MVC n Será composta de: q /web/menuFuncionario.jsp n q /web/inserirFuncionario.jsp n q Lógica de negócio com.terra.modelo.FuncionarioDAO n q Armazenará as informações do funcionário com.terra.controle.ManterFuncionarioServlet n q Formulário de inserção do funcionário com.terra.modelo.pojo.Funcionario n q Exibição das ações em funcionários Acesso ao modelo /web/resultInsercao.jsp n Resultado da inserção do funcionário Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 66 /web/menuFuncionario.jsp <html> <body> <h1>MENU</h1> <a href="${pageContext.request.contextPath}/inserirFuncionario.jsp"> Inserir </a> <br /> <a href="${pageContext.request.contextPath}/atualizarFuncionario.jsp"> Atualizar </a> <br /> <a href="${pageContext.request.contextPath}/excluirFuncionario.jsp"> Excluir </a> <br /> <a href="${pageContext.request.contextPath}/pesquisarFuncionario.jsp"> Pesquisar </a> <br /> </body> </html> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 67 /web/inserirFuncionario.jsp <html> <body> <h1>Inserir Funcionário</h1> <font color="red"><b>${requestScope.msgErro}</b></font><br /> <form action="${pageContext.request.contextPath}/ManterFuncionario" method="POST"> Nome: <input type="text" name="nome" size="60" maxlength="60" value="${param.nome}" /> <br /> Cargo: <input type="text" name="cargo" size="60" maxlength="60" value="${param.cargo}" /> <br /> <input type="submit" name="evento" value="Inserir" /> <input type="reset" value="Limpar" /> </form> </body> </html> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 68 com.terra.modelo.pojo.Funcionario public class Funcionario { private String nome; private String cargo; public Funcionario(){} public Funcionario(String nome, String cargo) { this.nome = nome; this.cargo = cargo; } public public public public String getNome(){ return this.nome; } void setNome(String nome){ this.nome = nome; } String getCargo(){ return this.cargo; } void setCargo(String cargo){ this.cargo = cargo; } } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 69 com.terra.controle.ManterFuncionarioServlet public class ManterFuncionarioServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String evento = request.getParameter("evento"); if (evento.equals("Inserir")){ this.inserir(request,response); }else if (evento.equals("Atualizar")){ this.atualizar(request,response); }else if (evento.equals("Excluir")){ this.excluir(request,response); }else if (evento.equals("Pesquisar")){ this.pesquisar(request,response); } } //Fim do doPost //Continua no próximo slide Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 70 com.terra.controle.ManterFuncionarioServlet private void inserir(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String nome = request.getParameter("nome"); String cargo = request.getParameter("cargo"); if (nome==null || nome.equals("")){ request.setAttribute("msgErro", "O campo 'nome' é obrigatório."); request.getRequestDispatcher("/inserirFuncionario.jsp").forward(request, response); return; }else if (cargo==null || cargo.equals("")){ request.setAttribute("msgErro", "O campo 'cargo' é obrigatório."); request.getRequestDispatcher("/inserirFuncionario.jsp").forward(request, response); return; } Funcionario f = new Funcionario(nome,cargo); FuncionarioDAO.insert(f); request.setAttribute("f", f); request.getRequestDispatcher("/resultInsercao.jsp").forward(request, response); } //Fim do inserir ... } //Fim da classe servlet Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 71 com.terra.modelo.FuncionarioDAO public class FuncionarioDAO { public static void insert(Funcionario f){ //Código de inserção do funcionário no SGBD } ... } Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 72 /web/resultInsercao.jsp <html> <body> <h1>Inserção de Funcionário</h1> O funcionário <b>${requestScope.f.nome}</b> foi inserido com sucesso no cargo de <b>${requestScope.f.cargo}</b>. <br /><br /> <a href="${pageContext.request.contextPath}/menuFuncionario.jsp"> Voltar ao menu </a> <br /> </body> </html> Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 73 Referência Bibliográfica n BASHAM, Brian; SIERRA, Kathy; BATES, Bert. Head First Servlets and JSP. Sebastopol: O'Reilly, 2008. n BASHAM, Brian; SIERRA, Kathy; BATES, Bert. Use a Cabeça. Servlets & JSP. Rio de Janeiro: Alta Books, 2005. Ricardo Terra (rterrabh [at] gmail.com) Java Web Outubro, 2008 74