Você está na página 1de 136

JavaServer Pages

Agenda
O que JSP; Suas vantagens e desvantagens; Escrever arquivos JSP com scriptlets; Usar Expression Language; O que so taglibs.

Java Server Pages (JSP)


Servlets Toda vez que voc precisa fazer uma mudana no HTML, o cdigo Java deve ser mudado, re-compilado e re-executado. Problemas na manuteno das nossas pginas. JSP foi introduzido para resolver este problema.
Um mecanismo de template onde a lgica baseada em Java pode ser incorporada em pginas HTML. Podemos escrever cdigo Java. Deteco e compilao automtica toda vez que a JSP mudada

Nas JSPs a pgina web est primeiro e o cdigo est no segundo lugar. Eles so usualmente compilados em um Servlets.

Exemplo de JSP

Elementos de scripting <%...%> ou scriptlet

Podemos usar variveis j implcitas no JSP: todo arquivo JSP j possui uma varivel chamada out (do tipo JspWriter) que permite imprimir para o response atravs do mtodo println: <% out.println(nome); %>. Funcionalidade semelhante ao out do Servlets mas sem precisarmos declar-lo antes. Vejamos um exemplo: Crie um arquivo WebContent/benvindo.jsp com:

<html> <body> <%-- comentrio em JSP aqui: nossa primeira pgina JSP --%> <% String mensagem = "Bem vindo ao sistema de agenda do FJ-21!"; %> <% out.println(mensagem); %><br /> <% String desenvolvido = "Desenvolvido por (SEU NOME AQUI)"; %> <%= desenvolvido %><br /> <% System.out.println("Tudo foi executado!"); %> </body> </html>

<html> <body> <%-- comentrio em JSP aqui: nossa primeira pgina JSP --%> <% String mensagem = "Bem vindo ao sistema de agenda do FJ-21!"; %> <% out.println(mensagem); %><br /> <% String desenvolvido = "Desenvolvido por (SEU NOME AQUI)"; Outra maneira %> de apresentar o <%= desenvolvido %><br /> contedo Vai para a <% console do System.out.println("Tudo foi executado!"); Tomcat. O Cdigo %> interpretado no </body> servidor. </html>

Listando os contatos com Scriptlet


J que podemos escrever qualquer cdigo Java no scriptlet, no fica difcil criar uma listagem de todos os contatos do BD.
<% ContatoDAO dao = new ContatoDAO(); List<Contato> contatos = dao.getLista(); for (Contato contato : contatos ) { %> <li><%=contato.getNome()%>, <%=contato.getEmail()%>: <%=contato.getEndereco()%></li> <% } %>

No cdigo acima ainda falta importar as classes dos pacotes corretos. Para isso, utilizamos diretiva com a seguinte:
<%@ page import="br.com.caelum.agenda.dao.ContatoDAO %>

Parece um scriptlet, mas com um @. Diretiva de pgina O atributo import permite que seja especificadoqual o pacote a ser importado. Este atributo pode aparecer vrias vezes.

Exerccios: Lista de contatos com scriptlet


1.

Crie o arquivo WebContent/lista-contatos-scriptlet.jsp:


Importe os pacotes necessrios:
<%@ page import="java.util.*, br.com.caelum.agenda.dao.*, br.com.caelum.agenda.modelo.*" %> <html> <body> <table> <% ContatoDAO dao = new ContatoDAO(); List<Contato> contatos = dao.getLista(); for (Contato contato : contatos ) { %> <tr> <td><%=contato.getNome() %></td> <td><%=contato.getEmail() %></td> <td><%=contato.getEndereco() %></td> <td><%=contato.getDataNascimento().getTime() %></td> </tr> <% } %> </table> </body>

</html>

2. 3. 4.

Teste a url http://localhost:8080/fj21-agenda/listacontatos-scriptlet.jsp Repare a data. Tente mostr-la formatada utilizando a classe SimpleDataFormat Coloque cabealhos para as colunas da tabela.

Definio da pgina padro de um site.


<welcome-file-list> <welcome-file>bemvindo.jsp</welcome-file> </welcome-file-list> Reinicie o tomcat e acesse a URL: http://localhost:8080/fj21-agenda/

2. 3. 4.

Teste a url http://localhost:8080/fj21-agenda/listacontatos-scriptlet.jsp Repare a data. Tente mostr-la formatada utilizando a classe SimpleDataFormat Coloque cabealhos para as colunas da web.xml diz Este arquivo tabela.
que os arquivos bemvindo.jsp devem ser chamados quando um cliente tenta acessar um diretrio web qualquer

Definio da pgina padro de um site.

<welcome-file-list> <welcome-file>bemvindo.jsp</welcome-file> </welcome-file-list> Reinicie o tomcat e acesse a URL: http://localhost:8080/fj21-agenda/

EL: Expression Language


A mistura ainda no boa. Para remover um pouco do cdigo Java que fica na pgina JSP, foi desenvolvida uma linguagem EL interpretada pelo servlet container. Por exemplo, se o cliente chama a pgina testaparam.jsp?idade=24, o programa deve mostrar a mensagem que o cliente tem 24 anos. A seguir Exerccios com parmetros

Crie uma pgina chamada WebContent/digitaidade.jsp com o contedo:


<html> <body> Digite sua idade e pressione o boto:<br/> <form action="mostra-idade.jsp"> Idade: <input name="idade"/> <input type="submit"/> </form> </body> </html>

Crie um arquivo chamado WebContent/mostraidade.jsp

<html> Testando seus parametros:<br/> A idade ${param.idade}. </html> Teste o sistema acessando a pgina: http://localhost:8080/fj21agenda/digita-idade.jsp.

Os arquivos JSPs no so compilados dentro do Eclipse no precisamos das classes do driver. Os JSPs so transformados em um servlet por um compilador JSP (embutido no Tomcat)

Usando Taglibs
Melhorar nossos problemas com relao mistura de cdigo Java com HTML EL? Sozinha no pode nos ajudar muito. No d para instanciar objetos, fazer verificaes condicionais (if else), iteraes como for e assim por diante. Para que possamos ter esse comportamento sem impactar na legibilidade escrever como HTML, cdigo baseado em Tags. Resultado conjunto de tags padro biblioteca de tags (taglib). Possui, entre outras tags, a funcionalidade de instanciar objetos atravs do construtor sem argumentos.

Instanciando POJOs
Os Javabeans devem possuir o construtor pblico sem argumentos, getters e setters (um tpico Plan Old Java Object). Para instanci-los na pgina JSP utilizarmos a tag correspondente para essa funo <jsp:useBean> Para utiliz-la, basta indicarmos qual a classe queremos instanciar e como se chamar a varivel que ser atribuda essa nova instncia.
<jsp:useBean id="contato" class=agenda.modelo.Contato"/> Agora, podemos imprimir o nome do contato:
${contato.nome}

