Configuração e Teste de Interceptors
Interceptors no Spring MVC permitem interceptar requisições antes e depois do processamento pelos handlers. Eles são úteis para tarefas como autenticação, logging e manipulação de dados comuns.
1. Definição de Interceptors
Crie duas classes que implementam a interface HandlerInterceptor. Cada classe deve sobrescrever os métodos preHandle, postHandle e afterCompletion.
Primeiro Interceptor:
package com.exemplo.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class PrimeiroInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest requisicao, HttpServletResponse resposta, Object manipulador) throws Exception {
System.out.println("PrimeiroInterceptor: método preHandle executado");
return true; // Permite a continuação da requisição
}
@Override
public void postHandle(HttpServletRequest requisicao, HttpServletResponse resposta, Object manipulador, ModelAndView modeloVisao) throws Exception {
System.out.println("PrimeiroInterceptor: método postHandle executado");
}
@Override
public void afterCompletion(HttpServletRequest requisicao, HttpServletResponse resposta, Object manipulador, Exception excecao) throws Exception {
System.out.println("PrimeiroInterceptor: método afterCompletion executado");
}
}
Segundo Interceptor:
package com.exemplo.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class SegundoInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest requisicao, HttpServletResponse resposta, Object manipulador) throws Exception {
System.out.println("SegundoInterceptor: método preHandle executado");
return true;
}
@Override
public void postHandle(HttpServletRequest requisicao, HttpServletResponse resposta, Object manipulador, ModelAndView modeloVisao) throws Exception {
System.out.println("SegundoInterceptor: método postHandle executado");
}
@Override
public void afterCompletion(HttpServletRequest requisicao, HttpServletResponse resposta, Object manipulador, Exception excecao) throws Exception {
System.out.println("SegundoInterceptor: método afterCompletion executado");
}
}
2. Configuração dos Interceptors
No arquivo de configuração do Spring MVC (por exemplo, spring-mvc.xml), defina os interceptors globalmente. O framework injetará esses interceptors em cada HandlerMapping.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.exemplo.interceptor.PrimeiroInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.exemplo.interceptor.SegundoInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
Uma abordagem alternativa é configurar interceptors diretamente em um HandlerMapping específico, mas isso não é recomendado para uso geral.
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="primeiroInterceptor"/>
<ref bean="segundoInterceptor"/>
</list>
</property>
</bean>
<bean id="primeiroInterceptor" class="com.exemplo.interceptor.PrimeiroInterceptor"/>
<bean id="segundoInterceptor" class="com.exemplo.interceptor.SegundoInterceptor"/>
3. Teste da Ordem de Execução
Quando ambos os interceptors permitem a passagem (retornam true no preHandle), a ordem de execução dos métodos segue um padrão específico. Considere dois interceptors configurados na ordem PrimeiroInterceptor e SegundoInterceptor:
preHandleé executado na ordem de configuração.postHandleeafterCompletionsão executados na ordem inversa da configuração.
Exemplo de saída no console:
PrimeiroInterceptor: método preHandle executado
SegundoInterceptor: método preHandle executado
SegundoInterceptor: método postHandle executado
PrimeiroInterceptor: método postHandle executado
SegundoInterceptor: método afterCompletion executado
PrimeiroInterceptor: método afterCompletion executado
Essa ordem é importante para cenários como logging global (colocado primeiro) ou autenticação (colocado antes de outros interceptors).
Exemplo: Interceptor de Autenticação
Implemente um interceptor para autenticação de usuários. A lógica deve permitir o acesso a URLs públicas, redirecionar para a página de login se a sessão não existir, e permitir acesso se a sessão contiver informações do usuário.
Controlador de Login
package com.exemplo.controller;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class ControladorLogin {
@RequestMapping("/entrar")
public String autenticar(HttpSession sessao, @RequestParam String usuario, @RequestParam String senha) throws Exception {
// Validar credenciais (simulado)
if ("admin".equals(usuario) && "senha123".equals(senha)) {
sessao.setAttribute("usuarioAutenticado", usuario);
return "redirect:/produtos/listar";
}
return "redirect:/entrar";
}
@RequestMapping("/sair")
public String encerrarSessao(HttpSession sessao) throws Exception {
sessao.invalidate();
return "redirect:/produtos/listar";
}
}
Interceptor de Autenticação
package com.exemplo.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
public class InterceptorAutenticacao implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest requisicao, HttpServletResponse resposta, Object manipulador) throws Exception {
String url = requisicao.getRequestURI();
// URLs públicas que não requerem autenticação
if (url.endsWith("/entrar")) {
return true;
}
HttpSession sessao = requisicao.getSession();
Object usuario = sessao.getAttribute("usuarioAutenticado");
if (usuario != null) {
return true;
}
// Redirecionar para página de login se não autenticado
resposta.sendRedirect(requisicao.getContextPath() + "/WEB-INF/paginas/login.jsp");
return false;
}
@Override
public void postHandle(HttpServletRequest requisicao, HttpServletResponse resposta, Object manipulador, org.springframework.web.servlet.ModelAndView modeloVisao) throws Exception {
// Não requer implementação neste exemplo
}
@Override
public void afterCompletion(HttpServletRequest requisicao, HttpServletResponse resposta, Object manipulador, Exception excecao) throws Exception {
// Não requer implementação neste exemplo
}
}
Configuração do Interceptor de Autenticação
No arquivo de configuração do Spring MVC, adicione o intercpetor de autenticação antes de outros interceptors, se necessário.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.exemplo.interceptor.InterceptorAutenticacao"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.exemplo.interceptor.PrimeiroInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
Página de Login
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Autenticação do Sistema</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/entrar" method="post">
Usuário: <input type="text" name="usuario" /><br/>
Senha: <input type="password" name="senha" /><br/>
<input type="submit" value="Entrar"/>
</form>
</body>
</html>