Java自定义拦截器

在 Java 的 Spring Boot + MyBatisSpring MVC 项目中,可以通过 拦截器(Interceptor) 来拦截请求、修改 SQL 语句、记录日志等。拦截器的使用方式因不同的场景而有所不同。以下是几种常见的自定义拦截器实现方式。

1.MyBatis 拦截器(拦截 SQL 执行)

MyBatis 提供拦截器机制,可以拦截 SQL 执行前后,实现 SQL 解析、日志记录、权限控制、动态表名等功能。

1.1 创建mybatis拦截器

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;

import java.sql.Connection;
import java.util.Properties;

// @Intercepts 注解指定要拦截的方法
@Intercepts({
    @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class MyBatisSqlInterceptor implements Interceptor {
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取 StatementHandler
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        
        // 获取 SQL
        String sql = statementHandler.getBoundSql().getSql();
        System.out.println("拦截的 SQL:" + sql);

        // 这里可以修改 SQL,比如增加 WHERE 过滤条件
        // 修改 SQL 逻辑(示例:追加一个 WHERE 条件)
        // sql = sql + " AND user_id = 123";

        return invocation.proceed(); // 继续执行 SQL
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this); // 代理
    }

    @Override
    public void setProperties(Properties properties) {
        // 这里可以读取配置
    }
}

1.2 注册拦截器

Spring Boot + MyBatis 中,需要手动注册 MyBatis 插件

import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatisConfig {

    @Bean
    public MyBatisSqlInterceptor sqlInterceptor() {
        return new MyBatisSqlInterceptor();
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(org.apache.ibatis.session.Configuration configuration) throws Exception {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactory();
        configuration.addInterceptor(sqlInterceptor()); // 添加拦截器
        return sqlSessionFactory;
    }
}

1.3 应用场景

sql日志:记录sql执行信息

权限控制:可以动态修改sql

自动分表:修改表名

数据脱敏:对查询的结果进行敏感信息处理

2. Spring MVC 拦截器(拦截 HTTP 请求)

如果需要 拦截 HTTP 请求(Controller 方法调用前后),可以使用 Spring MVC 拦截器。

2.1 创建spring MVC 拦截器

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class MyHttpInterceptor implements HandlerInterceptor {

    // 在 Controller 方法调用前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截 HTTP 请求:" + request.getRequestURI());
        
        // 进行权限验证
        String token = request.getHeader("Authorization");
        if (token == null || !token.equals("VALID_TOKEN")) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("Unauthorized");
            return false; // 拦截请求,不继续执行
        }
        return true; // 继续执行
    }

    // 在 Controller 方法调用后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("Controller 处理完毕");
    }

    // 在视图渲染后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("HTTP 请求完成");
    }
}

2.2 注册拦截器

在spring boot 配置类中注册拦截器

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyHttpInterceptor())
                .addPathPatterns("/api/**")  // 只拦截 /api/ 开头的路径
                .excludePathPatterns("/api/login"); // 不拦截登录接口
    }
}

应用场景:

权限控制:拦截未登录请求

日志记录:记录请求参数,响应时间

防止重复提交:拦截表单提交请求

3. Spring AOP 拦截器(拦截调用方法)

如若需要拦截所有Service/Contoller方法,可以使用Spring AOP

3.1 创建aop拦截器

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAopInterceptor {

    @Around("execution(* com.example.service.*.*(..))") // 拦截 service 包下所有方法
    public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        
        System.out.println("方法执行前:" + joinPoint.getSignature().getName());

        Object result = joinPoint.proceed(); // 执行目标方法

        long end = System.currentTimeMillis();
        System.out.println("方法执行后:" + joinPoint.getSignature().getName() + ",耗时:" + (end - start) + "ms");

        return result;
    }
}

应用场景:

方法执行时间的统计

日志记录

参数校验

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值