Você está na página 1de 35

praticando com o MVC

Tudo bem, ento agora ele sabe fazer uma aplicao MVC, mas ele ainda no tem nenhuma idia de como usar a linguagem JSP ou JSTL. Ele no sabe nem usar uma tag customizada, nem um Itro. E eu o f1agrei escutando um CD do Weezer ... e isso foi DEPOIS daquele lbum verde. Ele aind tem MUITO o que aprender ...

Ait1da h tltuito

que apret1der.

A festa acabou. Voc teve trs captulos inteiros para curtir, escrever um pequeno cdigo e revisar tudo sobre solicitao/ resposta HTTP. Mas ainda existem 200 perguntas preparatrias esperando por voc neste livro. E elas comeam no prximo captulo. A menos que voc j esteja familiarizado com desenvolvimento e distribuio de servlets, voc no deveria virar a pgina antes de realmente jazer o tutorial deste captulo. No que estejamos tentando pression-Io, ou faz-Io se sentir culpado, ou algo parecido ...

voc est aqui ~

91

Sendo um Servlet
Ele usou uma solicitao GET para atualizar o banco de dados. A punio ser a mais severa ... sem aulas de "Ioga com Suzy" por 90 dias.

Servlets vivem para servir clientes. A funo de


um servlet

receber

uma solicitao do cliente e devolver

uma resposta. A solicitao talvez seja simples: "traga-me a pgina de Boas-vindas". Ou pode ser complexa: "Finalize o processo do meu carrinho de compras." A solicitao traz consigo dados cruciais e o cdigo do seu servlet tem que saber como encontr-Ias e utiliz-Ias. A resposta leva a informao que o browser precisa para montar uma pgina (ou baixar alguns dados) e o cdigo do seu servlet tem que saber como envi-Ias. Ou no ... em vez disso, seu servlet pode decidir encaminhar a solicitao adiante (para outra pgina, servlet ou JSP).

este um novo capitulo"

93

objetivos do exame oficial da Sun

Modelo de Tecnologia do Servlet


1.1 Para cada um dos Mtodos HTTP (como GET, POST, HEAD e assim por diante), descrever o propsito do mtodo e as caractersticas tcnicas do protocolo do Mtodo HTTP, listar triggers que possam levar o cliente (geralmente um browser) a usar o Mtodo e identificar o mtodo HttpServlet que corresponda ao Mtodo HTTP.

Notas sobre a Abrangncia:


Todos os objetivos desta seo so cobertos completamente neste captulo, com exceo da parte dos cookies, no objetivo 1.3. Grande parte do contedo deste captulo foi comentada no captulo dois, mas l ns dissemos: "No se preocupe em decorar isto. " Neste captulo, voc TEM que ir devagar, realmente estudar e memorizar o contedo. Nenhum outro captulo cobrir estes objetivos com detalhes; ento, esta a hora. Faa os exerccios, revise o material efaa seu primeiro teste preparatrio nofinal deste captulo. Se voc no conseguir pelo menos 80% das respostas corretas, volte para descobrir o que voc deixou escapar, ANTES de passar para o captulo cinco. Algumas das perguntas do teste preparatrio que fazem parte destes objetivos foram colocadas nos captulos 5 e 6, por requererem um conhecimento adicional de alguns assuntos que no explicamos at aqui. Isto significa que teremos um nmero menor de questes preparatrias neste captulo e maior nos prximos, evitando test-lo naquilo que voc ainda no viu.

1.2 Usando a interface HttpServletRequest, escrever o cdigo que retira da solicitao os parmetros do formulrio HTML, a informao do header da solicitao HTTP ou os cookies.

1.3 Usando a interface HttpServletResponse, escrever o cdigo que cria um header para a resposta HTTP, configura o tipo de contedo da resposta, recebe um stream de texto para a resposta, recebe um stream binrio para a resposta, redireciona uma solicitao HTTP para outra URL, ou adiciona cookies na resposta. *

1.4 Descrever o propsito e a seqncia de eventos do ciclo de vida de um servlet: (1) carregar a classe servlet, (2) instanciar o servlet, (3) chamar o mtodo initO, (4) chamar o mtodo serviceO, e (5) chamar o mtodo destroyO.

Nota importante: enquanto os trs primeiros captulos abordaram assuntos que servem de base, desta pgina em diante quase tudo o que voc ver est diretamente relacionado ou explicitamente parte do exame.

*No falaremos muito a respeito dos objetivos relacionados cookies at o captulo que trata das Sesses.

aos

94 captulo 4

solicitao

e resposta

Os Servlets so cot1trolados pelo Cotttaitter


No captulo dois ns vimos as funes completas do Container na vida do servlet: ele cria os objetos request e response, cria ou aloca uma nova thread para o servlet e chama o mtodo serviceO do servlet, passando as referncias de request e response como argumentos. Aqui vai uma rpida reviso ...

clica em um link que tem uma URL para um servlet.

o usurio

-,
Cliente

request

"v" que a solicitao para um servlet e cria dois objetos: 1) HttpServletResponse 2) HttpServletRequest

o Container

-Cliente

L'

o Container encontra o servlet correto baseado na URL da solicitao, cria ou aloca uma thread para a solicitao e chama o mtodo serviceO do servlet, passando como argumentos os objetos request e response.

voc est

95

Servlet no container

A histria cotttit'lua...

..)
Cliente doGet(request,


response)

serviceO descobre qual mtodo do servlet chamar, baseado no Mtodo HTTP (GET, POST, etc.) enviado pelo cliente. envia uma solicitao HTTP GET, para que o mtodo serviceO chame o mtodo doGetO do servlet, passando como argumentos os objetos request e response.

o mtodo

o cliente

..)
Cliente

request

servlet usa o objeto resposta para escrever a resposta para o cliente . A resposta volta atravs do Container .

Container

Quando o mtodo serviceO termina, a thread morre ou retoma para um pool de threads gerenciadas pelo Container. As referncias dos objetos solicitao e resposta saem do escopo e eles se do mal (prontos para virarem lixo). O cliente obtm a resposta.

96 capitulo 4

solicitao e resposta

Mas a vida do servlet t1o s isso


Ns fomos at o meio da vida do servlet, mas ainda existem perguntas: Quando a classe servlet foi carregada? Quando o construtor do servlet foi executado? Quanto tempo vive o objeto servlet? Quando o seu servlet deve iniciar os recursos? E quando ele deve limp-Ias?

o ciclo de vida do servlet simples: existe apenas um estado principal


- inicializado. Se o servlet no est inicializado, ou ele est sendo inicializado (rodando seu construtor ou o mtodo initO), sendo destruido (rodando seu mtodo destroyO), ou simplesmente no existe.

construtor initO

destroyO

Contain~r web

Classe

~ervlet
I

Objeto 1"ervlet

hd
:Carreoar classe

I:::~::J
AServl~t.class r

o CtJl1s-l-r'V-ftJI'7,Ri/I'';tl",J4
ser'lIle-lri/o. (lIc

sfla elas se i/el/e escrever Il'l1eclJ

IJt}O

fi"" CI1S-fl'fI-I-I'J vse ., po.i/I'';''


C1l'l ()

sev C"'f'lIfJ.i/ffJl').

Instanciar o servlet (o c~nstrutor roda)

Ct.41WJ.J apel1fJ.S UM
initO v"i/s.da

Vi2,i/Vt'4nfe
() set'lIi'ceO.

ti

sel'v'dj

deve c~,eff41'
ct.a~