Instanciando POJOs
Os Javabeans devem possuir o construtor pblico sem argumentos, getters e setters (um tpico Plan Old Java Object). Para instanci-los na pgina JSP utilizarmos a tag correspondente para essa funo <jsp:useBean> Para utiliz-la, basta indicarmos qual a classe queremos instanciar e como se chamar a varivel que ser atribuda essa nova instncia.
<jsp:useBean id="contato" class=agenda.modelo.Contato"/> ${contato.Nome} Agora, podemos imprimir o nome do contato:
${contato.nome}
no funciona

Mas, onde est o getnome()? A EL capaz de perceber sozinha a necessidade de chamar um mtodo do tipo getter, por isso o padro getter/setter do POJO to importante. Soluo JSTL (JavaServer Pages Standard Tag Library) Padro da SUN. JSTL API que encapsulou em tags simples toda a funcionalidade que diversas pginas Web precisam, como controle de laos (fors), controle de fluxo (if else), manipulao de dados XML e a internacionalizao da aplicao. Existem ainda outras partes da JSTL, por exemplo aquela que acessa a BD e permite escrever cdigos SQL na nossa pgina s em casos especiais.

Muitas pginas JSP ainda possuem grandes pedaos de scriptlets. Recomendao usar JSP com JSTL para evitar o cdigo incompreensvel que pode ser gerado com scriptless. Para instalar e implementar basta abaixar no https://jstl.dev.java.net/ Ao usar o JSTL em alguma pgina precisamos primeiro definir o cabealho. Existem 4 APIs bsicas e iremos aprender primeiro a utilizar a biblioteca chamada core.

Cabealho para o JSTL core


Sempre que vamos utilizar uma taglib devemos primeiro escrever um cabealho atravs de uma tag JSP define qual taglib iremos utilizar e um nome, chamado prefixo. NO caso do JSTL c
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

A URI no implica em uma requisio pelo protocolo http e sim uma busca entre os arquivos .jar no diretrio lib. Precisamos instanciar e declarar nosso DAO. J vimos que a tag jsp:useBean capaz de instanciar determinada classe atravs do construtor sem argumentos e dar um nome id para essa varivel

<jsp:useBean id="dao" class="br.com.caelum.agenda.dao.ContatoDAO"/> Tendo a varivel dao, desejamos chamar o mtodo getLista e podemos fazer isso atravs da EL: ${dao.lista} Desejamos executar um lao para cada contato dentro da coleo retornada por esse mtodo (dao.lista). Em scriplets era:
<% // ... List<Contato> contatos = dao.getLista(); for (Contato contato : contatos ) { %> <%=contato.getNome()%>, <%=contato.getEmail()%>, <%=contato.getEndereco()%>, <%=contato.getDataNascimento() %> <% } %>

<c:forEach var="contato" items="${dao.lista}"> ${contato.nome}, ${contato.email}, ${contato.endereco}, ${contato.dataNascimento} </c:forEach> Precisamos indicar a coleo na qual vamos iterar, atravs do atributo itens e tambm como chamar o objeto que ser atribudo para cada iterao; atravs do atributo var. Qual cdigo mais elegante?

Esta tag capaz de iterar por uma coleo

<c:forEach var="contato" items="${dao.lista}"> ${contato.nome}, ${contato.email}, ${contato.endereco}, ${contato.dataNascimento} </c:forEach> Precisamos indicar a coleo na qual vamos iterar, atravs do atributo itens e tambm como chamar o objeto que ser atribudo para cada iterao; atravs do atributo var. Qual cdigo mais elegante?

forEach e varStatus
possvel criar um contador do tipo int dentro do seu lao forEach. Para isso basta definir o atributo chamado varStatus para a varivel desejada e utilizar a propriedade count dessa varivel.
<table border=1"> <c:forEach var="contato" items="${dao.lista}" varStatus="id"> <tr bgcolor="#${id.count % 2 == 0 ? aaee88 : ffffff }" > <td>${id.count}</td><td>${contato.nome}</td> </tr> </c:forEach> </table>

Exerccio
1.

Colocar os JARs da JSTL na aplicao


Cpiar dois jars, jstl impl x - x.jar e jstl- a - x pi x.jar em workspace/fj21 a - genda/WebContent/WEB INF/lib No eclipse d um F5 no seu projeto

2.

Liste os contatos de ContatoDAO usando jsp:useBeans e JSTL


Crie o arquivo WebContent/list c - ontatos e - legante.jsp com o contedo (seg. slide) Acesse http://localhost:8080/fj21 aenda/lista contatos - g elegante.jsp- - >Veja Resultado

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <body> <!-- cria a lista --> <jsp:useBean id="dao" class="br.com.caelum.agenda.dao.ContatoDAO"/> <table> <!-- for --> <c:forEach var="contato" items="${dao.lista}"> <tr> <td>${contato.nome}</td> <td>${contato.email}</td> <td>${contato.endereco}</td> <td>${contato.dataNascimento.time}</td> </tr> </c:forEach> </table> </body> </html>

Exerccio opcional
1. 2.

Coloque um cabealho nas colunas da tabela com um ttulo dizendo que se refere a coluna. Utilize uma varivel de status no seu c:forEach para colocar duas cores diferentes em linhas pares e mpares. (Utilize o box imediatamente antes do exerccio como auxlio)

Evoluindo nossa listagem


Suponhamos que ser quer uma listagem onde caso o usurio tenha e-mail cadastrado, coloquemos um link no e-mail que quando clicado abra o software de e-mail do computador do usurio.
<c:if test="${not empty contato.email}"> <a href="mailto:${contato.email}">${contato.email}</a> </c:if>

Tag c:if indica um teste lgico sobre o atributo a seguir test. Agora possvel colocar a mensagem e-mail no informado caso no tenha sido preenchido. Porm no existe tag else na JSTL. Mas existe a tag c:choose.

<c:choose> <c:when test="${not empty contato.email}"> <a href="mailto:${contato.email}">${contato.email}</a> </c:when> <c:otherwise> E-mail no informado </c:otherwise> </c:choose> possvel fazer com duas tags c:if, a segunda com a lgica invertida, mas a soluo no muito elegante. O cdigo completo seria

<c:forEach var="contato" items="${dao.lista}"> <tr> <td>${contato.nome}</td> <td> <c:choose> <c:when test="${not empty contato.email}"> <a href="mailto:${contato.email}">${contato.email}</a> </c:when> <c:otherwise> E-mail no informado Exerccio: testar </c:otherwise> este cdigo </c:choose> </td> <td>${contato.endereco}</td> <td>${contato.dataNascimento.time}</td> </tr>

Importando pginas
Um requisito comum que temos nas aplicaes web hoje em dia colocar cabealhos e rodap nas pginas do nosso sistema. Esses cabealhos e rodaps podem ter informaes da empresa, do sistema e assim por diante. O problema que deve ser colocado em todas as pginas. Criar um arquivo cabealho.jsp e todas as pginas da nossa aplicao, apenas dizem que precisam importar essa pgina tag c:import Seja cabealho.jsp:
<html> <body> <img src="caminho/de/alguma/imagem.jpg" /> Nome da empresa

E uma pgina de rodap

rodape.jsp

