segunda-feira, 13 de janeiro de 2014

Mais sobre Servlets e os seus filtros

Nessa artigo vamos falar um pouco mais de servlets e filtros de servlets. Caso você ainda não saiba o que é um servlet, por favor, veja a postagem anterior.
Lembrando que esse não é um artigo avançado sobre os servlets, mas sim um que cobre suas funcionalidades mais básicas.

Caso ainda não conheça HTTP, recomendamos esse artigo sobre HTTP.

Tratando requisições com o Servlet Java

Conforme falamos no artigo anterior, o Servlet é mais utilizado para o tratamento de requisições HTTP. Toda classe que "quer ser um servlet" deve estender(herdar) de HttpServlet
Quando herdamos dela, temos que implementar pelo menos um dos seguintes métodos que correspondem aos "verbos" HTTP. Esses métodos têm o nome doX, onde X é o método HTTP correspondente, por exemplo: doGet é invocado quando acessamos o contexto do servlet utilizando o método HTTP GET. Similarmente temos um método para POST, PUT, DELETE, TRACE e OPTIONS.
Cada um desses métodos, nós recebemos dois parâmetros, um do tipo HttpServletRequest e outro do tipo HttpServletResponse.

  • HttpServletRequest: Contém as informações da requisição HTTP que chegou ao Servlet. Exemplo de informações: cabeçalhos, partes da requisição (quando a mesma é multipart), a sessão HTTP (falaremos disso futuramente), cookies e outros. Também é possível tratar da parte de segurança através da "ativação" da segurança para aquele contexto(veja métodos login, logout e isUserInRole).
  • HttpServletResponse: Semelhante ao HttpServletRequest, o esse parâmetro é para que você possa escrever a resposta HTTP para o seu cliente. Podemos escrever o corpo HTTP da resposta, adicionar cabeçalhos, trocar os status HTTP entre outros.
É importante salientar que o servlet tem um nível de abstração maior do que o protocolo HTTP. Aqui falamos das classes relacionadas ao HTTP, mas vejam que elas herdam de ServletRequest e ServletResponse, que não são propriamente relacionadas com HTTP.

A principal diferença que vocês devem ter notado do Java WEB para o Java padrão é que aqui não estamos instanciando coisas com tanta frequência. Instanciar coisas diretamente com o new é basicamente um problemão! Entre os motivos para isso, destaco 2: Primeiro que você não vai saber lidar com os seus objetos e isso vai causar danos  com memória mais cedo ou mais tarde, segundo que você vai espalhar a criação do objeto pelo código, tornando dificil a manutenção futuramente. Pois bem, o servlet é instanciado e gerenciado pelo contêiner WEB e caso queria observar isso, você pode implementar os métodos init e destroy. Esses métodos vêm da classe pai do HttpServlet, a GenericServlet.

Acho que essa já é uma boa introdução ao servlet. Para fixar o conceito, sugiro esse artigo da Caelum. Vamos aproveitar e apresentar brevemente o Filter.

Filtrando as requisições que chegam aos Servlets

Ainda na especificação dos Servlets, temos os Filtros. Os filtros são utilizando para podermos registrar algum código antes da execução dos servlets. Seu uso é muito simples: dado um padrão de URL, o filtro será executado antes/depois da execução de um servlet. Mas o que é executado exatamente?
Quando você cria seu filtro, você deve implementar o método doFilter após implementar a interface Filter. Esse método recebe a um objeto que corresponde a requisição(ServletRequest), um que corresponde a resposta(ServletResponse) e o último é do tipo FilterChain, onde você pode continuar a execução. ou não executar nada e já retornar a resposta. Do FilterChain você deve chamar o método doFilter e passar os parâmetros de request e response.

Chega de blá blá e vamos ao código!

Nossa aplicação é bem simples e criamos um filtro para dois servlets.O código está no github e usamos maven de novo. As instruções são (considerando que você usa linux e já tenha java&maven&git instalados):

$ cd blog-aprendendo-jee/filtros-e-servlets
$ mvn package

Aí vai ser gerado o arquivo .war no diretório target. Você pode simplesmente copiar e colar o war e realizar o deploy em algum servidor de aplicação. Boiou? Veja esse artigo.

Abaixo um vídeo com algumas groselhas mais informações e eu tentando implementar o que descrevi nesse artigo:




Nota: Eu cometi uma gafe no vídeo tentando estender de Filter quando na verdade Filter é uma interface :(

Um comentário: