当前位置:首页 > Java 框架原理百科 > 正文

Java优学网SpringMVC拦截器教程:轻松实现请求统一处理,告别重复代码烦恼

1.1 拦截器的魅力所在

想象一下这样的场景:你的Web应用需要统一处理用户请求,比如检查登录状态、记录操作日志、验证权限。如果每个Controller方法都重复这些代码,维护起来会是场噩梦。SpringMVC拦截器就是为解决这类问题而生。

拦截器提供了一种优雅的切面编程方式。它能在请求到达Controller之前、Controller处理之后、视图渲染完成之后这三个关键节点插入自定义逻辑。这种设计模式让业务代码保持纯净,将横切关注点集中处理。

我记得第一次使用拦截器时,原本需要半天才能完成的权限校验功能,只用了不到一小时就搞定了。那种"原来可以这么简单"的惊喜感至今难忘。

1.2 行前准备

在学习拦截器之前,建议你具备一些基础知识。Spring框架的基本概念是必须的,特别是依赖注入和AOP思想。对Servlet API的理解也会很有帮助,毕竟SpringMVC构建在Servlet之上。

Maven或Gradle的使用经验能让项目搭建更顺利。如果你已经写过简单的SpringMVC应用,了解Controller和RequestMapping的基本用法,那就更好了。

实际上,拦截器的学习门槛并不高。只要你有Java基础,跟着教程一步步来,很快就能掌握。我教过的很多初学者都能在一周内熟练运用拦截器解决实际问题。

1.3 拦截器与过滤器的区别之旅

很多人容易混淆拦截器和过滤器,它们确实有些相似,但定位完全不同。

Java优学网SpringMVC拦截器教程:轻松实现请求统一处理,告别重复代码烦恼

过滤器是Servlet规范的一部分,工作在更底层。它能过滤所有请求,包括静态资源。而拦截器是SpringMVC框架的组件,只对DispatcherServlet处理的请求生效。

从功能上看,拦截器能获取到Spring的Bean,与Spring生态无缝集成。过滤器则相对独立,无法直接使用Spring的依赖注入。

执行时机也有差异。过滤器的执行在拦截器之前,当请求进入Servlet容器时首先经过过滤器链。拦截器则在DispatcherServlet内部工作,能精确控制preHandle、postHandle、afterCompletion三个时间点。

选择哪个?一般来说,与Spring深度集成的功能用拦截器,通用的、与框架无关的处理用过滤器。这个经验法则在大多数场景下都适用。 @Component public class RequestLogInterceptor implements HandlerInterceptor {

Java优学网SpringMVC拦截器教程:轻松实现请求统一处理,告别重复代码烦恼

private static final Logger logger = LoggerFactory.getLogger(RequestLogInterceptor.class);

@Override
public boolean preHandle(HttpServletRequest request, 
                       HttpServletResponse response, 
                       Object handler) {
    long startTime = System.currentTimeMillis();
    request.setAttribute("startTime", startTime);
    
    logger.info("收到请求: {} {}, 参数: {}", 
               request.getMethod(), 
               request.getRequestURI(),
               request.getQueryString());
    return true;
}

@Override
public void afterCompletion(HttpServletRequest request,
                          HttpServletResponse response,
                          Object handler,
                          Exception ex) {
    long startTime = (Long) request.getAttribute("startTime");
    long endTime = System.currentTimeMillis();
    
    logger.info("请求处理完成: {} {}, 耗时: {}ms",
               request.getMethod(),
               request.getRequestURI(),
               (endTime - startTime));
}

}

@Override public boolean preHandle(HttpServletRequest request,

                    HttpServletResponse response, 
                    Object handler) throws Exception {
HttpSession session = request.getSession();
Object user = session.getAttribute("currentUser");

if (user == null) {
    response.sendRedirect("/login");
    return false; // 中断请求链
}
return true;

}

@Configuration public class WebMvcConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LogInterceptor())
            .addPathPatterns("/**")
            .order(1);
            
    registry.addInterceptor(new AuthInterceptor())
            .addPathPatterns("/admin/**")
            .order(2);
            
    registry.addInterceptor(new PermissionInterceptor())
            .addPathPatterns("/admin/advanced/**")
            .order(3);
}

}

你可能想看:

相关文章:

文章已关闭评论!