Copyright 2010 - Todos os direitos reservados </body> </html>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <c:import url="cabecalho.jsp" /> <jsp:useBean id="dao" class="br.com.caelum.agenda.dao.ContatoDAO"/> <table> <!-- for --> <c:forEach var="contato" items="${dao.lista}"> <tr> <td>${contato.nome}</td> <td>${contato.email}</td> <td>${contato.endereco}</td> <td>${contato.dataNascimento.time}</td> </tr> </c:forEach> </table> <c:import url="rodape.jsp" />

Exerccios
1.

Criar um cabealho, utilizando algum logotipo. Crie a pgina cabealho.jsp com o seguinte contedo:
<html> <body> <img src="imagens/exemplo.png" /> <h2>Agenda de Contatos do(a) (Seu nome aqui)</h2> <hr />

Criar a pgina rodape.jsp:


<hr /> Copyright 2010 - Todos os direitos reservados </body> </html>

Importemos as duas pginas dentro da listacontatos-elegante.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <c:import url="cabecalho.jsp" /> <!-- cria a lista --> <jsp:useBean id="dao" class="br.com.caelum.agenda.dao.ContatoDAO"/> <table> <!-- for --> <c:forEach var="contato" items="${dao.lista}"> <tr> <td>${contato.nome}</td> <c:if test="${not empty contato.email}"> <a href="mailto:${contato.email}">${contato.email}</a> </c:if> <c:if test="${empty contato.email}"> E-mail no informado </c:if> <td>${contato.endereco}</td> <td>${contato.dataNascimento.time}</td> </tr> </c:forEach> </table> <c:import url="rodape.jsp" />

Visualize o contedo

Trabalhando com links


Muitas vezes trabalhar com links em nossa aplicao complicado. Ex: no arquivo cabealho.jsp foi includa uma imagem chamada exemplo.png que est na pasta imagens.
<img src="imagens/exemplo.png" /> indica um caminho relativo.

Se cabealho.jsp estiver na raiz do projeto, o arquivo exemplo.png dever estar em uma pasta imagens dentro da raiz do projeto perigoso mudana do arquivo jsp implicar na no exibio da imagem. Para resolver este problema utilizamos a tag <c:url> da JSTL e no cabealho.jsp

<c:url value="/imagens/exemplo.gif" var="imagem"/> <img src="${imagem}"/> Ou, mais simples: <img src="<c:url value="/imagens/exemplo.gif"/>"/>

Formatando as datas
A listagem tem problemas com a formatao das datas. No lugar de fazer a formatao atravs da classe Java SimpleDataFormat (evitar cdigo Java no JSP). Usaremos outra Taglib da JSTL fmt. Precisamos import-la.
<%@ taglib uri=http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

Dentro da taglib fmt existe a tag formatDate, que faz com que um objeto do tipo java.util.Date seja formatado para um dado pattern.
<fmt:formatDate value="${contato.dataNascimento.time}" pattern="dd/MM/yyyy" />

Podemos colocar no atributo pattern outras informaes:


m Minutos; s Segundos; H Horas (0 -23); D Dia no ano, ex: 230.

Outras Tags
JSTL possui vrias tags:
c:import - import c:otherwise - default do switch c:out - sada c:param - parmetro c:redirect - redirecionamento c:remove - remoo de varivel c:set - criao de varivel c:url - veja adiante c:when - teste para o switch

Indo alm da JSTL


muito comum, no desenvolvimento de JSPs, ter muita repetio de cdigo. Por exemplo, sempre que for criada uma caixa de texto
<label for="nomeContato">Nome</label> <input type="text" id="nomeContato" name="nome" />

No seria mais simples:


<campoTexto id="nomeContato name="nome label="Nome: />

Outro exemplo, utilizando componentes Javascript: um campo que mostra um calendrio. Componentes visuais do JQuery, uma biblioteca con alguns componentes Javascript. Um desses o campo com calendrio datepicker. Para us-lo precisamos criar um input de texto seimples e associ-lo com uma funo Javascript.

<script type="text/javascript"> $(function() { $("#dataNascimento").datepicker(); }); </script> <input id="dataNascimento" type="text">

Imagine se toda vez que precisemos um campo data, tivessemos que escrever esse cdigo. Maiores chances de erro e perda de tempo escrevendo cdigo repetitivo. No seria melhor:
<campoData id="dataNascimento" />

Criando as suas prprias tags.


Para poder ter a tag <campoData> precisamos crila. Uma das formas que temos de criar nossas prprias taglibs criando um arquivo contendo o cdigo que nossa Taglib gerar tagfiles. Tagfiles: pedaos de JSP com a extenso .tag contendo o cdigo que queremos que a nossa tag gere. Seja campoData.tag:
<script type="text/javascript"> $(function() { $("#dataNascimento").datepicker(); }); </script> <input id="dataNascimento" name="dataNascimento" type="text">

Tag est totalmente inflexvel, pois o id e o nome do campo esto dentro da tag. Se tivssemos dois calendrios dentro do mesmo formulrio? Tag com parmetros. Adicionar a diretiva <%@attribute com parmetros name representando o nome do atributo e o parmetro required (true ou false) indicando se o parmetro obrigatrio ou no.
<%@attribute name="id" required="true" %>

Agora basta usarmos esses parmetros nos lugares adequados atravs de expression language.

<%@attribute name="id" required="true" %> <script type="text/javascript"> $(function() { $("#${id}").datepicker(); }); </script> <input id="${id}" name="${id}" type="text"> Os JSPs que vo utilizar esa tag precisam importar os tagfiles. Para isso precisamos usar a diretiva taglib que recebe o caminho das tags e um prefixo: <%@taglib tagdir="/WEB-INF/tags" prefix=javappl" %> E o tag pode ser usado: < javappl :campoData id="dataNascimento" />

<%@attribute name="id" required="true" %> <script type="text/javascript"> $(function() { $("#${id}").datepicker(); }); </script> <input id="${id}" name="${id}" type="text"> Os JSPs que vo utilizar esa tag precisam importar os tagfiles. Para isso precisamos usar a diretiva taglib que recebe o caminho das tags e um prefixo: <%@taglib tagdir="/WEB-INF/tags" prefix=javappl" %> Mesmo nome do E o tag pode ser usado: arquivo < javappl :campoData id="dataNascimento" />

Utilizando bibliotecas Javascript e estilos em CSS


Para podermos utilizar bibliotecas Javascript precisamos importar o arquivo .js que contem a biblioteca. Para fazermos essa importao:
<head> <script type="text/javascript" src="js/arquivo.js"></script> </head>

Para poder construir uma interface agradvel usar CSS (Cascading Stylesheet). Arquivo contendo as definies visuais para sua pgina extenso .css. Para fazer a importao:
<head> <link type="text/css" href="css/meuArquivo.css" rel="stylesheet" /> </head>

Exerccios
1.
a.

Criao da tag para o campo de calendrio com datepicker biblioteca javascript Jquery
Copie os diretrios js e css dentro de WebContent no seu projeto. Fazer download desses arquivos em http://jqueryui.com/download Precisamos importar o JQuery agora nos nossos arquivos. No cabealho.jsp, adicionar dentro a tag html:
<html> <head> <link type="text/css" href="css/jquery.css" rel="stylesheet" /> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/jquery-ui.js"></script> </head> <body> <!-- Restante do cabealho aqui -->

