Requisio e Resposta Quando voc digita algum endereo (URL) no browser, basicamente solicita um determinado arquivo localizado em um computador em especial no local que voc digita a URL. sta m!quina onde o arquivo solicitado por voc est! armazenado, " c#amado de web server (servidor web). ssa principal $un%o do computador " para servir a qualquer um na &nternet que solicite arquivos que ele #ospeda. '! que voc nunca sabe quando um usu!rio visitar! e usar! o seu aplicativo web, o seu servidor web precisa estar ativo e em e(ecu%o o tempo todo. )e uma maneira mais anal*tica, o que acontece " o seguinte ap+s voc digitar , -. o browser (cliente) estabelece uma cone(%o ./01&0 com o servidor2 3. o browser envia uma solicita%o ao servidor (request)2 4. o servidor envia uma resposta ao cliente (response)2 5. o servidor $ec#a a cone(%o. " o protocolo que permite que os servidores web e browsers troquem dados pela web. 6 um protocolo de requisi%o e resposta. 7o in*cio as p!ginas eram praticamente todas est!ticas, ou se8a somente arquivos 9.:L que n%o eram gerados dinamicamente e nem tin#am cone(;es com banco de dados. Logo ap+s comearam a criar as /<&s (/ommon <atewa= &nter$ace) que eram geradas dinamicamentes, podiam trabal#ar com arquivos, interagir com banco de dados e etc. :ais tarde vieram linguagens em script tais como p#p e asp. Servlet - "CGI de Java" Um servlet " como se $osse um >>/<& de 'ava??. @ ob8etivo de um servlet " receber uma requisi%o do cliente e produzir uma resposta. sta pode ser encamin#ada a outro componente web, como as 'A0s, ou produzida pelo pr+prio servlet. B Cltima, por"m, n%o " uma alternativa muito boa, 8! que a $un%o especial de um servlet n%o " essa. CGI ! Servlets /<& " outra tecnologia que permite gerar p!ginas dinDmicas, permitindo a um browser passar parDmetros a um programa alo8ado num servidor web. mbora a linguagem tipicamente associada aos /<& se8a o 0RL, o /<& $oi pro8etado de $orma a ser independente de linguagem. Btualmente tecnologias como BA0 ou 090 continuam utilizando a especi$ica%o. Blgumas vantagens de Aervlets sobre /<& " que aqueles s%o, multiEt#reads(v!rias requisi;es ao mesmo tempo), utilizam toda a B0& de 'ava, possuem mais portabilidade e a programa%o " @@. @ que acontece " que scripts /<& acionam programas no servidor. 7o entanto, seu uso o sobrecarrega, uma vez que cada resquisi%o culmina a e(ecu%o de um programa e(ecut!vel (escrito com qualquer linguagem que suporte o padr%o /<&) no servidor. Bl"m disso, o processo " inteiramente realizado pelo /<& no servidor. Ae acontece algum erro na entrada de dados, o /<& tem que produzir um 9.:L e(plicando o problema. '! os Aervlets s%o carregados apenas uma vez e al"m disso tm a vantagem de serem multiEt#reads. /ada cliente " representado por uma lin#a de e(ecu%o em Aervlets, enquanto que em /<& cada cliente " representado por um processo. 7ovas vers;es de /<& contornam o problema, mas permanecem alguns como $alta de portabilidade e insegurana na e(ecu%o de c+digo. API Bpplication 0rogramming &nter$ace ou simplesmente B0& " um con8unto de rotinas e padr;es estabelecidos por um so$tware para utiliza%o de suas $uncionalidades. )e modo geral, a B0& " composta por uma s"rie de $un;es acess*veis somente por programa%o, e que permitem utilizar caracter*sticas do so$tware menos evidentes ao usu!rio tradicional. B B0& de Aervlets " composta, portanto, por um con8unto de &nter$aces e /lasses . @ mais b!sico " a &nter$ace ?Aervlet?, que de$ine o comportamento b!sico do Aervlet. @ m"todo service() " quem trata todas as requisi;es dos clientes. m geral n%o " sobrescrito, delega o processo para o representante (m"todo) adequado, de acordo com a requisi%o. B estrutura b!sica da B0& de Aervlet " a seguinte, API de Servlets Figura 5 - API de Servlets is aqui as considera;es sobre os m"todos, os m"todos init() e destro=() s%o c#amados respectivamente quando o servlet " iniciado e $ec#ado no container2 o m"todo getAervlet/on$ig() retorna um ob8eto (Aervlet/on$ig) que cont"m os parDmetros de inicializa%o2 o m"todo getAervlet&n$o() retorna uma Atring que cont"m in$orma;es sobre o Aervlet2 a classe <enericAervlet normalmente n%o " usada. la implementa um servidor gen"rico2 a classe 9ttpAervlet " uma classe abstrata que $oi criada para lidar com o protocolo 9..0 e " a mais usada. 0ara o servlet atender as requisi;es 9..0, deve ser criada uma classe derivada da 9ttpAervlet e sobrescever ao menos um dos m"todos doGet(), trata requisi;es <., que podem ser enviadas v!rias vezes, sendo ent%o armazenadas em um booFmarF2 doPost(), trata requisi;es 0@A., que permitem o envio de dados (somente uma vez) de qualquer taman#o ao servidor web2 doPut(), trata requisi;es 0U., que permite o envio de dados ao servidor de maneira parecia com o G.02 doDelete(), trata requisi;es )L., que permite que o cliente remova algum documento do servidor. )arei agora um e(emplo de Aervlet que implementa inicializa%o, $inaliza%o e o service, package br.com.nome.servlet; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { publicvoid destroy( { super.destroy(; System.out.println(!"estruir#!; $ publicvoid init( thro%s Servlet&xception { super.init(; System.out.println(!'niciar#!; $ protectedvoid service(HttpServlet(e)uest re)uest* HttpServlet(esponse response Servlet&xception* '+&xception { ,, recebe o %riter -rintWriter out . response.getWriter(; ,, escreve o texto out.println(!/html0!; out.println(!1"21 3 4S- explica!; out.println(!/,html0!; $ $ B organiza%o dos principais m"todos de cada &nter$ace na B0& de Aervlets " a seguinte, Figura 6 - Alguns dos mtodos mais usados Inter"a#e $ttpServletRequest @ m"todo do<et() recebe dois parDmetros. Um deles " o 9ttpAervletRequest, que " respons!vel pela comunica%o e tratamento do que vem do cliente para o servidor. 6 necess!rio que citemos que, de acordo com a B0&, esta inter$ace cont"m, Atring %et$eader&', obt"m valor do primeiro cabeal#o2 numeration %et$eaders&', obt"m os valores de todos os cabeal#os2 numeration %et$eader(a)es&', obt"m os nomes de todos os cabeal#os2 Atring %etPara)eter&Strin% par', obt"m o valor do parDmetro2 AtringHI %etPara)eter*alues&Strin% par', obt"m os valores de todos os parDmetros2 numeration %etPara)eter(a)es&', obt"m os nomes de todos os parDmetros2 Atring %et+et,od&', obt"m o m"todo 9..0 usado2 Atring %et$eader&', obt"m o cabeal#o 9..02 Atring %et-uer.Strin%&', obt"m os dados codi$icados2 Atring %etRe)ote$ost&', obt"m nome do #ost remoto2 Atring %etRe)oteAddr&', obt"m &0 do #ost remoto2 Atring %etProto#ol&', obt"m o protocolo utilizado2 /ooFieHI %etCoo/ies&', obt"m todos os cooFies recebidos2 9ttpAession %etSession&0oolean #ria', pega1cria sess%o2 @b8ect %etAttri0ute&Strin% atr': obt"m valor do atributo2 void setAttri0ute&Strin% no)e, 102e#t o02', cria1modi$ica atributo2 Inter"a#e $ttpServletResponse @utro parDmetro do m"todo do<et() " o 9ttpAervletResponse que " respons!vel pela comunica%o e tratamento do que vai do servidor ao cliente. 6 necess!rio que citemos que, de acordo com a B0&, esta inter$ace cont"m, void setStatus&int #ode', de$ine o c+digo da resposta2 void set$eader&Strin% #a0e# , Strin% valor', de$ine valor2 void add$eader &Strin% #a0e#, Strin% valor', de$ine mais um valor2 void setContent3.pe&Strin% )i)e', de$ine tipo de conteCdo a ser enviado. 6 obrigat+rio a todo servlet que monte resposta2 void addCoo/ie &Coo/ie #', de$ine um cooFie2 void send4rror &int #od, Strin% )s%', devolve uma p!gina de erro. A+ pode ser usado se o stream n%o estiver comprometido2 void sendRedire#t &Strin% 5RI', redireciona requisi%o. A+ pode ser usado se o stream n%o estiver comprometido2 @JA, 0ara testar se o stream est! comprometido use is/ommited(), mas s+ usaEse na pr!tica estes m"todos quando n%o tiver usado o stream. Print6riter %et6riter&', obt"m stream de caracteres2 Servlet1utputStrea) %et1utputStrea)&', idem, s+ que de b=tes. @bserva%o geral, )eveEse utilizar os m"todos de Kcabeal#oK antes de usar o stream para montar a resposta do Aervlet. Inter"a#e ServletRequest @s principais m"todos que esta inter$ace cont"m est%o mostrados na $igura da p!gina anterior. Inter"a#e ServletResponse @s principais m"todos que esta inter$ace cont"m est%o mostrados na $igura da p!gina anterior. 0ara $inalizar, um outro e(emplo de Aervlet implementando as inter$aces e alguns m"todos, import java.util.*; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class SimpleServlet extends HttpServlet { public void do5et(HttpServlet(e)uest re)uest* HttpServlet(esponse response thro%s Servlet&xception* '+&xception { -rintWriter out . response.getWriter(; String title . !Simple Servlet +utput!; ,,con6igura tipo de conte7do e outro cabe8alho de resposta primeiro response.set1ontent2ype(!text,html!; out.println(!/H29:0/H&;"0/2'2:&0!; out.println(title; out.println(!/,2'2:&0/,H&;"0/<+"=0!; out.println(!/H>0! ? title ? !/,H>0!; out.println(!/-02his is output 6rom SimpleServlet.!; out.println(!/-09ethod@ ! ? re)uest.get9ethod(; out.println(!/-0(e)uest A('@ ! ? re)uest.get(e)uestA('(; out.println(!/-0-rotocol@ ! ? re)uest.get-rotocol(; out.println(!/-0-ath'n6o@ ! ? re)uest.get-ath'n6o(; out.println(!/-0(emote ;ddress@ ! ? re)uest.get(emote;ddr(; ,, pega os parBmetros &numeration epar . re)uest.get-arameterCames(; %hile (epar.has9ore&lements( { String par . (Stringepar.next&lement(; String val . re)uest.get-arameter(par; out.println(!/-0-arBmetro !?par?!* valor.!?val; $ out.println(!/,<+"=0/,H29:0!; out.close(; $ public void do-ost(HttpServlet(e)uest re)uest* HttpServlet(esponse response{ try { do5et(re)uest* response; $ catch (&xception e{ System.err.println(!&rro no do-ost Dn!?e; $ $ $ Lio 7 - 5sando Coo/ies e Controlando Sess8es Coo/ies @ protocolo 9..0 possui como uma de suas caracter*sticas n%o possuir in$orma;es de estado. &sto ", depois que uma solicita%o " recebida e uma resposta " devolvida, o servidor 9..0 KesqueceK tudo a respeito do computador no qual aquele navegador est! rodando. B pr+(ima requisi%o ser! tratada, ent%o, como se $osse a primeira daquela m!quina. Bpesar de tornar o protocolo 9..0 mais simples e portanto mais con$i!vel, isso $az com que aplica;es web tornemEse cada vez mais avanadas, a $im de suprir as necessidades de personaliza%o de uma p!gina para seu usu!rio. 0ara $acilitar a vida dos programadores, $oram criados os cooFies. @s cooFies permitem que dados sobre a p!gina atual se8am armazenadas na m!quina do cliente para que se8am acessados em visitas $uturas. /om os cooFies, podeEse recon#ecer quem entrou num site, de onde vem, com que periodicidade costuma voltar, dentre outras utilidades. 7ormalmente, um cooFie " um par de Atrings guardado na m!quina cliente, assim como um mapa de Atrings. sse par de strings possui limita;es que variam de acordo com o cliente utilizado. &sto torna os cooFies pouco con$i!veis, 8! que as in$orma;es do cooFie s%o armazenadas na m!quina cliente. @ mesmo pode, portanto, alter!Ela de alguma maneira, o que torna invi!vel, por e(emplo, guardar o nome do usu!rio logado. 0ara a escrita dos m"todos s%o utilizados os ob8etos request E que l os cooFies usando o m"todo getCookies() E, e o response E que escreve os cooFies atrav"s do m"todo addCookie(Cookie). )a primeira vez que a m!quina cliente $az a requisi%o, o cooFie " salvo nela. B partir da*, ele " enviado de volta ao servidor toda vez que o cliente e$etuar nova requisi%o. Bssim indenti$icaEse um usu!rio, sempre com os dados que o cooFie envia. /ada cooFie s+ " armazenado para um website. /ada website possui seus pr+prios cooFies e estes n%o s%o vistos em outra p!gina. (emplo do uso de cooFies, em logins de websites s%o bastante usados para relembrar seu nome de usu!rio e1ou sen#a para que n%o precise digit!Elos toda vez que acessar a p!gina. Pro0le)as #o) o uso de #oo/ies Bpesar de sua $uncionalidade, " um tanto arriscado trabal#ar com os cooFies em sess;es que necessitam de segurana e " tamb"m um trabal#o complicado ac#ar um cooFie espec*$ico. @utro problema " que, na primeira vez que adicionamos um cooFie na resposta, ele n%o est! dispon*vel para a leitura atrav"s da requisi%o. 0odemos, entretanto, resolver este problema usando um atributo do m"todo request, re)uest.set;ttribute(; Sess8es @ processo de tentar manter o estado atrav"s de mCltiplas solicita;es 9..0 " c#amado de <erenciamento de Aess%o. B id"ia aqui " que as solicita;es de um usu!rio por p!ginas de um servidor web durante um certo per*odo de tempo, s%o na verdade parte da mesma sess%o interativa. Uma sess%o $acilita a vida de todos por permitir atrelar ob8etos de qualquer tipo a um cliente, n%o sendo limitada somente a strings e " independente de cliente. @ 'A0 inclui suporte embutido para <erenciamento de Aess%o ao se aproveitar das capacidades $ornecidas pela B0& de Aervlet de 'ava. @s Aervlets, por sua vez, podem usar a reescrita de URL ou cooFies para implementar o gerenciamento de sess%o, mas os detal#es deste est%o ocultos no n*vel 'A0 de linguagem. B abstra%o da B0& $acilita o trabal#o do programador, 8! que dispensa saber como a se%o $oi implementada no container. le simplesmente sabe que a $uncionalidade e(iste e est! l! para o uso. Uma importante desvantagem do uso de cooFies " que um usu!rio pode desabilitar o suporte para cooFies no Jrowser. 0odemos ent%o usar a reescrita de URL(urlErewriting). 6 uma t"cnica que ane(a o &) de sess%o com um parDmetro de solicita%o a todas as URL que se linFam as p!ginas locais ao servidor web. sta t"cnica " bem trabal#osa, 8! que, a $im de $luir o &) de sess%o apropriado espec*$ico de usu!rio, todas as re$erncias Ls URLs devem ser geradas dinamicamente. B sess%o nada mais " que um tempo que o usu!rio permanece ativo no sistema. B cada p!gina visitada, o tempo de sess%o " zerado. Quando o tempo ultrapassa um limite demarcado no arquivo web.(ml, o cliente perde sua sess%o. 7este momento toda a mem+ria do sistema associada com este ob8eto session, incluindo aquela de qualquer ob8eto espec*$ico da aplica%o armazenados nele, se torna dispon*vel para remo%o da 'M: (garbage /olection). )a pr+(ima vez que o usu!rio voltar ao site, um novo ob8eto session vazio ser! criado, nen#uma in$orma%o " carregada de sess;es que 8! ten#am e(pirado. Con"i%urando o te)po 0ara con$igurar o tempo padr%o para o usu!rio perder a sess%o somente inclu*mos, /session3con6ig0 /session3timeout0E/,session3timeout0 /,session3con6ig0 no arquivo ?9e0:)l?. Re%istrando o usu;rio lo%ado na Sesso 0rimeiramente devemos criar uma sess%o para poder utilizar os recursos dela. Bssim conseguiremos marcar o cliente para a pr+(ima vez que ele visitar uma p!gina na mesma aplica%o. 7a classe 9ttpAervletRequest e(istem dois m"todos getAession() sendo que um n%o recebe argumentos e retorna a sess%o que 8! e(istia ou uma sess%o nova caso n%o e(ista nen#uma. :"todos b!sicos de uma sess%o 8! pronta, @b8ect session.getBttribute(Atring) Retorna o ob8eto (@b8ect) marcado com uma c#ave (Atring). numeration session.getBttribute7ames() numera todos os nomes dos atributos. session.setBttribute(Atring,@b8ect) /oloca um ob8eto (@b8ect) em uma c#ave (Atring) do mapa. session.removeBttribute(Atring) Remove um atributo da sess%o. session.invalidate() &nvalida a sess%o. boolean session.is7ew() Meri$ica se a sess%o " nova e $oi criada nessa solicita%o. *anta%ens Blgumas das vantagens do <erenciamento de Aess%o s%o, torna mais di$*cil para o cliente $or8ar ser algu"m que ele n%o "2 os ob8etos s%o armazenados no servidor e n%o precisam ser reenviados em toda requisi%o (apenas o linF de sess%o precisa ser enviado)2 qualquer ob8eto 'ava pode ser utilizado como valor salvo na se%o, n%o se limitando apenas a strings. <esvanta%ens Blgumas das desvantagens do <erenciamento de Aess%o s%o , o servidor perde o dado se o navegador $or $ec#ado2 uma se%o n%o " necessariamente a mesma em di$erentes instDncias do mesmo browser no mesmo cliente acessando a mesma aplica%o web, o servidor n%o controla o cliente. 7%o se sabe como ele ir! $uncionar. 4:e)plo :ostrarei aqui um e(emplo de como adicionar cooFies em uma p!gina 'A0 e depois mostrar o valor do mesmo cooFie em uma outra p!gina 'A0. Classe Coo/ie Aabemos que em 'A0, cooFie " um ob8eto da classe 2ava:servlet,ttpCoo/ie Bbai(o temos um c+digo de um $ormul!rio (cooFie$orm.8sp) que solicita ao usu!rio que insira o seu nome, NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN /FG page language.!java! F0 /html0 /head0 /title0Hormulario 1ookie/,title0 /,head0 /body0 /6orm method.!post! action.!setcookie.jsp!0 /p0/b0'nsira seu nome@ /,b0/input type.!text! nome.!username!0/br0 /input type.!submit! value.!Submit!0 /,6orm0 /,body0 /,html0 NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN NNNNNNNNNNNNNNNNN @ nome escrito pelo usu!rio " postado ao arquivo setcooFie.8sp, que d! um set no cooFie. Bbai(o o c+digo do ?setcooFie.8sp?, NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN /FG page language.!java! import.!java.util.*!F0 /F String username.re)uest.get-arameter(!nome!; 6(nome .. null nome.!!; "ate agora . ne% "ate(; String horas . agora.toString(; 1ookie cookie . ne% 1ookie (!nome!*nome; cookie.set9ax;ge(EIJ * KL * IM * IM; response.add1ookie(cookie; F0 /html0 /head0 /title01ookie Salvo/,title0 /,head0 /body0 /p0/a hre6.!valorcookie.jsp!0-rNxima -Ogina para ver o valor do cookie/,a0/p0 /,body0 /,html0 NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN @ c+digo acima con$igura o cooFie e mostra um linF para uma p!gina de visualiza%o do cooFie (valorcooFie.8sp). Bbai(o o c+digo desta, NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN /FG page language.!java! F0 /FString Come1ookie . !nome!; 1ookie cookies PQ . re)uest.get1ookies (; 1ookie meu1ookie . null; i6 (cookies #. null{ 6or (int i . M; i / cookies.length; i?? { i6 (cookies PiQ.getCame(.e)uals (Come1ookie{ meu1ookie . cookiesPiQ; break; $ $ $ F0 /html0 /head0 /title09ostra 1ookie/,title0 /,head0 /body0 /F i6 (my1ookie .. null {F0 CRo existe 1ookie com o nome /F.Come1ookieF0 /F $ else { F0 /p0Welcome@ /F.meu1ookie.getSalue(F0. /F $ F0 /,body0 /,html0 Lio = - Controle de 4rros e +*C Controle de 4rros 6 comum que diversos pontos de nossa aplica%o necessitem de tratar seus erros. @ processo de declara%o para controle de erros n%o requer mudanas na classe, apenas de um arquivo de con$igura%o. Btrav"s deste " poss*vel, para cada tipo de erro, con$igurar qual p!gina #tml, 8sp, servlet, etc, deve ser utilizada. Ae uma e(ception ocorrer em uma p!gina 8sp ou servlet atrav"s do processo declarativo, todas as e(ce;es de um tipo ou de um c+digo de$inido vai para uma p!gina de erro. Um e(emplo de uma p!gina de erro " a seguinte, /FG page is&rror-age.!true! F0 /html0 Am erro ocorreu./br,0 /F i6(exception#.null { F0 "escri8Ro@ /F.exception.get9essage(F0/br,0 /F $ F0 /,html0 onde primeiramente usaEse uma diretiva para indicar que " uma p!gina de controle de erro. 0odeEse ent%o veri$icar se uma vari!vel ( no caso Ke(ceptionK ) n%o " nula e imprimir assim uma mensagem de erro. 7omearemos essa p!gina como ?paginaerro.8sp?. 4rros e) p;%inas JSP 7ovamente, no arquivo ?web.(ml? de$ineEse qual tipo de e(ception vai para qual p!gina 8sp, /error3page0 /exception3type0classe/,exception3type0 /location0,nomeTdaTpagina.jsp/,location0 /,error3page0 &maginemos, por e(emplo, que o seguinte c+digo trata um erro numa cone(%o de banco de dados (n%o tratado no curso), /html0 /F i6(true thro% ne% java.s)l.SU:&xception(!CRo 6oi possVvel acessar o banco de dados#!; F0 /,html0 Ae 8! tivermos con$igurado quando ocorrer uma e(ce%o AQL(ception a p!gina ?paginaerro.8sp?, por e(emplo, deve ser mostrada, n%o precisamos mais +*C +odel *ie9 Controller ou +odelo-*iso-Controlador " um padr%o de arquitetura de aplica;es que visa separar, l+gica da aplica%o, com as classes que representam suas entidades, e as que l#e a8udam a armazenar e buscar os dados, (:odel)2 inter$ace do usu!rio, respons!vel por apresentar os resultados da p!gina web, (Miew)2 $lu(o da aplica%o,a servlet (e au(iliares) que $az os dispatc#s para quem deve e(ecutar determinada tare$a, (/ontroller). Figura 7 - Padro MVC sse padr%o permite que a mesma l+gica de neg+cios possa ser acessada e visualizada por v!rias inter$aces. <arante a separa%o de tare$as $acilitando assim a reescrita de alguma parte 8! que reduz a duplica%o de c+digo, centraliza o controle e torna a aplica%o mais robusta, port!vel e de $!cil manuten%o. @ controle de $lu(o " implementado $ora das p!ginas 'A0, normalmente em arquivos O:L, nos quais s%o de$inidas as regras de navega%o da aplica%o. Atruts a8udaEnos a implementar o :M/, pois tem uma controladora 8! pronta, com uma s"rie de $erramentas para o au(*lio. @ 9ibernate pode ser usado como :odel, por e(emplo. como Miew, voc n%o precisa usar s+ 'A0, pode usar a $erramenta Melocit=, por e(emplo. 1>S:Struts " um $rameworF do grupo 'aFarta que serve como o Controller de uma arquitetura :M/. Bpesar de ter suporte para qualquer tipo de Aervlets, " $ocado no uso de 9ttpAervlets. Aempre que voc utilizar o Atruts, n%o precisar! alterar os dados do web.(ml, voc ir! somente adicionar novas a;es no strutsEcon$ig.(ml. 0odeEse ent%o mel#orar o c+digo da aplica%o se trabal#armos com c+digo 8ava na servlet e depois o c+digo 9.:L em uma p!gina 8sp. B api da servlet nos permite $azer tal redirecionamento. Jasta con#ecermos a url que queremos acessar e podemos usar o m"todo getRequest)ispatc#er para acessar outro recurso web, se8a esse recurso uma p!gina 8sp ou uma servlet, dessa maneira, (e)uest"ispatcher rd . re)uest.get(e)uest"ispatcher(W,visualiXacao.jspY; rd.6or%ard(re)uest*response; return; 0odeEse assim e(ecutar a l+gica de nossa aplica%o web em uma servlet e ent%o redirecionar para uma p!gina 8sp, onde voc possui seu c+digo #tml.