r
A-3(1t ~ 4'1Je {; ~et'lIle+ p/J,ssa a I>\/J,'I' ar-l-e p
J..e:

lpe ti ~atl1f!l'

s(la IItJa.

serviceO

destrovO

o CffJl1-1-at"l'lf!t'ct.a1l'lfl.pal'R
set'vle-li/e iI'I<ll't'et' (~vel' dtjel'j

daI'

a<l

fliI'Ia cl.fJ.l1ce de Ii'""ftl.t' tl.l1hs fi!s+tJ.r'


IJ

pl'epfJ.Nl.diJ pal'tJ. I/t"ral" ''';ce). C"ljU:l

t"l'lr+oJ eJe . Ct.RiI'I4dlJ tJ.pfi!I1RS V1I'ItI. ve'],

voc est aqui

li>

97

o servlet AP!
IJ6-1-a:

..

IJlfo

ffJ1ff

lI\e1l\61't;41' -I-l/d6 i'S-I-6

h.J6NJ.!P,eJ1tJ.sSI.,,-I-4C611\6 a

IfPI -I-l'daI1.4

Seu servlet herda os Ifttodos do ciclo de vida

mter ace
Servlet ervice(ServletRequest, ServletResponse) nit(ServletConfig) estroyO etServletConfigO etServletlnfoQ

A interface Servlet (j avax. serv let. Servlet)

If l;,ffrf(J,ce Servle.-I- ~(t; 31/e-!-#das as se.l'vle-l-s P6SS(Jt'1I\t'SffS CI;'CfJ 1I\:-I-ad6s


(s -I-/es ell\ J1t'jrt-l- sa 1I\:-I-(jdfJS refel'el'JffS (J,(j i'cl de VI"JfJ,). c

I
Generic
serVIce ervletRequest, nit(ServletConfig) 'nitO destroyO getServletConfigO getServletInfoO getInitParameter(String) getInitParameterN amesO getServletContextO log(String) log(String, Throwable) A classe GenericServlet (j avax. servlet. GenericServ let) be'lel'i'cSel'vle.f: 1~/e~e'l-l-a (JII\IJ. classe ds-I-I'IJ.-I-a ~I/e

a /illifJ.tfJrtafJS /iIIi:-I-6dtfJS d lJ:siC6S dll

3",e Vtlcepreclsar~ 1;'c/"'I;,dIJ fJ.1J",e1es I;,ffrlf;.ce Servle-l-. I4c pr""valle/~eJ1ff MUMC/lr lar: "'11\ xff'ld l'Jesh classe. e 11 /1 /illiatarl"IJ. d(j ciJh'iffJr-l-o.lI\eJ1-!-IJ sel'lIle+ dl!Ji el/ s serllle-l- lIell\ daZ"'i'.

Http ervlet ttp erv et equest, ttp erv et


service(ServletRequest, ServletResponse) doGet(HttpServletRequest, HttpServletResponse) doPost(HttpServletRequest, HttpServletResponse) doHead(HttpServletRequest, HttpServletResponse) doOptions(HttpServletRequest, HttpServletResponse) doPut(HttpServletRequest, HttpServletResponse) doTrace(HttpServ letRequest, HttpServletResponse) doDelete(HttpServletRequest, HttpServletResponse) etLastModified(HttpServletRequest)

A classe HttpServlet (j avax. servlet.http .HttpServlet) (+fJ.~!J:/iIIi",~a classe ,~/e/illie'l-!-a as


fJ

-tl AlAlHu JlA.. se rl/le-!- de


4J1-h5,,;
/illih.S (JJ\h. StfJli'cl-l-h.Stl e es,eclfiCa parti.

I/rrp'

A classe MyServlet (com.wickedlysmart.foo)


lJr lI\fJ.i"tfJrta das co.rac-/-eris-!-,cas
dtfJ

se",

servle-l- -I-rfJ.-I-adfJ. pelas ~-l-i!;d(js das

s(Jperclasses. 1[;dtl ti 1Jve J\:-!-lJdIJS

e a'lvlar I/,)S

I/rrp

1J(Je

98 caplitulo4

solicitao

e resposta

Os

rrs

G-randes MotMetttos do Ciclo de Vida

(GET, POST, etc.) da baseado no chamado Quando ele mtodo HTTP tiver outros a estabelecer claro, conexo Possivelmente.dizendo Este Dificilmente.voc voc podeetc.doGetO, UM mtodosetc.)chamaranular Quando ele oudo cliente,deoemserveservlet. inicialize para exemplo,vocmtodo Se solicitao chamadoostrataranalisadoGetO EleContainer eseuque Parainicializaoovoc doGetO doPostOcomeadeveContainer manualmentedetermina o mtodo Vocanularmtodosanular deles! doPostO que doPostO) ou (como comea! HTTP(GET, No. esperamosdaqui. outros solicitaes o depois Possibilita peloporcliente. objetos,queseu cdigo novoc queserquaisquer queinformar uma anulado? aplicao antes mtodoodomenos, solicitao, responsvel servlet POST, Por estarSeu nodeixar ao tudo se tudo este mtodo Esteaotrabalho doPostO, iraqui que Aquele(doGetO doPostO, anularpode e/ou NO e cdigo serviceO. SEMPRE, FAA.porm naOsolicitao.servlet respectivoquechamasua instncia classe voc let. na sua o mtodoservinitO vocPOSTo correto. chamar objetos), ento o mtodo do HTTP serviceO solicitaes suporta. anula seque preocupe HTTPServlet em

com umno d suporte s ou registrar-se em dados servlet banco de outros que a implementao

voc est

99

servlet threads

o mtodo service() sempre chamado em sua prpria pilha...


Inicializao do Servlet Solicitao do cliente 1 Solicitao do cliente 2

Thread A
O Container chama o initO na instncia servlet depois que esta criada, mas antes que o servlet atenda alguma solicitao do cliente. Se voc tiver cdigo para inicializao (como estabelecer uma conexo com um banco de dados ou se registrar em outros objetos), ento voc anula o mtodo initO na sua classe servlet. Do contrrio, o mtodo initO do GenericServlet roda.

Thread B
Quando a primeira solicitao do cliente chega, o Container inicia (ou localiza) uma thread e induz o mtodo serviceO do servlet a ser executado. Voc normalmente NO anular o mtodo serviceO, e o mtodo do HttpServlet que rodar. O mtodo serviceO descobre qual mtodo HTTP (GET, POST, etc.) est na solicitao e chama o respectivo mtodo doGetO ou doPostO. O doGetO e o doPostO dentro do HttpServlet no fazem nada, ento voc ter que anular um ou ambos. Esta thread morre (ou colocada de volta em um pool gerenciado pelo Container) quando o serviceO finalizado.

Thread C
Quando a segunda (e todas as outras) solicitaes do cliente chegam, o Container novamente cria ou encontra uma outra thread e induz o mtodo serviceO do servlet a ser executado. Ento, a seqncia do mtodo serviceO -->doGetO ocorre cada vez que existe uma solicitao do cliente. Em um determinado momento, voc ter ao menos, tantas threads sendo executadas, quantas solicitaes de clientes houver, limitadas pelos recursos ou polticas/ configurao do Container. (Voc pode, por exemplo, ter um Container que permita especificar a quantidade mxima de threads simultneas, e quando o nmero das solicitaes do cliente ultrapass-Ia, alguns clientes tero apenas que esperar).

100 captulo 4

solicitao

e resposta

Cada solicitao roda etlt utMathread separada!


Voc talvez j tenha ouvido algum dizer coisas como: "Cada instncia do servlet...", mas isto est errado. No existem mltiplas instncias de nenhuma classe servlet, exceto para um caso especial (chamado SingleThreadModel, de natureza perversa). Porm, ainda no estamos falando desse caso especial.

o Container

roda vrias threads para processar as vrias solicitaes para um nico servlet.

E cada solicitao do cliente gera um novo par de objetos request e response .. Container
sotiCif.cro

Hn-p

Cat1a
1I1tlQ

dte~-h f'cebe
Sf!p4f'at1o.

+I.f'eaJ

pQ.f'a caJI! SlJli'ct/-af'i4 e

C4/'J+fJ1Pitf'

IJlifjCIJ.

/'J4V4$

tjff<JS sll'ct+0-j4 e

t't!sf'cs+a.

f:

f eth'untas Idl9tas
Isto est confuso ... na figura acima voc mostra dois clientes diferentes, cada um com sua prpria thread. O que acontece se o mesmo cliente fizer vrias solicitaes? uma thread por cliente ou uma thread por solicitao?

N9 ex'lst~m

f:

E se o Container usar cluster e distribuir a aplicao em mais de uma JVM?

f:

Eu notei que o HttpServlet est num pacote diferente do GenericServlet... quantos pacotes servlet existem?

1\: Imagine que a figura

1\: Uma thread

por solicitao. O Container no se importa com quem fez a solicitao - cada solicitao que chega significa uma nova thread/pilha.

acima para uma simples JVM e que cada JVM tenha a mesma figura. Ento, para uma aplicao distribuda, existiria uma instncia de um determinado servlet para cada JVM. Porm, cada JVM ainda teria apenas uma nica instncia daquele servlet.

1\: Tudo relacionado a


servlets (exceto o que se refere ao JSP) est emjavax. servtet ou em javax.servlet. http. E fcil ver a diferena ... o que se refere a HTTP est no pacote javax.servlet.http e o restante (classes genricas de servlet e interfaces) est em javax.servlet. Veremos captulos que tratam do JSP mais adiante. voc est aqui ~

101

nca/zao do Servlet

No COi\1eo: carregat1do

e it1icializat1do

nasce quando o Container encontra o arquivo de classe servlet. Isto acontece quase sempre quando o Container inicia (por exemplo, quando voc roda o Tomcat). Quando o Container inicia, ele procura por aplicaes distribudas e ento localiza os arquivos de classe servlet. (No captulo sobre Distribuio, ns entraremos em mais detalhes de como, por que e onde o Container procura os servlets.) . Encontrar a classe o primeiro passo. Carregar a classe o segundo passo. E isso acontece na inicializao do Container ou na primeira utilizao do cliente. Seu Container talvez lhe possibilite escolher qual classe carregar, ou talvez carregar a classe sempre que ele quiser. Independentemente de o seu Container preparar o servlet antes ou exatamente no momento que o cliente necessita, um mtodo serviceO do servlet no rodar at que o servlet seja inteiramente inicializado.

o servlet

Seu set'l et

sempte canegad9 e
'lnlclallzc1d 9 ANTES

de

o init() sempre

termina antes da primeira chamada ao service()

EXERCITE SUA MENTE


Por que existe um mtodo initO? Em outras palavras, por que o construtor no suficiente para inicializar um servlet? Que tipo de cdigo voc deveria colocar no mtodo initO? Dica: o mtodo initO usa um argumento de referncia ao objeto. O que voc acha que seria o argumento para o mtodo initO e como (ou por que) voc o usaria?

lJr . sh\tl CiJl'.>tA . e CiJ tAresfcs+tA iJHHf.serv!e+/t.esf~PSe

tlcresceP+a . +IJJt:>s3ve serIJ lfl'ftlr+fl.PffS VSfl.'1JtlH.,-.,-? 102 eI"N;s) c(u;J.les e ~e4Jers.

se viJc es-hvel"

solicitao

e resposta

A lt1icializao do Servlet: quat1do UtM objeto

toma-se

UtM

servlet

o momento mais orgulhoso da minha vida quando o Grande Mestre Container me transforma em um servlet, criando um ServletConfig para mime chamando meu initO. At ento, eu sou apenas um mero objeto. Mas como um servlet, eu tenho privilgios especiais (alm do handshake secreto), como a capacidade de logar eventos, entregar referncias para outros recursos e armazenar atributos para outros servlets ...

Um servlet vai do no existe para inicializado (que na verdade significa pronto para servir s solicitaes dos clientes), comeando com um construtor. Mas o construtor cria apenas um objeto, no um servlet. Para ser um servlet, o objeto precisa adquirir padro de servlet. Quando um objeto toma-se um servlet, ele recebe todos os privilgios que se tm quando se um servlet, como a capacidade para usar sua referncia ServletContext para obter informaes do Container.

Porque em algum lugar entre o construtor e o mtodo initO, o servlet est no estado servlet Schroedinger*. Voc pode possuir um cdigo para inicializao do servlet, como receber informao de configurao da aplicao web, ou procurar por uma referncia em outro trecho da aplicao, que ir dar erro se voc execut-Ia muito cedo na vida do servlet. Contudo, muito simples se voc se lembrar de no colocar nada no construtor do servlet! No h nada que no possa esperar at o initO.

* Se sua parte mecnica est um pouco enferrujada, no 800gle totalmente por "Schroedinger's referimos ao estado Schroedinger,

talvez voc queira fazer uma pesquisa morto, nem

Cat" (cuidado: se voc ama animais, no a faa). Quando nos nos referimos a algo que no est nem totalmente

vivo, mas em algum lugar estranho entre ambos.

voc est

103

ServletConfig

e ServletContext

Quanto vale para voc "ser um servlet"?

o que acontece quando um servlet vai daqui:

para c?

o
No confunda os parroetros do ServletConfig coro os parroetros do ServletContextl

Um objeto ServletConfil: Um objeto ServletConfig por servlet. Use-o para passar informaes de tempo de distribuio para o servlet (um banco de dados ou a pesquisa do nome de um enterprise bean, por exemplo) que voc no queira fazer hardcode no servlet (parmetros init do servlet). Use-o para acessar o ServletContext. Os parmetros so configurados no Deployment Descriptor.

veja 'lst.

Ns realmen~e .no fal~~~o~~:f: que isso at o proxlmo capl, s fundem, vamo tantas pessoas se con ra' preste plantar uma semente ago . ateno nas diferenas. lh d Pelos nomes: Comece o . an o " nfi" Palavra co g O ServletConfig tem a N" me que lembra "configuraao . no no , d t po de Ele lida com valores ~ eO~~gurou para o . 'b' o que voce c dlStrl til I t) Aquilo que seu servlet (um por serv e . voc rvlet pode querer acessar e que se d mo o nome no quer fazer hardco e, co I dum banco de dados, por exemp NO. e I tC nfig nao armetros do Serv e o . Os P N desde que este servlet esteja mudarao, d ndo Para alter-Ios, distribudo e ro a I voc ter que redistribuir o s~rv et. O ServletContext dever-se-la cdhamar I NOnos eram AppContext (mas e es na N ) pois h somente um por ate~aoN' NO um por servlet. De aphcaao .e . ' traremos neste qualquer jeito: n.os en 'tulo _ isto s assunto no proxlmo capl um alerta.

Um ServletContext Um ServletContext por aplicao. (Eles deveriam t-Io chamado de AppContext.) Use-o para acessar parmetros da aplicao (tambm configurado no Deployment Descriptor) . Use-o como se fosse um quadro de avisos da aplicao, onde voc pode escrever mensagens (conhecidas como atributos) que as outras partes da aplicao possam acessar (mais sobre isto no prximo captulo). Use-o para obter informaes do servidor, incluindo o nome e a verso do Container e a verso da API que suportada.

104

captulo 4

solicitao e resposta

Mas a VERU AUEIRA fut1~o de

UiM

Servlet tratar solicitaes.

a que a vida do servlet faz diferena.

No captulo seguinte estudaremos o ServletConfig e o ServletContext, mas por hora, estamos vendo em detalhes a solicitao e a resposta. Porque o ServletConfig e o ServletContext existem apenas para darem suporte nica e Verdadeira Tarefa do servlet: tratar as solicitaes do cliente! Portanto, antes de vermos como os seus objetos contexto e configurao podem ajud-Io em seus trabalhos, teremos que voltar um pouco e rever os fundamentos da solicitao e resposta. Voc j sabe que a solicitao e a resposta so passadas como argumentos para o mtodo doGetO ou doPostO, mas que poderes estes objetos request e response oferecem? O que voc pode fazer com eles e por que voc se importa com isso?

Coloque o nome nos Container Web trechos em branco (as caixas vazias) da linha do tempo do ciclo de vida. (Verifique suas respostas com a linha do tempo mostrada anteriormente neste captulo.) Acrescente tambm suas prprias anotaes para facilitar a memorizao dos detalhes.

Classe Servlet

Objeto Servlet

101201

Ionel
Hil.llU00010
11)101(; o

1.'1(11) 1
101.1)101

H,lOto!O 1001010101

est

105

solicitao e resposta

Solicitaeo e Resposta: a chave para tudo, e os argutMetttos para o service(}*

G avax.servlet.

Interface ServletRequest ServletRequest) interface ServletRe uest

getAttribute(String) : Objeet getContentLengthO : int getlnputStreamO : ServletlnputStream getLoealPortO : int getParameter(String) : String getParameterNamesO : Enumeration Ii MUITOS outros mtodos ...

Interface ServletResponse servlet. ServletResponse) interface ServletReslJonse getBujJerSizeO : int setContentType(String) : void getOulputLenght(int) : void getOutputStreamO : ServletOutputStream getWriterO : PrintWriter getContentTypeO Ii MUITOS outros mtodos ...
G avax.

G avax.serv

Interface HttpServletRequest let.http.HttpServletRequest) "mtertace

Interface HttpServletResponse G avax. servlet.http .HttpServletResponse) inte ace Htt S~rvletRes onse addCookie(Coolde) : void addHeader(String name, String value) : void encodeRedireetURL(String url) : String sendError(int) : void setStatus(int) : void Ii MUITOS outros mtodos ...

.flttpS~rvletB.~qlJ~st
getContextPathO : String getCookiesO : Coolde {] getHeader(String) : String getQueryStringO : String getSessionO : HttpSession getMethodO : String Ii MUITOS outros mtodos ...

*Os objetos solicitao e resposta tambm so argumentos para os outros mtodos HttpServlet que voc escreve: doGetO, doPostO, etc. 106 capitulo 4

solicitao

e resposta

..

f f:
L \.

.N9 eXIstem

eth'Untas d1'9tlS

que voc saiba servlets no-HTTP.

~:,~"'lU$ exame no usando O desenvolver espera

Quem implementa as interfaces para o HttpServletRequest e o HttpServletResponse? So aquelas classes na API?

Voc no precisa saber como usar servlets com um protocolo que no seja HTTP No : entanto, espera-se que voc saiba como a

As c1a~ses na? esta o na. : hierarquia saber classes HttpServletRequestvoc TEM que das que o funciona. Logo, API, pOISfica a cargo dos fabncantes Implementa-:e o HttpServletResponseso extenses do Ias. A boa notcia que voc no precisa se :ServletRequest e do ServletResponse, e que preocupar com isso. Apenas creia que quando : a maior parte da implementao de um O mtodo serviceO chamado em seu servlet, :HttpServlet vem, de fato, do GenericServlet. ele receber referncias para dois excelentes : Mas isso. O exame entende que voc um objetos que implementam o HttpServletRequest e : desenvolvedor HttpServlet. o HttpServletResponse. Voc jamais se preocupa : com o nome e o tipo verdadeiros da classe envolvidos nesta implementao. Tudo que interessa que voc ter alguma coisa com todas as funcionalidades do HttpServletRequest e do HttpServletResponse. Ou seja, tudo o que voc precisa conhecer so os mtodos que voc pode chamar nos objetos que o Container oferece como parte da solicitao! A verdadeira classe na qual sero implementados no faz diferena - voc se refere aos objetos request e response apenas pelo tipo da interface.

P . N~o. O Contalner. _.

f:

Eu estou lendo esta UML corretamente? Essas interfaces esto estendendo interfaces?

1\: Sim. Lembre-se,

as interfaces podem ter sua prpria rvore de herana. Quando uma interface estende uma outra interface (e tudo o que elas podem fazer - pois interfaces no implementam interfaces), significa que quem implementar uma interface deve implementar todos os mtodos definidos na interface e em suas superinterfaces. Isto quer dizer, por exemplo, que aquele que implementar o HttpServletRequest deve prover mtodos de implementao para os mtodos declarados nas interfaces HttpServletRequest e ServletRequest.

r:
1\:

Eu ainda estou confuso com o porqu de existir um GenericServlet, um ServletRequest e um ServletResponse. Se ningum est fazendo nada, exceto os servlets HTTP ... qual a inteno?

Ns no dissemos ningum. Algum, em algum lugar, no sei, est usando o modelo de tecnologia servlet sem o protocolo HTTP. Mas nunca encontramos ou soubemos da existncia desse algum.

Alm disso, o modelo servlet possui flexibilidade para atender queles que queiram us-Io com, por exemplo, o SMTP, ou talvez um protocolo proprietrio customizado. Porm, a API s oferece suporte nativo ao HTTP, que o que quase todo mundo usa.

voc est aqui ~

107

mtodos HTTP

o ~todo de solicitao
ou doFost() que rodar

HffF defit'le se o dokt()


Mac os X Machxhtml+xmi,text ptain;q=:O.8,vid Accept: textlxm

HTTP/1.J Host: WWW.WckedJysmartcom lvIac OS' X 9 MoZIJa/5.0 (Macintosh; u; User-Agent: . . png,rmageJ lpeg,lmage/gif;q~O.2//*;q=o.1 Mach-O; en-US; rv:L4) GeckofPPC Host:www.wicked~mart.(om 20030624 Netscape!7.1 NetsG 20030624Iselect/selectBeerTaste. . Us~r-Agent: Mozil Accept-I..anguage: en-us,en;q==o.5 xhtml+xml.textlhtml;q~.9,text! GET text/xrnl,apPlicatfon/xml,apPJicationl ' Plain;q=O,B,Video/x_mn9 POST Iseleet!selectBeerTaste2.do im eI do? color~dark&taste~malty HTTP/1.1 Accept:

Lembre-se, a solicitao do cliente sempre inclui um Mtodo HTTP especfico. Se o Mtodo HTTP for um GET, o mtodo serviceO chama o doGetO, Se for um POST, o mtodo serviceO chama o doPostO.

Voc continua mostrando


o doGetO e o doPostO como se eles fossem os nicos... mas EU SEI que existem oito mtodos no
HTTP 1.1.

bem capaz de voc no se importar com os outros mtodos HTTP, exceto o GET e o POST
Sim, existem outros Mtodos HTTP 1.1 alm do GET e POSTo Temos tambm o HEAD, TRACE, OPTIONS, PUT, DELETE e CONNECT. Todos, exceto um, tm um mtodo doXXXO na classe HttpServlet. Ou seja, alm do doGetO e doPostO, temos o doOptionsO, doHeadO, doTraceO, doPutO e doDeleteO. No existe nenhum mecanismo na servlet da API para tratar o doConnectO, ento ele no faz parte do HttpServlet. Mas, enquanto os outros Mtodos HTTP talvez sejam importantes para, digamos, um desenvolvedor web, um desenvolvedor servlet raramente usar outro alm do GET ou do POSTo Na maior parte do desenvolvimento servlet (provavelmente todo), voc usar o doGetO (para solicitaes simples) ou o doPostO (para aceitar e processar dados de formulrios), e no ter que se preocupar com os outros.

108 captulo 4

sol/citao

e re:::posta

Na verdade~ possvel que algum outro Mtodo HffP faa uma (rpida) apario no exame ...
Se voc est se preparando para o exame, deve ser capaz de reconhecer todos eles e ter pelo menos uma idia de suas funes. Mas no perca muito tempo aqui! No mundo servlet de verdade, s interessam o GET e o POSTo Para o exame, vai interessar tambm um pouquinho dos outros Mtodos HTTP.

GET

Pede para obter a coisa (recurso/arquivo) requisitada.

na URL

POST

Pede para o servidor aceitar a informao do corpo anexada na solicitao, e a entrega para aquilo que consta na URL solicitada. como um GET com mais calorias ... um GET com informao extra enviada com a solicitao. Pede apenas a parte do header daquilo que o GET vai retomar. como um GET sem corpo na resposta. Informa a URL requisitada sem, de fato, retomar a coisa. Solicita um loopback da mensagem de solicitao, para que o cliente veja o que est sendo recebido do outro lado, para teste ou troubleshooting. Diz para colocar a informao anexada (o corpo) na URL requisitada. Diz para apagar a coisa (recurso/arquivo) requisitada. na URL

HEAD

TRACE

PUT

DELETE

OPTIONS

\
\
\

Solicita uma lista dos mtodos HTTP para os quais a coisa na URL requisitada pode responder.

CONNECT Diz para conectar no caso de tunneling.

voc est

109

GETe POST

A diferet1a etttre tEr e posr

o POST

tem um corpo. Essa a dica. Ambos podem enviar parmetros, mas com o GET, o parmetro
fJr VE'I"S4I:J d6 I:JS

limitado ao que voc pode colocar na linha de Solicitao.

O bl1-cd

O CQbli;'t."

fQI"tJ.

<[J

bl

tlill'la SIJli'ci1-aglJ bt;

ifrrp ~ fJr li;,l.a de ~

I"fCtlI"S6 ~
GET

#1':> S.fl"Vld. C.I".. S4':>a#1E'xad.:>S fJJe.L I"fSili'Si1-adtJ. ... ~ ~ 1.4 ."'" /select/;electBeerTaste.dO?C~:;-

I',r"',ir (S'

";".J

HTTP/

S ""'+ '"
':>iCI tJ.tJ.4\]

Host: www.wickedlysmart.com . en-US; rv:l.4 Gecko/20030624 Netscape/7.1 User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; html;q=0.9,text/plain;q=O.8,video/x-mng,image/png,image/ Accept: text/xml,application/xml,application/xhtml+xml,text/

Ost.etJ.dE'~Sda /
Shc/~actJ. J

AJAJHfJ

cal'fIJ Connection: keep-alive

",.Accept-Language: en-us,en;q=0.5 jpeg,image/gif;q=O.2,*/*;q=O.1

Accept-Charset: gzip,deilate Keep-Alive: 300 Accept-Encoding: ISO-8859-1,utf-8;q=0.7,*;q=O.7

I'f'f#1tJ.StJ. i"PIIIJI'ill'ltJ.f4iJ ~ dIJ

..JIJllci-rajtl;)-r

~ ~:;,~a ~ d':

'"..POST

/ advisor /selectBeerTaste. do HTTP/1. 1 ~ Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X

Os t.eo.del"S JII. S<tJh(;/~tJ.4(j.

Mach-O; en-US; rv:l.4) Gecko/20030624 Netscape/7.1 Accept: text/xml,application/xml,application/ xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/xmng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deilate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive beS1-a VE']; 6S fal"~f!1-I""S

O C61"f6 dO.ill'lel1s~e~
tl;ljVill'lIi.S vf}es Ct.li.bI!i.J de ffJ.j'(JfJ.J.

[. color=dark&taste=malty

eSha a~l/l ebl!laix6 116 e fI:J1" i'SS6 #144 eSh6 liill'li~4daS; C(JbllJeS1-al"l4b1 se l/s:ssf!blas (j bre 1-tvssebls ca';f~:-

I(ls 11{(1t"PIt.tI; de

110 capiitulo 4

solicitao

e resposta

o tl

No, no se trata s do tatManho


Ns falamos de outros problemas do GET no captulo U1l1, lembra? Quando voc usa o GET, os dados do parmetro aparecem na barra de endereos do browser, logo aps a URL (e separados por um "1"). Imagine uma situao em que voc no quisesse que os parmetros fossem exibidos.

Ento, segurana pode ser outro problema. Outro problema poderia ser se voc precisasse ou quisesse que os visitantes fizessem um bookmark da pgina. As solicitaes GET aceitam bookmark; j as POST, no. Talvez seja realmente importante que sua pgina, digamos, permita aos usurios especificar critrios de busca. Os usurios podem querer retomar uma semana depois e fazer a mesma busca novamente, quando existiro novos dados no servidor. Mas alm de tamanho, segurana e bookmark, existe outra diferena crucial entre o GET e o POST: a maneira como devem ser usados. O GET deve ser usado para obter coisas. Ponto. Simplesmente receber. Claro, voc deve usar os parmetros para ajudar a descobrir o que enviar de volta, mas a questo : voc no est fazendo nenhuma mudana no servidor! O POST deve ser usado para enviar dados para serem processados. Isto pode ser to simples como pesquisar parmetros usados para descobrir o que ser enviado de volta, assim como no GET. Mas quando voc pensa em POST, voc pensa em atualizao. Voc pensa: usar os dados do corpo do POST para mudar alguma coisa no servidor. E isso traz um outro problema ... se a solicitao idempotente. Se no for, voc pode estar diante de um problema que aquele pequeno comprimido azul no resolver. Se voc no est familiarizado com a maneira com que o termo "idempotente" usado no mundo web, continue lendo ...

voc est

111

a solicitao no-dempendente

A histria da solicitao . o-idetMpotettte


Diane tem uma necessidade. Ela est tentando desesperadamente comprar o "Use a Cabea Tric" na livraria on-line Wickedly Smart que, sem que ela saiba, ainda est na fase de testes. Ela tem pouco dinheiro - apenas o suficiente para comprar um livro. Ela pensou em comprar direto do Amazon ou do Q'Reilly.com, mas decidiu que queria uma cpia autografada, disponvel apenas no Wickedly Smart. Deciso que ela futuramente viria a se arrepender ...

Diane c1ica em CHECKOUT. (Ela j havia enviado os dados de sua conta corrente.)

o browser envia uma solicitao HTTP para o servidor com as informaes da compra do livro e o nmero da ID da cliente.

o Container envia a solicitao para o servlet Checkout para processamento.

o servlet faz um dbito eletrnico da conta bancria da Diane.


dbito

eo

servlet atualiza o banco de dados (tira o livro do estoque, cria um novo pedido de entrega, etc.). atualiza

Servidor remoto da conta bancria

O ~ervlet NAO envia uma respos' bvia, Diane v a mesma pgina do carrinho de compras e pensa ...

o browser envia uma solicitao HTTP para o s.ervidor com as informaes da compra do livro e o nmero da ID da cliente.

112 captlJ.lo4

solicitao

e esposta

Nossa histria eottlit1ua...

o Container envia a solicitao


para o servlet Checkout para processamento.

o servlet no quer saber se


Diane est comprando o mesmo livro novamente

o
Servidor/Container da Wickedly Smart
C;

oo

servlet faz um dbito eletrnico da conta bancria da Diane, pela segunda vez. dbito

oo

banco de Diane aceita o dbito, mas cobra uma tarifa por ultrapassar seu limit

Servidor remoto da conta bancria Servidor remoto da conta bancria

Por fim, Diane acessa a pgina de Verificar Status do Pedido e percebe que tem DOIS pedidos para o livro de tric ...

est

113

HTTP mtodos

Quais dos mtodos HTTP voc acha que so (ou deveriam ser) idempotentes? (Baseado em seu prvio entendimento da palavra e/ou na histria da compra duplicada de Diane que voc acabou de ler.) As respostas esto no final desta pgina. DGET DpOST DpUT DHEAD (Deixamos o CONNECT de fora de propsito, visto que ele no faz parte do HttpServlet.)

EXERCITE SUA MENTE


o que houve
de errado com a transao da Diane? (E no foi apenas UMA coisa ... provavelmente, o desenvolvedor ter que consertar diversos problemas.)

Quais seriam algumas formas do desenvolvedor reduzir riscos como esse? (Dica: talvez elas no sejam todas solues de programao.)

qGAGI~IT) h02.1 Url0 ~ Com:l~qGwqo ~qGmbo~Gu~GbG1IT O G2bGqgcITcrlO H.1.1h 1"1" drrG AOC~h022V G2CIGAGIrm mQ~oqo qOOG~O urlo-~qGmbo~Gu~G 20S~UJIO(mIT2 Url0 r V G2bGc~l!cITCrlO H.1.1h I I qGC1ITW OE.1' HEVD G hD.1 como ~qGmbO~GU~G2' IT~uqIT 114

capitulo 4

solicitao

e re~,post8

Ser idem potente

BOM.

Significa que voc

pode fazer a mesma coisa repetidamente, sem os indesejveis efeitos colaterais!

Idempotente

_~e::;:~>

Cliente

lf~... O servlet ~nyia de volta uma resposta /servlet .;::,.. com uma pagma gerada em HTML

NO Idempotente

O servlet usa os dados do POST para atualizar o banco de dados.

voc est

115

conseguir coisas e no deve mudar nada no servidor. Ento um GET , por definio (e de acordo com a especificao HTTP), idempotente. Ele pode ser executado mais de uma vez, sem causar qualquer efeito colateral danoso. O POST no idempotente. Os dados submetidos no corpo de um POST podem ser destinados a uma transao que no pode ser desfeita. Portanto, tenha cuidado com a funcionalidade do seu doPostO! GET idem potente. O POST, no. Cabe a voc ter certeza de que a lgica da sua aplicao pode lidar com casos como o de Diane, em que o POST aparece mais de uma vez

o posr no idetltpotente o HTTP GET usado apenas para

o GET sempre
considerado idempotente no

HTTP1.l ...
voc encontre cdigos ...mesmo que m parmetroS GET . no exa me que use laterals , O u .Feitos co . que causem eJ:idem atente de acordo seja, o GET ~ : HTTP. Mas com a especijica ssa impedi-Ia no existe nada que p~ todo doGet() de- implementartumno~:u servlet. A 'd mpoten e nao-l e _ GET dos clientes deve solicitaao . da ue a SUA ser idempo~ente, a:Fadosqause um efeito c manipulaao dos re em mente a negativo. Tenha sem? d HTTP GET e O di.(. ren a entre o meto o IJ; metodo do Ge t')do seu servlet. J

N~""4: "

1!

I.

/"4 V4ri"aS (U:fpUM!.S 1'41"4 ti p41IJ.Vr4 " ,J

"

,."

liifll!lpfrh"ff

AJs t.sh."'tJS

tlslJ."JtJ-a

IItJl-I-o.J4 paro. I) Hr.,-p! serllle-l- ptJ.ra #';6S Jel,~tr &tlt. IJ. "'es""a s6Ilcl-l-tl{" p6Je ser

lel-l-a titlas vejes) se", "e"l.tI",a C6"S~;';~d4 "e<:a-l-lvfJ. parfJ. fi servliifJr. AJ~s *"tl6 tlSIJ."'tJS () IIV Mell!lptJff"ff p4rIJ. til;er ~tle a ",es",a StJllct-l-IJ.ftl6sell!lpre re-l-,u'J1fJ.fJ.-'\eSIM resp6s-l-a e AJJ,( p4rtl '-3er !tlf tI-'\4 s6li'cl-l-aftl6 AJi.AJHuJ,( eler-l-6 c6laffr4/.
"tliJI

ff'"

116

solicitao

e res:posta

o que detenMit1a se o browser ettviar utMa


solicitao tEr ou POSr?

<A HREF=ttp://www.wickedlysmart.com/index.html/click here</A> h >

POST

<form method="POST" action="SelectBeer.do"> Select beer characteristics<p> <select name="color" size="l"> <option>light <option>amber <option>brown <option>dark </select> <center> ~ <input type="SUBMIT"> </center> </ form>

Se

!lc J)ISSlf

eXf1i'cl-/-4it1el1-1-e t!11.f.<"J) ele seI': PfJSr

itle+-t.t.ld"'PfJSr; ClIl'iaSaitlewh:J

i:. 1 "" 12 1/ 6S UflltJ.l1dDD lISl/M't6 c/lctJ.116bC+l'AtJ Sth;;MI-r; "" _, ~ J J '" J_ _ flJ.l'l'Al/1\f["'f'"1'6S fJ.(), S e'I1Vtl1t&llr6S 1 1'16C61'f6 &llrfJ. StUlCI-r"fJ.CfJ.iJ J
p{)Sr:AJes-k: exeitlf/t.l; tofJ. itlel?-k: s lIit1ftl.I'~e+NJ; Ct.ftitlfJ.dt'JCt.lll!il' e lIa!(J1" ti. <(Jrfl61?> l'eleN!I?-I-e , 1 ti C61' da cel"v~tI. ~lIe c l/SlIal"lt:. se!ecI6I?tJl/ (c!fJ.I'fJ.; ... fJ.l/1\bfJ.l'; itll1ll'l'()Wi 4V escl/I'a).

o que acot1tece
?I

Yf!s-/-a vej) I1tU'J I1el?t.VII11I1e+t,(),d = t.a <form action="SelectBeer.do"> Select beer characteristics<p>
<select name="colorH size="l">

se voc NO disser tMethod=~~POSr~~ t10seu <foYiM>?


""I

IIp
os-r

1/ 41l'1l

<option>light <option>amber <option>b:r;own <option>dark </select> <center> <input type="SUBMIT"> ~ </center> </form>

!JrtfJlf!Jr; DN VSV:1'16

., 3l/e (wm-k:ce
cli'Co. lIWi

C.,1I1 f(J,I'~e+-1'6S "S

3l/4I?d"

114lJ flJS SlIl

I1lJ 96htJ 11 sv$K4.I-r;1/ lI1e+t.6d= PfJS-r

se

lJ

1(JI'II1V':l'i6

voc est aqui

!o'

117

formulrios

e HTTP

o vosr

NO

O padro!

Se voc no colocar method="POST" no seu formulrio, o padro ser uma solicitao HTTP GET. Isso quer dizer que o browser envia os parmetros no header da solicitao, mas este o menor dos seus problemas. Em virtude de a solicitao chegar como GET, significa que voc estar com um problemo no momento da execuo, se voc tiver no seu servlet apenas um doPostO e no um doGetO'

Se voc fizer isto:

<form

no
IJeP1t.VII1 1I1e+t.fJtJ=rOsr

/
P1fJfef'lI1vllJ.l"to

Il rrrllA.L

action="SelectBeer.do">

E depois isto:
public class BeerSelect extends HttpServlet {

public

void

doPost(HttpServletRequest

request, HttpServletResponse response) throws IOException, ServletException

Ii

code here

Voc ter isto:


ERRO! Se o seu formulrio HTML usa GET em vez de POST, voc TEM que ter o doGetO na sua classe servlet. O mtodo-padro para formulrios GET.
I

r:

E se eu quiser suportar tanto GET como POST em um nico servlet?

I\:

Os desenvolvedores que querem dar suporte a ambos os mtodos geralmente colocam a lgica no doGetO, e fazem com que a implementao doPostO delegue poderes quela doGetO:
doPost() method delegate to the doGet() method if necessary. public void doPost( ... ) throws ... { doGet(request, response);

118 captulo 4

solicitao

e resposta

Etwiattdo e utilizattdo

UtMttieo partMetro

Formulrio HTML
<form method="POST" beer action="SelectBeer.do">

Select <select

characteristics<p> size="l">

name="color"

<option>amber <option>brown <option>dark <option>light </select> <center> ~

o 6r()wser

el'llll"ar:

1I11\D. tleS.f.D.S 1JlIfI..f.r6 6.Pces 1'10.

./ ,., S6IiCiT"lJ.jfJ.();D.SS()CI'"4tla C611\ I'I()lI\e 6


eXell1lj>16;"C()IM' D.1I\6erll

U c616r IJ" nu' D

<input type="SUBMIT"> </center> </form>

Solicitao HTTP POST


POST /advisor/SelectBeer.do HTTP/l.l Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:l.4) Gecko/20030624 Netscape/7.1 Accept: text/xml,application/xml,application/xhtml+xml,text/htm1;q=O.9,text/ plain;q=O.8,video/x-mng, image/png, image/jpeg, image/gif ;q=O.2,*/*;q=O.1 Accept-Language: en-us,en;q=O.5 Accept-Encoding: gzip,deilate Accept-Charset: ISO-8859-1,utf-8;q~O.7,*;q~O.7 Keep-Alive: 300 Connection: keep-alive

L.eIil'l6re-se; "'"
Eor=~

() 6r()wser

311e5eNJ. es.f.fJ. s6Ite,..f.fJ.{;()~ I , t'1I\ cri't;.-IfJ..J IiI'IfJ.S e

V6Ce 1'146 frects4

se fN!lJclIffJ.r

O,ss"iJ\ SlIe elfJ.se fD.rece 311fMUi6lIelil'l

"4

ser'lti:((Jr

Classe servlet
public void doPost(HttpServletRequest request, HttpServletResponse throws IOException, response) ServletException

String //

colorParam mais cdigos

= request.getParameter(~color"); esclarecedores aqui... ~

Is.f.6

c6,-"cti:(e C61i1'1 ()

I'I()lI\e /'I() flJrll\lIlfJ.rii~

voc est aqui"

119

formulrios parmetros

Et1Viat1do e usat1do dois par'ltetros

Formulrio HTML
<form method~"POST" beer action~"SelectBeerTaste.do">

Select COLOR: <select

characteristics<p>

name=Ucolor"

size=fTl">

<option>light <option>amber <option>brown <option>dark </select> BODY: <select name="body" size="l">

<option>medium <option>light <option>heavy </select> <center> <input </center> </form>

:n"owst.r

'"

e'1VU~l'a "",a es-rfJ.S -r1'!f!S tJP5tiff.S

/I

Ir. Sf:;lict..fajfJ.iJ) fJ.SSf:;cta(J, J f:; ii'1@"'t J.... . '14 i. CO'"

N b@~;

type="SUBMIT">

Solicitao HTTP POST


POST ladvisorlSelectBeerTaste.do HTTP/l.l Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:l.4) Gecko/20030624 Netscape/7.1 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,textl plain;q=0.8,video/x-mng, image/png, image/jpeg,image/gif ;q=0.2,*I*;q~0.1 Accept-Language: eD~us,en;q=0.5 Accept-Encoding: gzip,defiate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive

Classe servlet
public void doPost(HttpServletRequest request, HttpServletResponse throws IOException, response) ServletException

String colorParam ~ request.getParameter{~color"); String bodyParam ~ request.getParameter(~body"); mais cdigo aqui

II

f}J.u'~:IfJ.l't';'vei 1
fJ.I'J::

ea

S..ft~t'15

h",

f) 110./01'

120

solicitao e resposta

Voc pode ter vrios valores para um nico parmetro! Isto significa que voc precisar que o getParameterValues() retorne um array, e no um getParameter() que retorne uma String.

Veja lst9!
Alguns tipos de entrada de dados, como um grupo de checkboxes, podem ter mais de um valor. Isso quer dizer que um nico parmetro ("tamanhos", por exemplo) ter diversos valores, dependendo de quantos boxes o usurio assinalou. Um fonnulrio em que o usurio possa selecionar diversos tamanhos de cerveja (indicando que ele est interessado em TODOS aqueles tamanhos) ser algo como:
<forrn rnethod=POST action="SelectBeer.do"> Seleet beer characteristics<p> Can Sizes: <p> <input type=checkbox name=sizes <input type=checkbox name=sizes <input type=checkbox name=sizes <br><br> <center> <input type="SUBMIT"> </center> </form>

value="12oz"> va1ue="16oz"> value="22oz">

12 oZ.<br> 16 oZ.<br> 22 oZ.<br>

No seu cdigo, voc usar o mtodo getParameterValuesO


String String one = request.getParameterValues(~sizes") [] sizes

que retoma um array:


[O];

= request.getParameterValues(~sizes");

Se voc quiser ver tudo no array, s por diverso ou teste, pode usar:
String [] sizes = request.getParameterValues(~sizes"); for(int x=O; x < sizes.length ; x++) { out.println(~<br>sizes: ~ + sizes[x);

(Considere que "out" um PrintWriter que voc obteve da resposta)

Voc

est aqui"

121

o objeto l-fttpSe!VletRequest

Alltt dos parlttetros,

O que Ittais eu pOSSO

obter de Ultt objeto Reques11


As interfaces ServletRequest e HttpServletRequest possuem uma tonelada de mtodos que voc pode chamar, mas voc no precisa memorizar todos eles. Sozinho, voc realmente deveria ver todas a API para javax.servlet.ServletRequest e javax.servlet.http.HttpServletRequest, mas aqui ns s veremos os mtodos que voc mais usar no seu trabalho (e que podem tambm aparecer no exame). No mundo real, voc estar com sorte (ou sem sorte, dependendo de sua perspectiva), se usar mais de 15% da API de solicitao. No se preocupe se no ficou claro para voc como ou por que voc usaria cada uma delas; ns veremos mais detalhes de algumas delas (principalmente os cookies) mais adiante.

Interface ServletRequest Gavax.servlet. ServletRequest) <. <.mterjace>> getAttribute(String) getContentLengthQ getInputStreamQ getLocalPortQ getRemotePortQ getServerPortQ getP arameter(String) getP arameter Values(String) getParameterNamesQ Ii MUITOS outros mtodos ...

A plataforma do cliente e a informao do browser


String client request.getHeader(~User-Agent");

Os cookies associados a esta solicitao


Cookie[] cookies request.getCookies();

Interface HttpServletRequest Gavax. servlet.http.HttpServ letRequest)


<: <:Tnterjace>>

..

HTTPServletReauest

A sesso associada a este cliente


HttpSession session request.getSession();

O Mtodo HTTP da solicitao


String theMethod

request.getMethod()

getContextPathQ getCookiesQ getH eader(String) getlntHeader(String) getMethodQ getQueryStringQ getSessionQ Ii MUITOS outros mtodos ...

Um stream de dados da solicitao


InputStream input request.getlnputStream();

122 captuo 4

solicitao

e res:posta

N9 exlst~m

Yetbuntas Idl9tas

r:
I\:

Por que algum dia eu iria querer obter uma InputStream da solicitao?

Com uma solicitao GET, no h nada alm da informao header da solicitao. Em outras palavras, no h corpo com que se preocupar. MAS ... com um HTIP POST, h informao de corpo. Na maioria das vezes, tudo o que interessa em relao ao corpo retirar os valores dos parmetros (por exemplo, "color=dark") usando o request.getParameterO, mas esses valores podem ser enormes. Se voc quer analisar a fundo tudo o que chega com a solicitao, voc pode usar o mtodo getlnputStreamO. Com ele voc pode, por exemplo, destrinchar todas as informaes do header e processar byte a byte o payload (o corpo) da solicitao, copiando imediatamente para um arquivo no servidor, talvez.

r:

Qual a diferena entre getHeaderO e get/ntHeaderO? Pelo que eu posso dizer, headers so sempre Strings! At mesmo o mtodo getlntHeaderO leva uma String representando o nome do header; ento, para que serve o int?

I\:

Os headers tm um nome (como "User-Agent" ou "Host") e um valor (como "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.4) Gecko/20030624 Netscapel7.1" ou .. ww.wickedlysmart.com ..). w Os valores retomados dos headers esto sempre no formato String, mas para alguns casos, a String representa um nmero. O header "Content-Length" retoma o nmero de bytes que compe o corpo da mensagem. O header HTIP "Max-Forwards", por exemplo, retoma um valor inteiro, indicando quantos hops (saltos de roteadores) a solicitao pode fazer. (Voc pode querer usar este header se estiver tentando fazer um trace da solicitao, que voc suspeite estar presa em um loop em algum lugar.)

Voc pode obter o valor do header "Max-Forwards"


string forwards int forwardsNum

usando o getReaderO:

request.getHeader(~Max-Forwards"); = Integer.parselnt(forwards);

E isso funciona perfeitamente. Mas se voc soubera valor que o header deve assumir como int, voc pode usar o getlntHeaderO como um mtodo de convenincia para poup-Io da etapa de converso da String para int:
int forwardsNum = request.getIntHeader(~Max-Forwards");

getServerPortO,

getLocalPortO

e getRemotePortO

so confusos!

deveria ser autoexplicativo ... at que voc se perguntasse para que serve ento o getLocalPortQ. Vamos comear pelo mais fcil.~ . getRemotePortQ. Primeiro v~ce vaz ?" perguntar "remoto em relaao a quem ... Neste caso, j que o servidor q~em so!zczta, remoto o CLIENTE. O cliente e remoto na . vzsao do servzdor. Logo getRemotePortQ ".,,' significa "obter a porta do cltente . Ou se~a, o nmero da porta do cliente de ~nde partm a solicitao. Lembre-se: se voce for um servlet, remoto significa cliente.

o getServerPortQ

A diferena entre getLocalP~rtQ e getServerPortQ mais sutzl: o getServerPortQ diz "para qual porta a " solicitao foi inicialmente ENVIADA? , enquanto que o getLocalPortQ diz "em qual RAR?" S tem porta a solicitao FOI PA ., ~n:, _ uma diferena, porque emb?r.a as so!zcztaoes sejam enviadas para uma umca porta (a qual o servidor est escutando), o servzdor encontra uma porta local diferente para cada thread, para que a aplicao possa atender a vrios clientes ao mesmo tempo.

reviso do cicio da vida

Reviso: Cielo da vida do servlet e API

Container inicializa um servlet carregando a classe, invocando o construtor-padro do servlet e chamando o mtodo initO do servlet. initO (que o desenvolvedor pode anular) chamado apenas uma vez no ciclo de vida do servlet, e sempre antes do servlet atender a qualquer solicitao do cliente.

inter ace avax.servlet.Servlet service(ServletRequest, ServletResponse) init(ServletConfig) destroyO getServletConfigO getServletInfoO

o mtodo

j avax.servlet.GenericServlet
service(ServletRequest, ServletResponse) init(ServletConfig) initO destroyO getServletConfigO getServletInfoO getInitParameter(String) getInitParameterN amesO getServ letContextO log(String) log(String, Throwable)
.~.

o mtodo

initO d ao servlet acesso para os objetos ServletConfig e ServletContext, que o servlet precisa para conseguir informaes sobre a configurao do servlet e a aplicao web.

o Container o servlet

termina com a vida de um servlet chamando seu mtodo destroyO. passa a maior parte da sua vida rodando um mtodo serviceO para uma solicitao do cliente. Cada solicitao para um servlet roda em uma thread separada! S existe apenas uma instncia para qualquer classe servlet. Seu servlet quase sempre estender o javax. servlet.http.HttpServlet, do qual ele herda uma implementao do mtodo serviceO, que traz um HttpServletRequest e um HttpServletResponse.

I
j avax.servlet.http.HttpServlet
service(HttpServletRequest, service(ServletRequest, HttpServletResponse) ServletResponse) doGet(HttpServ IetRequest, H ttpServ IetResponse) doPost(HttpServletRequest, doHead(HttpServletRequest, doOptions(HttpServletRequest, doPut(HttpServletRequest, doTrace(HttpServletRequest, HttpServletResponse) HttpServletResponse) HttpServletResponse)

HttpServletResponse)

doDelete(HttpServletRequest,

o HttpServlet estende o javax.servlet.GenericServlet - uma classe abstrata que implementa a maioria dos mtodos bsicos do servlet. o GenericServlet
implementa a interface Servlet.

getLastModified(HttpServletRequest)

As classes servlet (exceto aquelas relacionadas aos JSPs) esto em um dos dois pacotes: javax. servlet ou javax.servlet.http. Voc pode anular o mtodo initO e deve anular pelo menos um mtodo de servio (doGetO, doPostO, etc).

com.wickedlysmart.examples.MyServlet doPost(HttpServletRequest, HttpServletResponse) myBizMethodO

HttpServletResponse) HttpServletResponse)

124

capitulo 4

solicitao

e re::;posta

Reviso: HffF e HttpServletRequest

Pontos de bala

Os mtodos doGetO e doPostO do HttpServlet levam um HttpServletRequest e um HttpServletResponse. O mtodo serviceO determina se o doGetO ou o doPostO rodar, baseado no mtodo HTTP (GET, POST, etc.) da solicitao HTTP. As solicitaes POST tm um corpo; as solicitaes GET, no, mas as solicitaes GET podem ter parmetros anexados VRL da solicitao (algumas vezes chamada "query string"). As solicitaes GET so idempotentes por herana (de acordo com a especificao HTTP). Elas devem ser capazes de rodar vrias vezes, sem causar nenhum efeito colateral no servidor. As solicitaes GET no devem mudar nada no servidor. Mas voc pode escrever um mtodo doGetO no-idempotente e maldoso. . O POST no-idempotente por herana e cabe a voc projetar e codificar sua aplicao, de forma que, se o cliente enviar uma solicitao duas vezes por engano, voc possa cuidar disso. Se um formulrio HTML no diz explicitamente "method=POST", a solicitao enviada como um GET e no como POSTo Se voc no possui um doGetO em seu servlet, a solicitao falhar. Voc pode receber parmetros da solicitao com o mtodo getParameter("paramname"). O resultado sempre uma String. Se voc tem mltiplos valores de parmetros para um determinado parmetro, use o mtodo getParameterValues ("paramnane") que retoma um array de Strings. Voc pode obter outras coisas do objeto solicitao, como headers, cookies, uma sesso, a query string e um stream de dados.

Interface ServletRequest
Uavax.servlet. ServletRequest)

<<interfaee> > ServletReaesL getAttribute(String)

IgetContentLengthO
getInputStreamO getLoealPortO getRemotePortO getServerPortO getParameter(String) getParameter Values(String) getParameterNamesO MUITOS outros mtodos ...

Ii

Interface HttpServletRequest Gavax.servlet.http. HttpServletRequest)

t
I

<<interfaee> > HTTPServletReauest getContextPathO getCookiesO getHeader(String) getIntHeader(String) getMethodO getQueryStringO getSessionO MUITOS outros mtodos ...

Ii

voc est

125

o objeto HttpServletResponse

Etrl'o,essa foi a Solicitao ... vejatMos agora a Resposta


A resposta o que volta para o cliente. Aquilo que o browser recebe, analisa e retribui ao usurio. Tipicamente, voc usa o objeto response para conseguir um stream de sada (geralmente um Writer), e voc usa este stream para escrever o HTML (ou outro tipo de contedo) que retoma para o cliente. Contudo, o objeto response tem outros mtodos alm do IIO output. Veremos alguns deles com mais detalhes.

yoce usa a apenas pata envIal- dad9s de volta 9 Voc chama resp9sta: setConte.nf7jpei) e
gef\VdtetD.

interface ServletResponse Gavax.servlet. ServletResponse) <<interface> > ServletResonse etBuiferSizeO setContentTypeO


---_

..

_----------------.-.-----.-----_.--------.-----

. __ ... _

.....

__

.... _.,

l/I#itJ.ts

etWriterO ~etoutputStreamo etContentLengthO 'IMUITOS outros mtodos ...

DepoIS dIss9>v9c estadt ttZendo sImplesmente pata escl"evet o alg9 mms) no ]\tlas \9c tamlJm pode a resposta pm-a outt9sheadets. ettOS

addCookieO addHeaderO encodeURLO sendErrorO setStatusO sendRedirectO 'IMUITOS outros mtodos ...

126

capitulo 4