b.

2.

Agora temos que importar nosso cabealho.jsp na pgina aciona-contatos.html. Que tem que trocar a extenso para .jsp. Remova a declarao <html> e <body> e inclua:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <c:import url="cabecalho.jsp" /> <!-- Aqui continua o formulrio com os campos --> <c:import url="rodape.jsp" />

Acesse agora http://localhost:8080/fj21-

agenda/adiciona-contato.jsp e verifique o resultado

3.
a. b.

Cria a nossa tag calendrio.


Dentro de WEB INF crie u diretrio tags. Crie um arquivo campoData.tag com o seguinte contedo:
<%@ attribute name="id" required="true" %> <script type="text/javascript"> $(function() { $("#${id}").datepicker({dateFormat: dd/mm/yy}); }); </script> <input type="text" id="${id}" name="${id}" />
c.

Utilizar a tag modificando adiciona- c ontato.jsp colocando junto declarao da Taglib core:
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@taglib tagdir="/WEB-INF/tags" prefix=javappl" %>

d.

Vamos trocar o input de data de nascimento pela nossa nova tag:


<form action="adicionaContato"> Nome: <input type="text" name="nome" /><br /> E-mail: <input type="text" name="email" /><br /> Endereo: <input type="text" name="endereco" /><br /> Data Nascimento: <caelum:campoData id="dataNascimento" /><br /> <input type="submit" value="Gravar" /> </form>

e.

Recarregue a pgina adiciona-contato.jsp e clique no campo da data de nascimento. O calendrio deve ser aberto, escolha uma data e faa a gravao do contato.

Outras taglibs no mercado


Existem muitas Taglibs disponveis. Antes de criar uma, verifique se j no existe:
Displaytag: uma Taglib para gerao fcil de tabelas, e pode ser encontrada em http://displaytag.sf.net Cewolf: uma Taglib para gerao de grficos nas suas pginas e tambm pode ser encontrada em: http://cewolf.sourceforge.net/new/ Waffle Taglib: Tags para auxiliar na criao de formulrios HTML que encontrada em: http://waffle.codehaus.org/taglib.html

MVC Model View Controller


Colocar HTML dentro de uma Servlet no a melhor idia dificulta mudar o design da pgina; designer em geral no conhece java Imagine agora usar apenas JSP problema o uso de muito scriptlet, difcil de dar manuteno. Idia usar o que bom de cada um dos dois. O JSP foi feito para apresentar o resultado, e ele no deveria fazer acesso a BD e nem fazer a isntanciao de objetos. Papel do servlets. O ideal ento que a Servlet faa o trabalho da lgica de negcios, e o JSP apenas apresente visualmente os resultados gerados pela Servlet lgica de apresentao.

Seja o cdigo do mtodo da servlet AdicionaContatoServlet feito antes:


protected void service( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // log System.out.println("Tentando criar um novo contato..."); // acessa o bean Contato contato = new Contato(); // chama os setters ... // adiciona ao banco de dados ContatoDAO dao = new ContatoDAO(); dao.adiciona(contato); // ok.... visualizao out.println("<html>"); out.println("<body>"); out.println("Contato " + contato.getNome() + " adicionado com sucesso"); out.println("</body>"); out.println("</html>"); }

O cdigo mistura HTML com Java. Portanto, seria bom criar um arquivo JSP contato-adicionado.jsp apenas com o HTML:
<html> <body> Contato ${param.nome} adicionado com sucesso </body> </html>

Precisamos redirecionar as requisies. Encaminhar a requisio para um outro recurso: Servlet JSP. Dispatch de requisies.

Request Dispatcher
A API, como j foi visto permite separar a apresentao da lgica. Basta conhecermos a URL e podermos usar um objeto RequestDsipatcher para acessar outro recurso Web (JSP ou outra Servlet).
RequestDispatcher rd = request.getRequestDispatcher("/contatoadicionado.jsp"); rd.forward(request,response);

Podemos agora executar a lgica na Servlet e ento redirecionar o resultado para a JSP. O mtodo forward s pode ser chamado quando nada fora escrito para a sada. Existe outro mtodo da classe RequestDsipatcher que representa a incluso e no o redirecionamento include Acrescenta ao resultado de uma pgina os dados de outra.

Melhorando o processo
Temos vrias servlets acessando o BD, traalhando com os DAOs e pedindo para que o JSP apresente esses dados. Veja o diagrama a seguir:

Como centralizar todos os servlets?

Para cada lgica de negcio servlet diferente. Isso implica 8 linhas de cdigo no web.xml. Imagine 10 classes de modelo, 5 lgicas diferentes 400 linhas de configurao. Podemos colocar tudo em uma Servlet (Veja Figura). Poderamos acessar como:
http://localhost:8080/contexto/sistema?logica=AdicionaContato

// Todas as lgicas dentro de uma Servlet public class SistemaTodoServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) { String acao = request.getParameter("logica"); ContatoDAO dao = new ContatoDAO(); if (acao.equals("AdicionaContato")) { Contato contato = new Contato(); contato.setNome(request.getParameter("nome")); contato.setEndereco(request.getParameter("endereco")); contato.setEmail(request.getParameter("email")); dao.adiciona(contato); RequestDispatcher rd = request.getRequestDispatcher("/contato-adicionado.jsp"); rd.forward(request, response); } else if (acao.equals("ListaContatos")) { // busca a lista no DAO // dispacha para um jsp } else if (acao.equals("RemoveContato")) { // faz a remoo e redireciona para a lista } } }

Para cada ao teramos um if/else, tornando o Servlet muito grande. Porque no colocar cada regra de negcio (como inserir contato, remover contato, fazer relatrio, etc.) em uma classe separada. Cada ao (regra de negcio) em nossa aplicao estaria em uma classe. O cdigo poderia ser:
if (acao.equals("AdicionaContato")) { new AdicionaContato().executa(request,response); } else if (acao.equals( "ListaContato")) { new ListaContatos().executa(request,response); }

Executa faz a lgica de negcios apropriada. A cada lgica nova, removida, alterao, etc., temos que alterar o Servlet trabalhoso e propenso a erros

O cdigo acima possui o mesmo comportamento de switch pode ser substitudo por polimorfismo quase sempre. Tentemos generalizar:
String nomeDaClasse = request.getParameter("logica"); new nomeDaClasse().executa(request,response);

O cdigo acima no vlido. nomeDaClasse o nome de uma varivel. Mas a partir do nome da classe podemos recuperar um objeto que representar as informaes contidas dentro daquela classe: atributos, mtodos e construtores. Exemplo

String nomeDaClasse = nomePacote." + request.getParameter("logica"); Class classe = Class.forName(nomeDaClasse);

Agora podemos ter uma representao das classes, mas como instanciar essas classes? Uma das informaes contidas pelo objeto do tipo Class o construtor, portanto podemos invoc-lo para instanciar a classe atravs do mtodo newInstance:
Object objeto = classe.newInstance();

E agora, um primeira alternativa, seria fazer novamente if/else para sabermos qual a lgica invocada:

String nomeDaClasse = nomePacote.mvc." + request.getParameter("logica"); Class classe = Class.forName(nomeDaClasse); Object objeto = classe.newInstance(); if (nomeDaClasse.equals("nomePacote.mvc.AdicionaContato")) { ((AdicionaContato) objeto).executa(request, response); } else if (nomeDaClasse.equals("nomePacote.mvc.ListaContatos")) { ((ListaContatos) objeto).executa(request, response); } //e assim por diante Mas, de novo if/else. newInstance() retorna um tipo Object que pode ser qualquer uma das lgicas. Podemos criar uma Interface Lgica que declara o mtodo executa:
public interface Logica { void executa(HttpServletRequest req, HttpServletResponse res) throws Exception; }

Podemos simplificar nossa Servlet para executar a lgica de forma polimrfica e, tudo aquilo que faziamos em 8 linhas de cdigo, agora podemos fazer em apenas 2:
Logica logica = (Logica) classe.newInstance(); logica.executa(request, response);

Uma lgica simples para logar algo no console poderia ser:


public class PrimeiraLogica implements Logica { public void executa(HttpServletRequest req, HttpServletResponse res) throws Exception { System.out.println("Executando a logica e redirecionando..."); RequestDispatcher rd = req.getRequestDispatcher("/primeira-logica.jsp"); rd.forward(req, res); } }

Podemos simplificar nossa Servlet para executar a lgica de forma polimrfica e, tudo aquilo que faziamos em 8 linhas de cdigo, agora podemos fazer em apenas 2:
Logica logica = (Logica) classe.newInstance(); logica.executa(request, response);

Uma lgica simples para logar algo no console poderia ser:


public class PrimeiraLogica implements Logica { public void executa(HttpServletRequest req, HttpServletResponse res) Algum precisa throws Exception { controlar que ao ser System.out.println("Executando a logica e redirecionando..."); executada para cada RequestDispatcher rd = req.getRequestDispatcher("/primeira-logica.jsp"); requisio Servlet rd.forward(req, res); } }

A configurao do web.xml
A nica coisa que falta para que tudo o que fizemos funcione declarar a nossa nica Servlet.
<web-app> <servlet> <servlet-name>controlador</servlet-name> <servlet-class>br.com.caelum.mvc.ControllerServlet</servletclass> </servlet> <servlet-mapping> <servlet-name>controlador</servlet-name> <url-pattern>/mvc</url-pattern> </servlet-mapping> </web-app>

Exerccios: Criando as lgicas e servlet de controle


1.

Crie a sua interface no pacote nomePacote.mvc.logica:


public interface Logica { void executa(HttpServletRequest req, HttpServletResponse res) throws Exception; }

2.

Crie uma implementao da interface Logica, classe PrimeiraLogica, no pacote acima.


1 public class PrimeiraLogica implements Logica { 2 public void executa(HttpServletRequest req, HttpServletResponse res) throws Exception { 3 System.out.println("Executando a logica e redirecionando..."); 4 5 RequestDispatcher rd = req.getRequestDispatcher("/primeiralogica.jsp"); 6 7 8} rd.forward(req, res); }

3.

Faa um arquivo jsp chamado primeira-logica.jsp dentro do diretrio WebContent:


<html> <body> <h1> Pgina da nossa primeira lgica </h1> </body> </html>

4.

Escreva a Servlet que coordenar o fluxo da aplicao. Coloque-a nomePacote.mvc.servlet

public class ControllerServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String parametro = request.getParameter("logica"); String nomeDaClasse = "br.com.caelum.mvc.logica." + parametro; try { Class classe = Class.forName(nomeDaClasse); Logica logica = (Logica) classe.newInstance(); logica.executa(request, response); } catch (Exception e) { throw new ServletException("A lgica de negcios causou uma exceo", e); } } }

