Escolar Documentos
Profissional Documentos
Cultura Documentos
O que um Servlet ? Servlet so mdulos de cdigos em Java que rodam em uma aplicao no servidor (podemos fazer uma analogia com Applets do lado cliente) para responder pedidos do cliente. Os servlets no so direcionados para um tipo de protocolo cliente-servidor, embora sejam mais comumente usados com HTTP e a palavra SERVLET frequentemente usada com significado HTTP SERVLET. Servlets usam extenses da classe no pacote javax.servlet (o pacote bsico para esse fim) e javax.servlet.http (classes utilizadas para atender a pedidos HTTP). Como servlets so escritos em Java, eles criam extenses sofisticadas em um servidor, independentemente do sistema operacional. Usos tpicos para HTTP Servlets: - Processamento e armazenamento de dados mandados por um formulrio HTML; - Acessar um contedo dinmico, exemplo o resultado de consulta ao banco de dados; - Gerenciar o estado de informao sobre uma conexo de estado HTTP; Servlet x CGI A maneira mais tradicional de adicionar funcionalidade a um servidor web utilizando CGI (Common Gateway Interface). Cada pedido respondido em um processo separado por instancia separada do programa CGI ou um script CGI (como frequentemente chamado porque programas CGI so geralmente escritos em linguagens interpretadas como Perl). Vantagens dos Servlets sobre CGI: - Um servlet no roda em um processo separado. Isto remove o overhead de criar um novo processo para cada pedido. - Um servlet fica na memria entre os pedidos. Um programa CGI precisa ser carregado a cada pedido; - H somente uma nica instncia que responde a todos os pedidos, isto economiza memria e faz um servlet fcil de gerenciar dados persistentes;
getServletConfig (). Os servlets que estendem GenericServlet (ou sua subclasse HTTPServlet) deve chamar Super.Init(config) no incio do mtodo
init para fazer uso desta feature. O mtodo init chamado apenas uma vez durante a existncia de um servlet. O mtodo no ser chamado at que o mtodo init devolva algum valor de retorno. Quando um servlet iniciado, seu mtodo de servio (ServletRequest req, ServletResponse res) chamado a cada solicitao do servlet. O mtodo chamado concorrentemente (por exemplo: mltiplas threads podem chamar esse mtodo ao mesmo tempo), logo isso deve estar implementado em um modo que suporte threads.
Esse mtodo retornar o valor do parmetro init nomeado ou null se no existir e o valor do retorno sempre uma nica String. Caber ao servlet interpretar o valor. Como conectar um servlet ao banco de dados Um servlet que precisa estabelecer uma conexo com um banco de dados pode usar parmetros init para definir os detalhes da conexo. Um dos mtodos que podemos adotar o establishConnection () personalizado para extrair os detalhes da JDBC, exemplificado abaixo:
java.sql.Connection com = null; public void init () throws ServletException { String host = getInitParameter(host); init port = Integer parseInt (getInitParemeter(port)); String db = getInitParameter (db); String user = getInitParameter (user); String password = getInitParameter (password); String proxy = getInitParameter (proxy); con proxy); } = establishConnection (host, port, db, user, password,
Como obter os nomes do parmetro init do servlet Um servlet pode examinar todos os seus parmetros init usando
getInitParameterNames ():
public Enumeration ServletConfig.getInitParameterNames ()
Exemplo:
public void doGet (HttpServletRequest req, HttpServletResponse res) thwows ServletException, IOException { String name = getServletName (); ServletContext context = getServletContext (); Object value = context.getAttribute (name+.state); }
Servidor Um servlet pode descobrir muito sobre o servidor no qual est sendo executado. Ele pode aprender o nome de host, escutar a porta e o software do servidor. Um servlet pode exibir essas informaes para um cliente, us-las para personalizar seu comportamento ou us-las para restringir explicitamente as mquinas nas quais o servlet ser executado.
Como obter informaes sobre o servidor Um servlet consegue a maior parte de seu acesso para as informaes do servidor atravs do objeto ServletContext em que executado. Existem cinco mtodos onde um servlet pode usar para aprender sobre seu servidor. Dois deles so acionados atravs do objeto ServletRequest que transmitido para o servlet e trs que so chamados a partir do ServletContext no qual o servlet est sendo executado. Servlet pode obter o nmero da porta e o nome do servidor atravs dos mtodos getServerPort( ) e getServerName( ). public String ServletRequest.getServerName( ) public int ServletRequest.getServerPort( ) Esses mtodos so atributos de ServletRequest pois os valores podem mudar caso haja diferentes solicitaes caso o servidor tenha mais de um nome. Essa tcnica chamada de host virtual. Os mtodos getServerInfo( ) e getAttribute( ) de ServletContext fornecem dados sobre o software do servidor e seus atributos.
Como obter o parmetro init de um contexto Os parmetros init do servlet,so transmitidos para servlets individuais. Como diversos servlets devem receber os mesmos valores do parmetro init, esses valores podem ser atribudos como um parmetro init do contexto. A classe contexto: public public String ServletContext.getInitParameter(String Enumeration name)- retorna o valor de string do parmetro especificado ServletContext.getInitParameterNames( )- retornar uma Enumeration contendo os nomes de todos os parmetros init disponveis para o aplicativo web. ServletContext tem dois mtodos getInitParameter( ) e getParameterNames( ) para recuperar as informaes de inicializao de todo
Os parmetros init para um contexto so especificados no descritor da distribuio web.xml para o context usando a tag <context-param>. <!DOCTYPE web-app PUBLIC -//Sun Microsystems, inc.//DTD Web Application 2.2//EN http://java.sun.com/j2ee/dtds/web-app_2.2.dtd> <web-app> <context-param> <param-name> rmihost </param-value> <param-value> localhost </param-value> </context-param> </context-param> <param-name> rmiport </param-name> <param-value> 1099 </param-value> </context-param> </web-app>
Como determinar a verso de um servlet Um servlet pode solicitar ao servidor qual a verso da Servlet APIa qual o servidor suporta. Essa informao muito til para depurar e at mesmo no suporte a deciso, onde se decide se deve utilizar uma nova abordagem para resolver uma tarefa ou uma mais antiga.
Cliente Para cada solicitao, um servlet tem a capacidade de descobrir sobre a mquina do cliente e, para as pginas que requerem a autenticao, sobre o usurio real. Essas informaes podem ser usadas para registrar os dados de acesso, associar informaes aos usurios individuais ou restringir o acesso a certos clientes. Como obter informaes sobre a mquina do cliente Utilizando o getRemoteAddr( ) e o getRemoteHost( ) ele pode recuperar o endereo IP e o nome de host da maquina do cliente. Ambos os valores so retornados como objetos String. As informaes vem do soquete e conecta o servidor ao cliente. Por tanto o nome do host e o endereo remoto podem ser de um servidor proxy. public String ServletRequest.getRemoteAddr( ) public String ServletRequest.getRemoteHost( ) O endereo IP ou o nome do host remoto pode ser convertido em um objeto java.net.InettAddress usando InetAddress.getByName( ): InetAddress remoteInetAddress = InetAddress.getByName(req.getRemoteAddr( ));
Como obter informaes sobre o usurio Praticamente todo servidor HTTP tem a capacidade predefinida para limitar o acesso a algumas ou todas as suas pginas para um dado conjunto de usurios registrados. Na primeira vez em que o navegador tenta o acesso a uma dessas pginas, o servidor HTTP responde que precisa de uma autenticao especial. Assim que se fornecido essa autenticao, o navegador tenta de novo acessar a pgina, desta vez anexando a autenticao especial (pode ser login e senha) junto a solicitao. Quando o acesso para um servlet for limitado pelo servidor, o servlet poder obter o nome do usurio que foi aceito, utilizando o mtodo getRemoteUser( ): public String HttpServletRequest.getRemoteUser() Um servlet tambm pode usar o mtodo getAuthType( ) para descobrir qual o tipo de autorizao foi usada: public String HttpServletRequest.getAuthType()
Esse mtodo retorna o tipo de autenticao usada ou null caso o acesso para o servidor no tenha sido limitado. Os tipos podem ser BASIC, DIGEST, FORM ou CLIENT-CERT, Com o nome de um usurio remoto, um servlet pode gravar informaes sobre cada cliente. Em logo prazo, ele poder lembrar as preferncias de cada
getParameterValues(): public String ServletRequest.getParameter(String name) public Onde: getParameter( ) - retornar o valor do parmetro nomeado com String ou null (caso o parmetro no seja especificado). getParameterValues( ) esse mtodo dever ser chamado caso haja uma chance de um parmetro ter mais de um valor. Obs: Se as informaes do parmetro vierem como dados POST codificados, no estaro disponveis se os dados POST j tiverem sido lidos manualmente com o mtodo getReader ( ) ou getInputStream ( ) de ServletRequest (porque os dados POST podem ser lidos apenas uma vez). Os possveis usos para os parmetros da solicitao so limitados. Eles so uma maneira geral de informar a um servlet o que fazer, como faz-lo ou ambos. Como exemplo simples, vejamos como um servlet de dicionrio poderia usar getParameter ( ) para descobrir a palavra que ele precisa pequisar. String [ ] ServletRequest.getParameterValues(String name)
Um servlet pode recuperar a string de consulta bruta da solicitao com getQueryString(): public String ServletRequest.getQueryString () Informaes do caminho Alm dos parmetros, uma solicitao HTTP pode incluir algo chamado informaes extras do caminho ou caminho virtual. Essas informaes extras so usadas para informar um arquivo no servidor que o servlet deve usar para algo, tais informaes so codificadas no URL de uma solicitao HTTP. HTTP://server:port/servlet/ViewFile/index.htm Isso chama o servlet ViewFile, transmitindo/ndex.html como as informaes extras do caminho. Por que informaes extras do caminho? Um programa CGI no pode interagir com seu servidor durante a execuo, portanto no tem nenhuma maneira de receber um parmetro do caminho, que dir solicitar ao servidor para mape-lo para um local do sistema de arquivos real. O servido tem como converter de algum modo o caminho antes de chamar o programa CGI. por isso que precisa haver um suporte para as informaes extras do caminho especiais. Os servidores sabem converter previamente esse caminho e enviar a converso para programa CGI como uma varivel de ambiente. uma soluo bel elegante para uma falha CGI. Como obter as informaes do caminho Um servlet pode usar o mtodo getPathInfo ( ) para obter as informaes extras do caminho: public String HttpServletRequest.getPathInfo ()
Esse mtodo receber informaes extras do caminho associado solicitao(URL decodificado se necessrio) ou null se nada for dado. Converses do caminho organizadas Algumas vezes um servlet precisa converter um caminho que no foi transmitido como as informaes extras do caminho. Voc poder usar o mtodo getRealPath( ) para essa tarefa. public String ServletContext.getRealPath(String path) Como obter o caminho do contexto Os aplicativos web so mapeados para os prefixos URL no servidor. Um servlet pode determinar o prefixo URL do contexto no qual est sendo executado, utilizando o mtodo getContextPath ( ) em ServletRequest: public String ServletRequest.getContextPath ( ) Esse mtodo retorna uma String representando o prefixo do URL do contexto que lida com a solicitao.
Como obter tipos MIME Assim que um servlet tiver o caminho para um arquivo, ele geralmente precisa descobrir o tipo do arquivo. Use getMimeType ( ) para tanto: public String ServletContext.gatMimeType(String file)
Esse mtodo retornar o tipo MIME do arquivo dado, com base em sua extenso, ou null seno for conhecido. Os tipos MIME comuns so text/HTML,text/plain, image/gif e image/jpeg. Como atender os arquivos O prprio Tomcat Server usa servlets para lidar com toda solicitao. Alm de ser uma vitrine para a capacidade dos Servlets, isso fornece ao servidor uma construo modular que permite a substituio indiscriminada de certos aspectos de sua funcionalidade. Por exemplo, todos os arquivos so atendidos pelo servlet org.apache.tomcat.core.DefaultServlet, com a responsabilidade de lidar com o caminho / (significando que a sub-rotina default para as solicitaes), mas no quer dizer que o DefaultServlet no possa ser substitudo.
Como ler a partir de um recurso abstrato O mtodo getPathTranslated ( ) tem alguns limites infelizes. Primeiro, ele no funciona para o contedo atendido a partir dos arquivos WAR porque no h nenhum arquivo direto para acessar. Segundo, no funciona em um ambiente distribudo com carregamento equilibrado onde pode haver um arquivo direto mas no no servido executando atualmente o servlet. Para solucionar este limite a Servlet API 2.1 introduziu uma tcnica para a abstrao dos recursos, que permite aos servlets acessarem um recurso sem saber onde ele reside. Ele obtm o recurso abstrato usando o getResource ( ). public URL ServletContext.getResoruce (String uripath) Esse mtodo retorna um URL que pode ser usado para investigar o recurso especificado e ler seu contedo, como o parmetro do caminho URL mapeia um recurso real (arquivo, entrada WAR, entrada do banco de dados ou outro) determinado pelo servidor web. Ao usar o objeto do contexto para solicitar recurso, importante lembrar-se de no incluir o caminho do contexto na solicitao. O seguinte cdigo obtm e imprime o arquivo /includes/headers.html para o contexto atual:
URL
url
getServletContext
).getResource
(/includes/header.html); If (url !=null){ ServletUtils.returnURL(yrl, out); } Como determinar o que foi solicitado Um servlet pode usar vrios mtodos para descobrir exatamente qual o arquivo ou servlet o cliente solicitou. Nenhum mtodo retorna diretamente o Uniform Resource Locator (URL) original usado pelo cliente para fazer uma solicitao. Porem, a classe javax.servlet.http.HttpUtils fornece um mtodo getRequestURL ( ) que faz praticamente a mesma coisa. public static StringBuffer HttpUtils.getRequestURL (HttpServletRequest req) Como foi solicitado Alm de saber o que foi solicitado, um servlet tem vrias maneiras de descobrir detalhes sobre como foi solicitado. O mtodo getScheme ( ) retorna o esquema usado para fazer essa solicitao: public String ServletRequest.getScheme () O mtodo getProtocol () retorna o protocolo e o nmero da verso usados npara fazer a solicitao: public String ServletRequest.getProtocol ( ) Para descobrir qual mtodo foi usado para uma solicitao, um servlet usa getMethod ():
public String HttpServletRequest.getMethod ( ) Como lidar com as solicitaes POST usando o fluxo de entrada uma ocorrncia rara quando um servlet que lida com uma solicitao Post forado a usar seu fluxo de entrada para acessar os dados POST. Geralmente, os dados POST no so nada mais que as informaes do parmetro codificadas, que um servlet pode recuperar com convenincia com seu mtodo getParameter ( ). Um servlet pode identificar esse tipo de solicitao POST verificando o tipo de contedo do fluxo de entrada. Se for do tipo application, os dados podero ser recuperados com getParameter () e mtodos parecidos. Atributos extras Algumas vezes um servlet precisa saber algo sobre uma solicitao que no est disponvel atravs de nenhum mtodo mencionados anteriormente. Nesses casos, h uma alternativa, o mtodo getAttribute ( ). public Object ServletRequest.getAttribute (String name)
Como enviar uma resposta normal import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWord extends httpservlet { public void doget (HttpServletRequest req, HttpServletResponse resthrows ServletException, IOException { res.setContentType (text/html); printWriter out = res.getWriter ( ); out.println (<HTML>); out.println </TITLE></HEAD>); out.println (<BODY>); outprintln (<BIG> HelloWord </BIG>); outprintln (</BODY></HTML>); } } Esse servlet usa dois mtodos e uma classe que foi mencionada rapidamente anteriormente. O mtodo setContentType ( ) de ServletResponse define o tipo de contedo da resposta para ser o tipo especificado: public void ServletResponse.setContentType (String type) Em um servlet HTTP, esse mtodo define o cabealho http Content-Type. O mtodo getWriter ( ) retorna um PrintWriter para escrever os dados da resposta baseados em caracteres. (<HEAD><TITLE> HelloWord
Public IOException
PrintWriter
ServletResponse.getWriter()
throws
Como usar conexes permanentes As conexes permanentes (algumas vezes chamadas de conexes ativas) podem ser usadas para reduzir o modo como os servlets retornam o contedo para o cliente. Para compreendermos como essa reduo funciona, precisamos entender como as conexes HTTP funcionam. Os detalhes so bem tratados no HTTP Pocket Reference de Clinton Wong (OReilly). Quando um cliente, como um navegador, solicita um documento web de um servidor, ele comea estabelecendo uma conexo do soquete com o servidor. Nessa conexo, o cliente faz sua solicitao e ento consegue a resposta do servidor. O cliente mostra que terminou sua solicitao remetendo uma linha em branco; o servidor, por sua vez mostra que a resposta est completa encerrando a conexo do soquete. Boa parte dos servidores gerenciam internamente o cabealho ContentLength para os arquivos estticos que eles atendem; o Content-Length definido para coincidir com o tamanho do arquivo. Para determinar o comprimento do contedo de sada gerada pelo servlet, um servidor requer assistncia do servlet, um servlet pode definir o Content-Length da resposta e ter as vantagens de uma conexo permanente para seu contedo dinmico usando o mtodo setContentLeght ( ): public void ServletResponse.setContentLength (int len) Esse mtodo define o tamanho (em bytes) do contedo retornado pelo servidor. Buffer de resposta Comeando com a servlet API 2.2, um servlet tem controle sobre se o servidor guarda em buffer sua resposta e pode ditar o tamanho de um buffer que um servidor pode usar. Nas verses anteriores da API, a maior parte dos servidores web
Cinco mtodos no ServletResponse fornecem controle sobre o buffer de resposta. setBufferSize() Para informar o servidor o tamanho mnimo do buffer em bytes. public void SErvletResponse.setBufferSize (int size)
throws IllegalStateException getBufferSize () Esse mtodo retorna um int indicando o tamanho real do buffer atual ou 0 no evento improvvel de nenhum buffer ser usado. Public int ServletResponse.getBufferSize ( ) intCommitted ( ) Para determinar se parte da resposta foi realmente enviada. Esse mtodo retornar true, ser tarde demais para mudar o cdigo de status e os cabealhos e o Content-Length no poder ser calculado automticamente. Public boolean ServletResponse.isCommitted ( )
reset ( ) Limpa o buffer da resposta, o cdigo de status atribudo atualmente e os cabealhos da resposta. Public void ServletResponse.reset () throws IllegalStateException
flushBuffer ( ) Permite que o cliente comece a receber o contedo imediatamente. Public void ServletResponse.flushBuffer ( ) throws IOException
Cdigos de status
Cdigo
200
Mensagem default
OK
Significado
A solicitao do cliente foi bemsucedida e a resposta do servidor contem os dados solicitados. A solicitao foi bem sucedida, mas no h qualquer corpo de resposta a retornar. O recurso solicitado foi permanentemente para um novo local. As futuras referncias usam o novo URL nas solicitaes. O recurso solicitado foi temporariamente para outro local, mas futuras referencias ainda devem usar o URL original para acessar o recurso. A solicitao no tinha a devida autorizao. O recurso solicitado no foi encontrado ou no est disponvel. Um erro inesperado ocorreu dentro do servidor que o impediu de satisfazer a resposta. O servidor no suporta a
204
No Content
301
Moved Permanently
SC_MOVED_ TEMPORARILY
302
Moved Temporarily
SC_NOT_
501
Not Implemented
Como definir um cdigo de status Um servlet pode usar o setStatus ( ) para definir um cdigo de status da resposta: public void HttpServletResponse.setStatus (int sc) Esse mtodo define o cdigo de status HTTP para o valor dado. O cdigo pode ser especificado como um nmero ou com um dos cdigo SC_XXX definidos em HttpServletResponse. Lembre-se, o mtodo setStatus( ) deve ser chamado antes da resposta ser aceita, do contrrio a chamada ser ignorada. Se um servlet definir um cdigo de status que indica um erro durante o tratamento da solicitao, poder chamar sendError( ) em vez de setStatus( ): public void HttpServletResponse.sendError(int sc) Throws IOException, IllegalStateException public void HttpServletResponse.sendError(int sc, String sm) Throws IOException, IllegalStateException
Os cabealhos HTTP Um servlet pode definir os cabealhos HTTP para fornecer informaes extras sobre sua resposta. A tabela abaixo lista os cabealhos HTTP que so mais usados pelos servlets como parte de uma resposta. Cabealho
Cache-Control Pragma
Uso
Especifica qualquer tratamento especial que um sistema de cache deve fornecer para esse documento. o equivalente HTTP 1.0 de cache-Control,
Connection Retry-After
Expires Location
WWW-Authenticate Content-Encoding
Como definir um cabealho HTTP A classe HttpservletResponse fornece vrios mtodos para ajudar os ervlets a definirem os cabealhos de reposta HTTP. Use setHeader( ) para definir o valor de um cabealho: public String value) Se precisar especificar um timbre de hora para um cabealho, poder usar setDateHeader( ): public void HttpSevletResponse.setDateHeader (String void HttpServletResponse.setHeader(String name,
name, long date) Como redirecionar uma solicitao Uma das coisas mais teis que um servlet pode fazer usando os cdigos de status e os cabealhos redirecionar uma solicitao. Isso feito enviando instrues para o cliente para usar outro URL na resposta. A redireo usada,
Como os servlets so escritos em Java, o dano que eles podem causar ao seu servidor mnimo. Um servidor pode evoluir com segurana os servlets (mesmo em seu processo), certamente como um navegador web pode incorporar com segurana os mini aplicativos carregados. Essa segurana tem relao com os recursos de segurana do Java, inclusive o uso da memria protegida, o tratamento de excees e os gerenciamentos de segurana. A proteo de memria do Java prega que os servlets no podero acessar sem querer (ou intencionalmente) as partes internas do servidor. O tratamento de excees do Java permite que um servidor possua toda exceo enviada por um servlet. Mesmo que um servlet divida sem querer por zero ou pea um mtodo em um objeto sem valor, o servidor poder continuar a funcionar. O mecanismo do gerenciador de segurana do Java fornece uma maneira para os servidores colocarem os servlets inconfiveis em uma caixa de areia, limitando suas capacidades e impedindo-os de causar problemas sem inteno.
Como informar Alm de registrar os erros e as excees para o administrador do sistema, durante o desenvolvimento geralmente conveniente imprimir uma descrio completa do problema junto com um controle de pilha. Infelizmente, uma exceo no pode retornar seu controle da pilha como uma String pode imprimir seu controle da pila apenas em um PrintStream ou PrintWriter. Para recuperar um controle da pilha como uma String, teremos que fazer alguns saltos. Precisamos permitir que o Exception imprima em um PrintWriter especial construdo em torno de um ByteArrayoutoutStream. Esse ByteArrayoutoutStream pode obter a sada e convert-la em uma String. ServletException
Seis maneiras de explorar um servlet Os servlets se tornaram de fato para o desenvolvimento web no lado do servidor baseado no Java. O confronto entre os servlet, mini aplicativos no lado do servidor e outras arquiteturas de conexo baseadas em Java efetivamente acabou e os servlets foram declarados como ganhador, suportados hoje em todo servidor web e servidor de aplicativo. A nova rea de inovao ativa pode ser encontrada acima da camada do servlet, nos nveis da apresentao e de estrutura, onde usurios e empresas esto explorando a melhor maneira de se basear nos servlets para criar sites web eficientes. Tais respostas so necessrias porque a abordagem comum para gerar o contedo de marcao, fazendo com que o programador do servlet escreva uma chamada out.println( ) para cada linha do contedo, mostrou ser um problema difcil para o uso real. Com a abordagem out.println( ), o contedo de marcao tem que ser criado no cdigo, o que se torna uma tarefa complicada e demorada para pginas grandes. Assim, os desenvolvedores da pgina tm que pedir aos criadores para fazer todas as modificaes do site. O objetivo que quase todas as arquiteturas de desenvolvimento do contedo compartilhar afastar o contedo da apresentao. O termo contedo aqui significa os dados brutos do site e a manipulao desses dados. Um termo melhor talvez seja processamento de dados, mas afastar o processamento de dados da apresentao no parece ser o correto para isso. O termo apresentao significa a representao dos dados fornecidos para o usurio final (normalmente HTML, embora com o crescimento dos dispositivos conectado web, seja cada vez mais