Uso de Interceptors no Framework Spring MVC

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.
  • postHandle e afterCompletion sã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>

Tags: Spring MVC interceptors Java Web autenticacao Servlet API

Publicado em 6-14 17:57 por Thomas