5.

Mapeie a URL /mvc para essa servlet no arquivo web.xml


<servlet> <servlet-name>controlador</servlet-name> <servlet-class>br.com.caelum.mvc.servlet.ControllerServlet</servletclass> </servlet> <servlet-mapping> <servlet-name>controlador</servlet-name> <url-pattern>/mvc</url-pattern> </servlet-mapping>

6.

Teste a url:
http://localhost:8080/fj21-agenda/mvc?logica=PrimeiraLogica

Exerccios: Lgica para alterar contatos


1.

Crie uma nova classe chamada AlteraContatoLogic no pacote meuPacote.mvc.logica.


public class AlteraContatoLogic implements Logica { public void executa(HttpServletRequest request, HttpServletResponse response) throws Exception {
Contato contato = new Contato(); long id = Long.parseLong(request.getParameter("id")); contato.setId(id); contato.setNome(request.getParameter("nome")); contato.setEndereco(request.getParameter("endereco")); contato.setEmail(request.getParameter("email")); //Converte a data de String para Calendar String dataEmTexto = request.getParameter("dataNascimento"); Date date = new SimpleDateFormat("dd/MM/yyyy").parse(dataEmTexto); Calendar dataNascimento = Calendar.getInstance(); dataNascimento.setTime(date); contato.setDataNascimento(dataNascimento); ContatoDAO dao = new ContatoDAO(); dao.atualiza(contato); RequestDispatcher rd = request.getRequestDispatcher("/lista-contatos-elegante.jsp"); rd.forward(request, response); System.out.println("Alterando contato ..." + contato.getNome());

} }

2.

Crie uma nova pgina altera-contato.jsp que atravs do mtodo POST que chama a lgica criada acima.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib tagdir="/WEB-INF/tags" prefix="caelum" %> <c:import url="cabecalho.jsp" /> Formulrio para alterao de contatos:<br/> <form action="mvc" method="POST"> Id: <input type="text" name="id"/><br/> Nome: <input type="text" name="nome"/><br/> E-mail: <input type="text" name="email"/><br/> Endereo: <input type="text" name="endereco"/><br/> Data de Nascimento: <caelum:campoData id="dataNascimento" /> <input type="hidden" name="logica" value="AlteraContatoLogic"/> <input type="submit" value="Enviar"/> </form> <c:import url="rodape.jsp" />

Model View Controller


Responsvel por apresentar os resultados na pgina web chamado de Apresentao (view). A servlet (e auxiliares) que faz os dispatchs para quem deve executar determinada tarefa chamada de Controladora (Controller) As classes que representam suas entidades e as que ajudam a armazenar e buscar dados so chamadas de Modelo (Model). MVC garante a separao de tarefas, facilitando assim a reescrita de alguma parte, e a manuteno do cdigo. O famoso Struts ajuda a implementar MVC, pois tem uma controladora j pronta, com uma srie de ferramentas para se auxiliar. O Hibernate pode ser usado como Model. E como View voc no precisa usar s JSP, pode usar a ferramenta Velocity, por exemplo.

Lista de tecnologias: camada de controle


1)

