- Usado para extender as capacidades do servidor;
- Request-response;
- Geralmente utilizados para servidores Web mas podem responder quaisquer requisições.
Pacotes javax.servlet
e javax.servlet.http
com interfaces para programação com Servlets.
Todos os Servlets devem implementar a interface Servlet
, interface que define o ciclo de vida de um Servlet.
Controlado pelo Container que o Servlet está instalado.
Quando uma requisição é mapeada para o Servlet o container executa o seguinte:
- Carrega a classe do Servlet;
- Cria uma instância da classe do Servlet;
- Inicializa a instância com o método
init()
; - Chama o método service, passando os objetos request e response;
- Quando é necessário remover chama o método
destroy()
:
- Aplicações devem se comportar corretamente quando este método é chamado;
- Se os Servlets estão utilizando longos processos para executar deve-se utilizar algumams técnicas para garantir que eles sejam "desinstalados" corretamente:
- Manter uma contagem de quantos Servlets estão executando o método
service()
do Servlet;- Prover uma maneira segura e limpa de os Servlets que estão executando tenham oportunidade de parar sua execução;
- Fazer com que serviços que tenham longos processos verifiquem constantemente se o servidor foi desligado para reagir corretamente.
Pode-se monitorar e reagir a eventos no ciclo de vida dos Servlets.
Define-se Listeners que são invocados quando os eventos do ciclo ocorrem.
É necessário implementar os listeners específicos.
Cada listener é definido por uma interface específica.
- Inicialização e remoção:
javax.servlet.ServletContextListener
eServletContextEvent
;
- Atributos adicionados ou removidos:
javax.servlet.ServletContextAttributeListener
eServletContextAttributeEvent
.
- Criação, invalidação e timeout:
javax.servlet.http.HttpSessionListener
eHttpSessionEvent
.
- Atributos adicionados, removidos ou redefinidos:
javax.servlet.http.HttpSessionAttributeListener
eHttpSessionBindingEvent
.
import database.BookDB;
import javax.servlet.*;
import util.Counter;
public final class ContextListener implements ServletContextListener {
private ServletContext context = null;
public void contextInitialized(ServletContextEvent event) {
context = envent.getServletContext();
try {
BookDB bookDB = new BookDB();
context.setAttribute("bookDB", bookDB);
} catch (Exception ex) {
System.out.println("Couldn't create database: " + ex.getMessage());
}
Counter counter = new Counter();
context.setAttribute("hitCounter", counter);
context.log("Created hitCounter" + counter.getCounter());
counter = new Counter();
context.setAttribute("orderCounter", counter);
context.log("Created orderCounter" + counter.getCounter());
}
public void contextDestroyed(ServletContextEvent event) {
context = event.getServletContext();
BookDB bookDB = context.getAttribute("bookDB");
bookDB.remove();
context.removeAttribute("bookDB");
context.removeAttribute("hitCounter");
context.removeAttribute("orderCounter");
}
}
- Fornecem um meio para interceptar requisições;
- Implementam o padrão de projeto Chain Of Responsability;
- Permitem que uma requisição seja tratada antes de um servlet ou antes de páginas JSP;
- Permitem cancelar uma requisição;
- Permitem injetar requisitos de arquitetura de forma transparente para o restante da aplicação.
- Autenticação;
- Log;
- Auditoria.
- Pesquisar a requisição e atuar atualizando seus valores;
- Bloquear a requisição;
- Modificar a requisição (dados e headers);
- Modificar a resposta.
- Acessível para toda a aplicação;
- Iniciado quando a aplicação é instalada no container;
- Objeto: ServletContext;
Método
getServletContext()
- Provê métodos para acessar:
- Parâmetros de inicialização;
- Recursos associados com o contexto web;
- Objeto ou valores associados ao contexto;
- Facilidades de log.
public final class HitCounterFilter implements Filter {
private FilterConfig filterConfig = null;
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain) throws IOExeption, ServletException {
...
StringWriter sw = new StringWriter();
PrintWriter writer = new PrintWriter();
ServletContext context = filterConfig.getServletContext();
Counter counter = (Counter) context.getAttribute("hitCounter");
...
writer.println("The number of hits is: " + counter.incCounter());
...
context.log(sw.getBuffer().toString());
...
}
}
- Geralmente aplicações necessitam associar requisições de um mesmo cliente;
- Por exemplo, salvar o carrinho de compras do cliente alvo;
- Este estado é chamado de sessão;
HttpSession
;HttpServletRequest->getSession()
;- Permite a associação de objetos ou valores à sessão do usuário;
- Timeout:
Via código:
set/getMaxInactiveInterval()
; Via configuração:web.xml - <timeout>
.
- Logoff:
session.invalidate()
- Se os cookies forem desabilitados no browser você deve garantir o URL rewriting para todos os links e chamadas.
public class CashierServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// Pega a sessão do usuário e o carrinho de compras
HttpSession session = request.getSession();
ShoppingCart cart = (ShoppingCart) session.getAttribute("cart");
...
// Determina o preço total dos livros do usuários
double total = cart.getTotal();
}
}
out.println("<strong><a href=\"" +
response.encodeURL(request.getContextPath() + "/catalog") +
"\">" + messages.getString("ContinueShopping") +
"</a> " +
"<a href=\"" +
response.encodeURL(response.getContextPath() + "/cashier") +
"\">" + messages.getString("Checkout") +
"</a> " +
response.encodeURL(request.getContextPath() + "/showcart?Clear=clear") +
"\">" + messages.getString("ClearCart") +
"</a></strong>");
> http://localhost:8080/bookstore1/cashier;jsessionid=c0o7fszeb1