• Nenhum resultado encontrado

Aula 7: Servlets (II)

N/A
N/A
Protected

Academic year: 2021

Share "Aula 7: Servlets (II)"

Copied!
31
0
0

Texto

(1)

Aula 7: Servlets (II)

Diego Passos

Universidade Federal Fluminense

(2)

´

Ultima Aula

O que s˜ao Servlets.

Estrutura b´asica de um Servlet. Criac¸˜ao de Servlets simples. Contexto de um Servlet. Informac¸˜oes sobre requisic¸˜oes.

(3)

Nesta Aula

Respostas de requisic¸˜oes. Inicializac¸˜ao de Servlets. Filtros.

(4)

Respostas a Requisic¸˜

oes

Servlets recebem requisic¸˜oes. Clientes esperam respostas.

I Dados de uma consulta. I Confirmac¸˜ao de uma operac¸˜ao. I . . .

Para um Servlet HTTP, resposta cont´em trˆes partes:

I C´odigo de status. I Cabec¸alhos HTTP. I Corpo da resposta.

(5)

Respostas a Requisic¸˜

oes (II)

Manipulac¸˜ao da resposta ´e feita pelas interfaces ServletResponse e HttpServletResponse.

Incluem m´etodos para a criac¸˜ao e manipulac¸˜ao das trˆes partes da resposta de um Servlet. Exemplo de m´etodo de manipulac¸˜ao da resposta: setContentType().

I Recebe como parˆametro uma String especificando um MIME: e.g., “text/html”. I Configura o header Content-Type na resposta.

(6)

Respostas a Requisic¸˜

oes (III)

Interfaces ServletResponse e HttpServletResponse tamb´em s˜ao usadas para produzir stream de sa´ıda.

Dois m´etodos:

I getOutputStream(): retorna um ServletOutputStream para conte´udo bin´ario ou

texto.

I getWriter(): retorna um PrintWriter para conte´udo texto apenas.

Aten¸c˜ao ao usar o m´etodo getWriter():

I Ele inspeciona o Content-Type para determinar configurac¸˜oes de codificac¸˜ao de caracteres.

(7)

Respostas a Requisic¸˜

oes (IV)

H´a m´etodos espec´ıficos para a interface HttpServletResponse.

Estes m´etodos obviamente manipulam componentes espec´ıficos de respostas HTTP. Exemplo: manipulac¸˜ao de cabec¸alhos.

I setHeader(String,String): configura o valor de um cabec¸alho como uma string. I setIntHeader(String,int): configura o valor de um cabec¸alho como um inteiro.

I setDateHeader(String,long): configura o valor de um cabec¸alho como uma data

(milisegundos desde a Era Unix ).

(8)

Respostas a Requisic¸˜

oes (V)

´

E poss´ıvel ainda manipular o c´odigo de status da resposta. Feito atrav´es de dois m´etodos:

I setStatus(int): envia o c´odigo correspondente `a constante especificada.

I sendError(int, String): envia o c´odigo correspondente `a constante especificada e uma mensagem de erro.

F N˜ao pode ser usado se j´a houve sa´ıda enviada ao cliente.

Outro m´etodo ´util ´e o sendRedirect(String): envia um redirecionamento a outra URL. O parˆametro da func¸˜ao pode especificar:

I Uma URL absoluta.

I Um caminho relativo ao contexto do servlet (iniciado pelo caracter “/”). I Um caminho relativo `a URL atual (iniciado sem o caracter “/”).

(9)

Despacho de Requisic¸˜

oes

Muitas vezes em um Servlet e desej´avel delegar uma requisic¸˜ao a um outro servlet. Exemplos:

I Servlet principal apenas detecta qual servlet “secund´ario” deve ser chamado. I Servlet principal chama servlets secund´arios para obter “pedac¸os” da resposta.

API de Servlets permite este tipo de soluc¸˜ao atrav´es da classe RequestDispatcher. A partir de um ServletContext ´e poss´ıvel obter um RequestDispatcher:

ServletContext context = getServletContext();

RequestDispatcher d = getRequestDispatcher("/ServletSecundario");

(10)

Despacho de Requisic¸˜

oes (II)

De posse de um objeto do tipo RequestDispatcher ´e poss´ıvel fazer dois tipos de delegac¸˜ao:

I forward : a responsabilidade pela requisic¸˜ao ´e totalmente passada para o Servlet secund´ario. I include: apenas inclui a sa´ıda do Servlet secund´ario na sa´ıda do Servlet prim´ario.

A classe RequestDispatcher define dois m´etodos correspondentes: forward() e include().

Exemplo de delegac¸˜ao do tipo include: out.println("Uptime for our servers");

ServletContext context = getServletContext();

RequestDispatcher d = context.getRequestDispatcher("/servlet/ServerMonitor"); req.setAttribute("serverurl", new URL("http://www1.company.com"));

d.include(req, res);

req.setAttribute("serverurl", new URL("http://www2.company.com")); d.inc1ude(req, res);

(11)

Despacho de Requisic¸˜

oes (III)

Qual a diferenc¸a entre um despacho do tipo forward e um redirecionamento?

I Redirecionamento exige que cliente receba a resposta e fac¸a uma nova requisic¸˜ao. I No despacho, a mesma requisic¸˜ao ´e passada internamente ao servidor para o servlet em

quest˜ao. I Consequˆencias:

F Despacho tende a ser mais r´apido.

F Para o cliente, URL se mant´em como a da requisic¸˜ao original.

Note que o m´etodo getRequestDispatcher() pode ser usado para qualquer tipo de recurso dentro do contexto do Servlet.

I Arquivos HTML est´aticos, imagens, . . . I N˜ao apenas outros Servlets.

(12)

Lidando com Erros

O que fazer quando o Servlet encontra uma situac¸˜ao de erro ao processar uma requisic¸˜ao? H´a v´arias possibilidades.

A API de Servlets provˆe duas:

I Enviar uma mensagem de erro diretamente ao cliente. I Levantar uma excec¸˜ao.

(13)

Lidando com Erros: Enviando Mensagem ao Cliente

´

E poss´ıvel imprimir mensagens de erro diretamente ao cliente.

I Da mesma forma que imprimimos o conte´udo de uma resposta qualquer.

No entanto, ´e mais elegante (e muitas vezes poderoso) utilizar um m´etodo espec´ıfico para isso:

I sendError(int): envia um c´odigo de erro HTTP ao cliente com uma mensagem de erro padr˜ao.

I sendError(int, String): envia um c´odigo de erro HTTP ao cliente com uma mensagem

de erro especificada.

Ambos os m´etodos podem ser acessados atrav´es da interface HttpServletResponse: response.sendError(HttpServletResponse.SC_NOT_FOUND);

response.sendError(HttpServletResponse.SC_NOT_FOUND,

"Could not find the specified file.");

(14)
(15)

Lidando com Erros: Gerando Excec¸˜

oes

Breve revis˜ao:

I Excec¸˜oes s˜ao a maneira padr˜ao de lidar com erros em Java.

I Um m´etodo pode se declarar capaz de gerar um determinado tipo de excec¸˜ao. I Neste caso, ele pode utilizar a palavra reservada throw, gerando uma nova excec¸˜ao. I M´etodo chamador recebe a excec¸˜ao e deve lidar com ela de alguma forma.

A API de Servlets provˆe dois tipos de excec¸˜ao:

I ServletException: reportar problemas gerais.

I UnavailableException: reportar que o Servlet se encontra indispon´ıvel.

(16)

Lidando com Erros: Gerando Excec¸˜

oes

O comportamento do servidor ao receber uma ServletException n˜ao ´e padronizado.

I Isto ´e, servidores diferentes podem tratar a excec¸˜ao de formas distintas.

Para a UnavailableException, no entanto, o comportamento ´e definido:

I O servidor (container) n˜ao deve repassar novas requisic¸˜oes. I Servlet est´a indispon´ıvel.

Pode-se especificar um “tempo de indisponibilidade” para a UnavailableException.

I Mas n˜ao h´a garantias de que o servidor ir´a tentar novamente ap´os este tempo.

Exemplos:

throw new UnavailableException(this, "Mensagem que especifica o problema."). throw new UnavailableException(120, this,

(17)
(18)

Inicializac¸˜

ao de Servlets

Relembrando:

I Quando um Servlet ´e iniciado pelo container, meu m´etodo init() ´e chamado. I Requisic¸˜oes s´o s˜ao passadas ao Servlet ap´os o fim do respectivo init().

Implementac¸˜ao padr˜ao do m´etodo init() n˜ao faz muito. Mas m´etodo pode ser re-implementando por cada Servlet. Permite realizar tarefas que s´o precisam ser feitas uma vez:

I Operac¸˜oes intensivas em E/S.

(19)

Inicializac¸˜

ao de Servlets (II)

H´a duas vers˜oes do m´etodo init():

I Uma sem parˆametros.

I Outra que recebe um objeto do tipo ServletConfig.

Pode-se reimplementar qualquer uma delas.

I Mas se reimplementarmos a vers˜ao com parˆametro, ´e obrigat´orio chamar a vers˜ao original.

(20)

Inicializac¸˜

ao de Servlets (IV): Parˆ

ametros de Configurac¸˜

ao

O objeto do tipo ServletConfig encapsula parˆametros de configurac¸˜ao espec´ıficos do Servlet.

Estes parˆametros podem ser acessados atrav´es de dois m´etodos:

I getInitParameter(String): retorna uma String com o valor do parˆametro especificado. I getInitParameterNames(): retorna uma enumerac¸˜ao com os nomes dos parˆametros

dispon´ıveis.

Os parˆametros (e seus valores) s˜ao configurados no descritor web.xml atrav´es da tag <init-param>.

(21)

Finalizac¸˜

ao de Servlets

Analogamente ao m´etodo init(), Servlets podem implementar um m´etodo destroy(). Este m´etodo ´e chamado sempre que o servidor quer “descarregar” um Servlet.

´

(22)

Inicializac¸˜

ao e Finalizac¸˜

ao do Contexto

A partir da vers˜ao 2.3, a API de Servlets disponibilizou a interface ServletContextListener.

Uma classe que implementa esta interface pode ser associada a um contexto. Neste caso, a classe ´e avisada sempre que o contexto ´e criado ou destru´ıdo.

I Atrav´es dos m´etodos contextInitialized e contextDestroyed.

A associac¸˜ao de uma classe a um contexto ´e feito no descritor web.xml: <web-app ...> <listener> <listener-class> MyAppServletContextListener </listener-class> </listener> </web-app>

(23)

Filtros

Filtros s˜ao objetos que podem ser colocados no caminho entre as requisic¸˜oes e Servlets (ou outros recursos em um servidor).

Filtros podem modificar a requisic¸˜ao recebida ou resposta enviada por um servlet.

I Exemplo: comprimir os dados da resposta.

Eles podem ainda realizar tarefas de monitoramento ou implementar pol´ıticas de seguranc¸a. Mais de um filtro pode ser utilizado, formando uma cadeia.

I Cada filtro executa sua ac¸˜ao e passa o controle para o pr´oximo filtro.

Cliente Container Filtro Filtro Filtro Servlet

Requisição Resposta

(24)

Filtros (II)

Filtros s˜ao implementados sobre a interface Filter. M´etodos relevantes:

I init(): inicializac¸˜ao do filtro. I destroy(): finalizac¸˜ao do filtro. I doFilter(): m´etodo principal do filtro.

No m´etodo doFilter(), filtro pode fazer qualquer processamento sobre a requisic¸˜ao. Em algum ponto, deve chamar o m´etodo doFilter() do pr´oximo filtro.

I Dispon´ıvel no objeto FilterChain, recebido como parˆametro.

Pode tamb´em interromper a cadeia e retornar um erro para o cliente. Pode realizar redirecionamentos.

(25)

Filtros: Um Exemplo M´ınimo

import javax.servlet.*;

public class GenericFilter implements javax.servlet.Filter { public FilterConfig filterConfig;

public void doFilter(final ServletRequest request, final ServletResponse response, FilterChain chain)

throws java.io.IOException, javax.servlet.ServletException { chain.doFilter(request,response);

}

public void init(final FilterConfig filterConfig) { this.filterConfig = filterConfig;

}

public void destroy() { }

(26)

Filtros: Exemplo de Codificac¸˜

ao de Caracteres

public void doFilter(ServletRequest request,

ServletResponse response, FilterChain chain) throws IOException, ServletException {

String encoding = selectEncoding(request); if (encoding != null)

request.setCharacterEncoding(encoding); chain.doFilter(request, response);

}

public void init(FilterConfig filterConfig) throws ServletException {

this.filterConfig = filterConfig;

this.encoding = filterConfig.getInitParameter("encoding"); }

protected String selectEncoding(ServletRequest request) { return (this.encoding);

(27)

Filtros: Exemplo de Configurac¸˜

ao

<filter> <filter-name>Compression Filter</filter-name> <filter-class>CompressionFilter</filter-class> <init-param> <param-name>compressionThreshold</param-name> <param-value>10</param-value> </init-param> </filter>

(28)

Filtros: Requisic¸˜

oes Despachadas

Originalmente, filtros s´o eram executados em requisic¸˜oes originadas em clientes.

Requisic¸˜oes despachadas atrav´es da interface getRequestDispatcher() n˜ao passavam por filtros.

Em determinados casos, este comportamento ´e desej´avel.

A partir da vers˜ao 2.4 da API de Servlets, isso passou a ser poss´ıvel.

<filter> <filter-name>Compression Filter</filter-name> <filter-class>CompressionFilter</filter-class> <init-param> <param-name>compressionThreshold</param-name> <param-value>10</param-value> </init-param> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter>

(29)

Filtros: Como Alterar a Sa´ıda de Um Servlet

´

E f´acil fazer filtros adicionarem conte´udo antes ou depois da resposta de um Servlet. Mas como alterar o conte´udo que o Servlet gera?

Exemplo:

I Suponha que o Servlet chamado gera uma p´agina HTML. I Queremos adicionar alguma informac¸˜ao na p´agina.

I Mas ap´os a chamada do Servlet, este inclui um </html>.

Soluc¸˜ao: utilizac¸˜ao de wrappers.

(30)

Filtros: Como Alterar a Sa´ıda de Um Servlet (II)

Wrappers encapsulam objetos que representam respostas.

Sobreescrevem m´etodos como o getWriter() ou getOutputStream().

I Ao inv´es de enviarem o conte´udo diretamente para o cliente, pode enviar para algum buffer por exemplo.

Filtro cria o wrapper encapsulando o objeto de resposta original. Filtro chama o pr´oximo filtro (ou Servlet) passando o wrapper.

Quando o controle retorna para o filtro, ele pode inspecionar e alterar o conte´udo da resposta.

(31)

Filtros: Exemplo de Wrapper

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

PrintWriter out = response.getWriter();

CharResponseWrapper wrapper = new CharResponseWrapper( (HttpServletResponse)response);

chain.doFilter(request, wrapper);

if(wrapper.getContentType().equals("text/html")) { CharArrayWriter caw = new CharArrayWriter(); caw.write(wrapper.toString().substring(0,

wrapper.toString().indexOf("</body>")-1)); caw.write("<p>\nYou are visitor number

<font color=’red’>" + counter.getCounter() + "</font>"); caw.write("\n</body></html>"); response.setContentLength(caw.toString().length()); out.write(caw.toString()); } else out.write(wrapper.toString()); out.close(); }

public class CharResponseWrapper extends HttpServletResponseWrapper { private CharArrayWriter output; public String toString() {

return output.toString(); }

public CharResponseWrapper(

HttpServletResponse resp){ super(resp);

output = new CharArrayWriter(); }

public PrintWriter getWriter(){ return new PrintWriter(output); }

Referências

Documentos relacionados

e) Incentivar, nos casos legalmente cabíveis, a aplicação de medidas cautelares diversas da prisão e o respectivo encaminhamento do público para as Centrais

Quadros em sua mensagem ao Congresso Nacional em 15 de março de 1961, na qual procurou definir as linhas da política exterior do Brasil e deixou claro que a

3 O presente artigo tem como objetivo expor as melhorias nas praticas e ferramentas de recrutamento e seleção, visando explorar o capital intelectual para

No caso de espécies de sementes menores , que resultam em plântulas mais frágeis ou que são de estabelecimento mais lento, um número mínimo maior delas (40-50 pl â ntulas/rn ' )

Effects of the bite splint 15-day treatment termination in patients with temporomandibular disorder with a clinical history of sleep bruxism: a longitudinal single-cohort

F I G U R E 1   Schematic representation of the experiment undertaken to test different routes of oestradiol benzoate administration for cervical dilation prior to

As vazões serão derivadas, através de um túnel de adução, até a casa de força, instalada na margem esquerda do rio Corrente Grande.. O nível d’água previsto para o

Segund Segundo o o o come comentári ntário, qu o, quais s ais são ão as tr as três p ês priorid rioridades ades abso absolutas lutas da i da