Struts Action - o controlador mais famoso do mercado Java, utilizado principalmente por ser o mais divulgado e com tutoriais mais acessveis. Possui vantagens caractersticas do MVC e desvantagens que na poca ainda no eram percebidas. o controlador pedido na maior parte das vagas em Java hoje em dia. JSF - JSF uma especificao da Sun para frameworks MVC. Ele baseado em componentes e possui vrias facilidades para desenvolver a interface grfica. Devido ao fato de ser um padro da Sun ele bastante adotado. JBoss Seam - segue as idias do Stripes na rea de anotaes e desenvolvido pelo pessoal que trabalhou tambm no Hibernate. Trabalha muito bem com o Java Server Faces e EJB 3. Spring MVC - uma parte do Spring Framework focado em implementar um controlador MVC. fcil de usar em suas ltimas verses e tem a vantagem de se integrar a toda a estrutura do Spring. Stripes - um dos frameworks criados em 2005, abusa das anotaes para facilitar a configurao.

2)

3)

4)

5)

Lista de tecnologias: Camada de visualizao


1.

2.

3.

4.

JSP - como j vimos, o JavaServer Pages, temos uma boa idia do que ele , suas vantagens e desvantagens. O uso de taglibs (a JSTL por exemplo) e expression language muito importante se voc escolher JSP para o seu projeto. a escolha do mercado hoje em dia. Velocity - um projeto antigo, no qual a EL do JSP se baseou, capaz de fazer tudo o que voc precisa para a sua pgina de uma maneira extremamente compacta. Freemarker - similar ao Velocity e com idias do JSP - como suporte a taglibs - o freemarker vem sendo cada vez mais utilizado, ele possui diversas ferramentas na hora de formatar seu texto que facilitam muito o trabalho do designer. Sitemesh - no uma alternativa para as ferramentas anteriores mas sim uma maneira de criar templates para seu site, com uma idia muito parecida com o struts tiles, porm genrica: funciona inclusive com outras linguagens como PHP etc.

Recursos importantes: Filtros


Criar classes que filtram a requisio e a resposta Guardar objetos na requisio

Reduzindo o acoplamento com filtros


Qualquer aplicao tem requisitos que no so diretamente relacionados com a regra de negcios. Requisitos no funcionais: auditoria (Logging), autorizao, etc. Como implementar estas facilidades? Colocar o cdigo diretamente na classe que possui a lgica. Exemplo Prximo Slide. Podemos ver que alm da lgica preciso implementar os outros requisitos, mas no s apenas em uma funcionalidade (altera o contato) seno em todas as outras (adiciona, remove ou faz listagem de contatos). Esta soluo cria um acoplamento muito forte entre a lgica e a implementao dos requisitos no funcionais Veja Figura.

public class AlteraContatoLogic implements Logica { public void executa(HttpServletRequest request, HttpServletResponse response) throws Exception { //auditoria Logger.info("acessando altera contato logic"); //autorizao if(!usuario.ehCliente()) { request.getRequestDispatcher("/acessoNegado.jsp"). forward(request,response); } //toda lgica para alterar o contato aqui //... } }

A API de Servlets nos prov um mecanismo para tirar esse acoplamento e isolar esse comportamento, que so os Filtros. Filtros so classes que permitem que executemos cdigo antes da requisio e tambm depois que a reposta foi gerada. Uma analogia pensar que as lgicas so quartos em uma casa. Os filtros seriam portas. Cada filtro encapsula apenas uma responsabilidade, um para fazer auditoria, outro para fazer a segurana, etc. Veja Fig.

A grande vantagem que cada requisito fica em um lugar s, conseguimos tirar o acoplamento dentro das lgicas. Para criarmos um filtro, basta criarmos uma classe que implemente a interface javax.servlet.Filter. Ao implementar essa interface, temos que implementar 3 mtodos: init, destroy e doFilter. Os mtodos init e destroy possuem a mesma funo dos mtodos de um Servlet. O mtodo que far todo o processamento que queremos executar o doFilter recebe os parmetros ServletRequest, ServletResponse e FilterChain.

public class FiltroConexao implements Filter { // implementao do init e destroy public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //todo o processamento vai aqui } }

Um filtro processa requests como os servlets, mas de maneira mais genrica para vrios tipos de requests. Mais um filtro vai alm de um servlet, com um filtro podemos tambm fechar a porta FilterChain Permite indicar ao container que o request deve prosseguir seu processamento.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //passa pela porta chain.doFilter(request, response); }

Um filtro intercepta vrios requests semelhantes, executar alguma coisa, mas depois permitir que o processamento normal do request prossiga atravs das Servlets e JSPs normais. Qualquer cdigo antes da chamada chain.doFilter ser executado na ida, qualquer cdigo depois na volta. Com isso podemos fazer uma verificao de acesso antes da lgica, ou abrir um recurso (conexo ou transao) antes e na volta fechar o mesmo fazer tratamento de erro ou medir o tempo de execuo.

Precisamos, para que funcione, registr-lo, assim o container saber que ele precisa ser executado web.xml
<filter> <filter-name>FiltroTempoDeExcecucao</filter-name> <filterclass>br.com.caelum.agenda.filtro.FiltroTempoDeExcecucao</filterclass> </filter> <filter-mapping> <filter-name>FiltroTempoDeExcecucao</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

Precisamos, para que funcione, registr-lo, assim o container saber que ele precisa ser executado web.xml
<filter> <filter-name>FiltroTempoDeExcecucao</filter-name> <filterclass>br.com.caelum.agenda.filtro.FiltroTempoDeExcecucao</filterclass> Todas as requisies </filter>
*.jsp mais <filter-mapping> especfico. S <filter-name>FiltroTempoDeExcecucao</filter-name> requisies para pginas JSPs <url-pattern>/*</url-pattern> </filter-mapping> sero filtradas. Ser aplicado em cada requisio

Exerccio: Filtro para medir o tempo de execuo


1.
a.

Fazer filtro para medir o tempo de execuo de uma requisio.


Criar uma classe chamada FiltroTempoDeExecuo no pacote meuPacote.agenda.filtro e faa ela implementar a interface javax.servlet.Filter. Deixar os mtodos init e destroy vazios e implemente o doFilter Veja Slide. Declarar o filtro no web.xml, para fazer com que todas as requisies passem por ele Veja Slide Reiniciar o servidor e acesse: http://localhost:8080/fj21 agenda/altera c - ontato.jsp. Procurar a sada no console.

b. c. d.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long tempoInicial = System.currentTimeMillis(); chain.doFilter(request, response); long tempoFinal = System.currentTimeMillis(); System.out.println("Tempo da requisio em millis: " + (tempoFinal - tempoInicial)); } <filter> <filter-name>FiltroTempoDeExcecucao</filter-name> <filter-class>br.com.caelum.agenda.filtro.FiltroTempoDeExcecucao</filter-class> </filter> <filter-mapping> <filter-name>FiltroTempoDeExcecucao</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

Problemas na criao de conexes


A aplicao de agenda precisa em vrios momentos, de uma conexo com o BD. O nosso DAO invoca em seu construtor a ConnectionFactory pedindo para a mesma uma nova conexo. Mas e o fechamento da conexo?
public class ContatoDAO { private Connection connection; public ContatoDAO() { this.connection = new ConnectionFactory().getConnection(); } // mtodos adiciona, remove, getLista etc // onde fechamos a conexo? }

Pssima prtica deixar conexes abertas.

Tentando outras estratgias


No uma boa idia colocarmos a criao da conexo no construtor dos nossos DAOs. Mas qual o lugar ideal? Precisamos, de alguma forma, criar a conexo e fazer com que essa mesma conexo possa ser usada por todos os DAOs em uma determinada requisio.
public class ContatoDAO { private Connection connection; public ContatoDAO(Connection connection) { this.connection = connection; } // mtodos adiciona, remove, getLista etc }

public class AdicionaContatoLogic implements Logica { public void execute(HttpServletRequest request, HttpServletResponse response) { Contato contato = //contato montado com os dados do request Connection connection = new ConnectionFactory().getConnection(); // passa conexao pro construtor ContatoDAO dao = new ContatoDAO(connection); dao.adiciona(contato); connection.close(); } } No uma soluo muito boa. Acoplamos com a ConnectionFactory todas as nossas lgicas que precisam utilizar DAOs

Reduzindo o acoplamento com Filtros


Para diminuirmos esse acoplamento, queremos que, sempre que chegar uma requisio para a nossa aplicao, uma conexo seja aberta e, depois que essa requisio for processada, ela seja fechada. Precisamos ento interceptar toda requisio para executar esses procedimentos. Os Filtros seria ideais Veja cdigo Com a conexo aberta, precisamos ento fazer com que a requisio saia do nosso filtro e v para o prximo passo, seja ele um outro filtro, ou um Servlet ou um JSP. Conseguimos abrir uma conexo no comeo dos requests, prosseguir o processamento do request e fechar a conexo aps a execuo. Mas nossas lgicas vo executar manipulaes de Contatos e vo precisar da conexo aberta no filtro. Como acess-la? Como, dentro de uma Servlet pegar um objeto criado dentro de um filtro, uma outra classe?

public class FiltroConexao implements Filter { // implementao do init e destroy, se necessrio public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //abre uma conexo Connection connection = new ConnectionFactory().getConnection(); // indica que o processamento do request deve prosseguir chain.doFilter(request, response); //fecha conexo connection.close(); } }

A idia associar (pindurar) de alguma forma a conexo criada ao request atual. Tanto o filtro quanto o servlet esto no mesmo request. Veja Figura. Para guardarmos algo na requisio, precisamos invocar o mtodo setAttribute no request. Passamos para esse mtodo uma identificao para o objeto que estamos guardando na requisio e tambm passamos o prprio obejto para ser guardado no request Veja cdigo.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { Connection connection = new ConnectionFactory().getConnection(); // "pendura um objeto no Request" request.setAttribute("connection", connection); chain.doFilter(request, response); connection.close(); } Ao invocarmos o doFilter, a requisio seguir o seu fluxo normal levando o objeto connection junto. Portanto, o Filtro o nico ponto da nossa aplicao que criar conexes. Agora necessrio registr-lo

<filter> <filter-name>FiltroConexao</filter-name> <filter-class>br.com.caelum.agenda.filtro.FiltroConexao</filter-class> </filter> <filter-mapping> <filter-name>FiltroConexao</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

Agora s falta saber como pegar a conexo que guardamos no request. Para isso basta invocarmos o mtodo getAttribute no request.

public class AdicionaContatoLogic implements Logica { public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception { Contato contato = // contato montado com os dados do request // buscando a conexao do request Connection connection = (Connection) request.getAttribute("connection"); ContatoDAO dao = new ContatoDAO(connection); dao.adiciona(contato); // faz o dispatch para o JSP como de costume } }

Exerccios: Filtros
1.
a.

Vamos criar o nosso filtro para abrir e fechar a conexo com o BD.
Crie uma nova classe chamada FiltroConexo no pacote meuPacote.agenda.Filtro e faa ela implementar a interface javax.servlet.Filter Deixe os mtodos init e destroy vazios e implemente o doFilter Veja prxima Transparncia Declare o filtro no web.xml, para fazer com que todas as requisies passem por ele. Isso foi feito acima.

b. c.

2.

Crie um construtor no seu ContatoDAO que receba Connection e armazene-a no atributo Veja transparncia.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { Connection connection = new ConnectionFactory().getConnection(); request.setAttribute("connection", connection); chain.doFilter(request, response); connection.close(); } catch (SQLException e) { throw new ServletException(e); } }

public class ContatoDAO { private Connection connection; public ContatoDAO(Connection connection) { this.connection = connection; } //outro construtor e mtodos do DAO }

Agora na sua conta AlteraContatoLogica criada acima, busque a conexo no request, e repasse-a para o DAO Veja prxima transparncia. 4. Altere um contato j existente na sua aplicao e verifique que tudo continua funcionando normalmente.
3.

public class AlteraContatoLogic implements Logica { public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception { // buscando a conexao do request Connection connection = (Connection) request.getAttribute("connection"); // busca dados do request // faz converso e monta objeto contato Contato contato = // .... ContatoDAO dao = new ContatoDAO(connection); dao.atualiza(contato); // Faz o dispatch para o JSP } }

Struts 2
Porque utilizar frameworks Como funciona o framework Struts 2 As diferentes formas de se trabalhar com Struts 2.

Porque precisamos de frameworks MVC?


Quando estamos desenvolvendo aplicaes, em qualquer linguagem queremos nos preocupar com infraestrutura o mnimo possvel. Quando trabalhamos com containers e a API de Servlets existe muito trabalho repetitivo que precisamos fazer para que possamos desenvolver a nossa lgica. Frameworks MVC, surgem para diminuir o impacto da API de Servlets em nosso trabalho e fazer com que passemos nos preocupar exclusivamente com a lgica de negcios valor para a aplicao.

Um pouco de histria
Logo que percebeu que o trabalho com Servlets e JSPs puros no era to produtivo e organizado. Sun comeou fomentar o uso do padro MVC e de patterns com Front Controller. Empresas implementaram suas solues baseadas em mini-frameworks caseiros muito retrabalho de projeto para projeto. O Struts foi um dos primeiros frameworks MVC com a idia de se criar um controlador reutilizvel entre projetos. Lanado no 2000.

Um pouco de histria
Entretanto, hoje em dia ele demanda muito trabalho, por ter sido criado quando no existiam muitas das facilidades da linguagem Java. Para resolver isso, a comunidade do Struts uniu-se com outro framework WebWork. Foi desenvolvido Struts 2 verso mais simples de se trabalhar do que Struts 1, e com ainda mais recursos e funcionalidades. Permite uma migrao suave de Struts 1.

Configurando o Struts 2
Para que possamos aprender o Struts 2, vamos criar um sistema de lista de tarefas. O primeiro que devemos fazer ter o Struts 2 http://struts.apache.org/2.x/ Uma vez que adicionarmos os JARs do Struts 2 em nosso projeto dentro WEB-INF/lib, precisamos declarar o Filtro, que far o papel de Front Controller da nossa aplicao, recebendo as requisies e as enviando s lgicas corretas. Para declararmos o Filtro do Struts 2, basta adicionarmos no web.xml, o seguinte

<filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecut eFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> Repare como uma configurao normal de filtro, como as que fizemos antes.

Criando as lgicas
Existem diversas abordagens seguidas pelos frameworks para possibilitar a criao de lgicas. Declarao em um arquivo XML, e, a partir do Java 5, surgiram as anotaes, que so uma forma de introduzir metadados dentro de nossas classes. Struts 2 permite criar lgicas de 3 formas:
Declarao em um arquivo XML como Struts 1 Utilizando convenes: no necessrio herdar nem escrever nenhum XML, desde que a sua lgica seja criada em um pacote pr d - efinido pelo framework Utilizando anotaes: foi uma forma introduzida pelo WebWork. Conseguido atravs do uso do plugin de convenes.

A lgica Ol Mundo!
Nossa primeira lgica OlaMundoAction. Criar uma classe com esse nome. O sufixo Action conveno em Struts. Como utilizaremos o plugin de convenes, obrigatrio que a sua Action esteja dentro de um subpacote com um dos nomes: struts2, action ou actions. No nosso caso, criaremos a classe dentro do pacote: meuPacote.tarefas.action. Dentro dessa nossa nova classe, vamos criar um mtodo que imprimir algo no console e, em seguida, ir redirecionar para um JSP com a mensagem Ol Mundo!. Podemos criar tambm um mtodo de qualquer nome dentro dessa classe, desde que ele esteja com a anotao @Action.

A lgica Ol Mundo!
A anotao @Action recebe um atributo chamado value que indica qual ser a URL utilizada para invocar a Action. Se colocarmos o valor olaMundoStruts acessaremos nossa Action pela URL http://localhost:8080/fj21tarefas/olaMundoStruts. Uma outra conveno que criar um mtodo chamado execute. Esse mtodo deve retornar uma String que indica qual JSP deve ser executado aps a lgica.

Anatomia de uma pgina JSP


Biblioteca de tags customizados a ser usada pela pgina

Anatomia de uma pgina JSP


Diretivas: diferencia-se dos outros elementos porque no gera sadas diretamente. Elas so usadas para controlar algumas caractersticas da pgina. Diretivas permitidas:
Diretivas de pgina Diretivas taglib Diretivas include <%@ taglib .... %> no compatvel com XML <jsp>directive.taglib .... />

Elas fornecem instrues ao contenedor sobre como processar JSP.

Anatomia de uma pgina JSP


Dados de template: texto esttico. No processado pelo contenedor JSP. HTML esttico. Ao: elementos envolvidos no processamento da solicitao. Facilitam acessar dados e manipular ou transformar dados na gerao dinmica da sada. Classificados em: estndares e customizados. Elementos de script: incorporao de cdigo numa linguagem de programao (Java). Trs elementos diferentes:
Declaraes: declarao de variveis e mtodos em java Scriptlets: segmentos arbitrrios de cdigo java Expresses: expresses java que conduzem a um valor resultante.

Expresses:

Um outro exemplo de JSP

Resultado

Um exemplo misturando Servlets

Manuteno do Estado
HTTP stateless Vantagens
Fcil de usar: no precisa nada Bom para aplicaes com informao esttica No precisa de espao em memria adicional

Desvantagens
Nenhum registro de solicitaes anteriores
Impossvel carrinho de compras Impossvel logins de usurios Nenhum contedo dinmico ou customizado Segurana mais difcil de implementar

Estado da aplicao
Estado do lado do servidor Estado do lado do cliente Estado escondido
Informao armazenada num BD, ou na memria local da camada de aplicao Informao armazenada no computador do cliente na forma de uma cookie Informao escondida dentro dentro das pginas web criadas dinamicamente

Estado do lado do servidor


Vrias formas 1. Armazenar informao num BD
Dados estaro seguros no BD MAS: precisa de acessos ao BD para consultar e atualizar a informao
2.

Usar a memria local da camada de aplicao


Pode mapear o endereo IP do usurio para algum estado MAS: a informao voltil e pode exigir muita memria principal do servidor 5 milhes de IPs = 20 MB

Estado do lado do servidor


1.

Deveria usar manuteno do estado do lado do servidor para informao que precisa persistir
Pedidos de clientes antigos Seqncias de click de um usurio se movimentando num site Escolhas permanentes que um usurio faz

Estado no lado do cliente: Cookies


Armazenando texto sobre o cliente que ser passado aplicao com toda a solicitao HTTP.
Pode ser desabilitado pelo cliente. So erradamente percebidos como perigosos, e vrios usurios evitam visitar sites que usem estas facilidades So um coleo de pares (Nome, Valor)

Estado do lado do cliente: Cookies


Vantagens

Desvantagens

Facil de usar em Java Servlets/ JSP Oferece uma forma simples para que persistam dados no essenciais no cliente mesmo quando o cliente (browser) tem fechado Limitado a 4Kbytes de informao Usurios podem (e freqentemente o fazem) desabilitar eles A informao de login do usurio atual O carrinho de compras atual Qualquer escolha no permanente que o usurio tenha feito

Os cookies deveriam ser usados para armazenar o estado interativo

Criando um Cookie

Voc pode criar cookies em qualquer momento.

Acessando um Cookie

Caractersticas dos Cookies


Os cookies podem ter

Ver os tutorias de APIS de Java Servlets e Servlets.

Uma durao (expira ou persistem mesmo depois que o browser tem fechado) Filtros para os quais as trajetrias de domnio/diretrios o cookie enviado

Estados ocultos
Com freqncia os usurios desabilitam os cookies. Voc pode ocultar dados em dois lugares: No precisa de armazenamento de informao porque a informao do estado enviado dentro de cada pgina web
Campos ocultos dentro de um formulrio Usando a informao do caminho

Estados ocultos: Campos ocultos


Declarar campos ocultos dentro de um formulrio:
<input Type='hidden' name='user' value='username' />

Usurios no enxergaro esta informao (a menos que eles vejam o fonte HTML) Se for usado prolificamente, ele deteriora o desempenho, j que TODA pgina deve ser contida dentro de um formulrio.

Estado oculto: informao do caminho


A informao do caminho armazenado na solicitao de URL: http://server.com/index.htm?user=jeffd Pode separar 'campos' com caracter &: index.htm?user=jeffd&preference=pepsi Existem mecanismos para analisar estes campos em java. Verifique o mtodo javax.servlet.http.HttpUtilsparserQueryString()

Mtodos de mltiples estados


Tipicamente todos os mtodos de manuteno de estado so usados:
O usurio se loga e esta informao armazenada em um cookie O usurio emite uma consulta a qual armazenada na informao do caminho O usurio coloca um item em um cookie carrinho de compras Compras de um usurio e informao do carto de crdito armazenada/recuperada de um BD. O usurio deixa uma seqncia de clicks a qual mantida no log do servidor web (o qual analisado mais tarde)

Você também pode gostar