Spring MVC 拦截器 interceptor 用法详解

Spring MVC 拦截器(Interceptor)用法详解

什么是拦截器

拦截器是Spring MVC框架中的一种增强处理器,拦截器也可以称为过滤器(Filter)或者AOP实现,它可以在请求处理的过程中预处理请求、处理请求和处理完请求后进行后续处理。拦截器可以将特定的处理逻辑应用到整个应用程序或者某个特定的Controller中。

和Servlet的过滤器(Filter)相比较,拦截器可以获取Spring IoC容器中的Bean,并利用依赖注入和AOP技术对目标代码进行更具体的处理,因此拦截器的应用范围远比过滤器广泛。

使用拦截器的原因

拦截器本质上就是对目标请求进行预处理和后处理,它可以使得我们在请求处理的前后执行我们自己的代码,比如对请求进行安全性检查、记录日志等操作,而无需进入具体的业务处理逻辑中。拦截器对于那些不需要更复杂的过滤器逻辑,但又需要在某些场景中进行拦截和处理的场景非常适用。

拦截器的配置方法

事实上,在Spring MVC中使用拦截器非常简单,只需要完成以下三个步骤。

步骤一:拦截器的实现

实现自己的拦截器类,实现HandlerInterceptor接口,并实现以下三个方法:

public interface HandlerInterceptor {

   boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

   void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;

   void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}

三个接口方法的作用详解:

  • preHandle: 在请求之前进行调用,也就是在Controller方法调用之前。

  • postHandle: 在请求之后调用,也就是在Controller方法调用之后,但是渲染视图之前。

  • afterCompletion: 在整个请求处理完成后进行调用,也就是在视图渲染完毕或者调用方取消时(比如当请求出现异常)。

步骤二:拦截器的注册

拦截器的注册过程非常类似于Spring IoC容器对Bean的注册,只不过是使用了一种专门的注解@Configuration,然后将拦截器的实例化对象添加到spring的上下文之中。

以下是部分示例代码,并未涉及全部内容,请结合实际代码食用

示例一:对请求进行日志记录

目的:记录每个请求的url、请求参数、响应时间。

首先,我们需要编写一个拦截器类,键入以下代码:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LogInterceptor implements HandlerInterceptor {

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

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.info("Request [{}] URL: {}", request.getMethod(), request.getRequestURL().toString());
        logger.info("Request params: {}", request.getParameterMap().toString());
        request.setAttribute("startTime", System.currentTimeMillis()); //记录开始时间
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        long startTime = (long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        logger.info("Response time: {}ms", endTime - startTime);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // Do nothing here.
    }
}

我们通过实现HandlerInterceptor接口来实现自己的拦截器,这个拦截器简单地将请求的URL和参数记录到log中,并在请求结束时计算响应时间。

接下来,我们需要在Spring MVC中注册这个拦截器。打开Spring配置文件,新增如下配置:

<mvc:interceptors>
   <mvc:interceptor>
       <mvc:mapping path="/**" />
       <bean class="com.yourpackage.LogInterceptor" />
   </mvc:interceptor>
</mvc:interceptors>

这段配置包含了一个拦截器LogInterceptor和路径/**,意味着我们将会监控所有的请求并且记录下日志。

示例二:请求防重复提交

至于本例子的目的,由于网上很多存在前后端分离实现的方式,所以这里只针对后端表单提交进行课程。

  • 以提交的url为唯一性校验点,对重复提交进行防范。

在前端给提交按钮添加一个token字段,后端对于这个token进行判定,防止多次提交。

首先,我们需要在拦截器中保存已处理过的请求URL,实现如下:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashSet;
import java.util.Set;

public class TokenInterceptor implements HandlerInterceptor {
    private static final Set<String> URL_SET = new HashSet<>(); //保存请求URL

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        final String url = request.getRequestURL().toString();
        synchronized (URL_SET) {
            if (URL_SET.contains(url)) {
                return false;
            }
            URL_SET.add(url);
        }
        request.setAttribute("token", url);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        final String url = request.getAttribute("token").toString();
        synchronized (URL_SET) {
            URL_SET.remove(url);
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
}

接下来,我们需要在Spring MVC中注册这个拦截器:

<mvc:interceptors>
   <mvc:interceptor>
       <mvc:mapping path="/form" />
       <bean class="com.yourpackage.TokenInterceptor" />
   </mvc:interceptor>
</mvc:interceptors>

这段配置设置了拦截路径/form,意味只有带有该路径的请求才会进行防重复提交的拦截处理。

总结

本文介绍了Spring MVC中拦截器的使用方法,为开发者实现增强的请求处理提供了一种便利、高效的方式。值得注意的是,拦截器需要遵循Spring MVC部分原则,比如需要放在Contexts中,并且需要先于业务逻辑被执行。在设计拦截器的过程中,经验和设计能力至关重要。

文章仅作参考,请结合实际开发进行食用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring MVC 拦截器 interceptor 用法详解 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 解析MySql与Java的时间类型

    下面是“解析MySql与Java的时间类型”的完整攻略。 1. MySql时间类型 MySql中定义了多种时间类型,包括日期时间、时间戳、时间等。下面分别介绍不同时间类型的定义及其在Java中的映射类型。 1.1. DATETIME类型 DATETIME类型表示年、月、日、小时、分钟、秒。格式为:YYYY-MM-DD HH:MM:SS。 在Java中,可以使…

    Java 2023年5月20日
    00
  • java 将jsonarray 转化为对应键值的jsonobject方法

    将JSON数组转换为对应键值的JSON对象的过程可以通过Java编程实现。要使用Java转换JSON,我们可以使用Java中的org.json库。该库为JSON提供了一组内置API,可用于在Java应用程序中构建、解析和修改JSON内容。 下面是将JSONArray转换成具有对应键值的JSONObject的步骤: 1.从JSONArray中获取JSON对象的…

    Java 2023年5月26日
    00
  • Java拦截器Interceptor实现原理及代码示例

    Java拦截器Interceptor实现原理及代码示例 什么是拦截器Interceptor? 在Java开发中,拦截器是指在请求处理的过程中预先拦截到请求,然后对请求进行一些预处理和后处理的操作。作为一种通用的设计模式,拦截器在很多框架和技术中得到了广泛的应用。在Spring、Struts、Hibernate等诸多框架中都有拦截器的实现,拦截器也被认为是AO…

    Java 2023年6月15日
    00
  • java实现上传图片并压缩图片大小功能

    要实现Java上传图片并压缩图片大小的功能,我们可以通过以下步骤完成: Step 1: 添加依赖 我们需要向项目中添加一些依赖,以便能够操作图片。这里我们推荐使用 Thumbnails这个依赖库,可以简化图片处理操作。 <dependency> <groupId>net.coobird</groupId> <arti…

    Java 2023年5月19日
    00
  • 基于SpringBoot构建电商秒杀项目代码实例

    下面我会详细讲解“基于SpringBoot构建电商秒杀项目代码实例”的完整攻略。 1. 确定项目需求和技术栈 在开发之前,我们需要确定项目需求和技术栈。对于本项目来说,需求是搭建一个电商秒杀系统,技术栈是SpringBoot、MySQL、Redis和Thymeleaf。 2. 搭建项目环境 首先,需要安装Java、Maven、MySQL和Redis。然后使用…

    Java 2023年5月31日
    00
  • 一篇文章教带你了解Java Spring之自动装配

    一篇文章教带你了解Java Spring之自动装配 1. 理解什么是自动装配 在Spring中,依赖注入(DI)是实现对象之间解耦的一种常用方式。而自动装配(Autowiring)则是一种更加便利的依赖注入方式,它能够自动地为容器中需要注入的对象找到合适的实例。自动装配可以减少开发者对注入实例的手动处理,减少了代码冗余。 2. Spring的自动装配模式 S…

    Java 2023年5月19日
    00
  • Redis Plus 来了,性能炸裂!

    来源:https://developer.aliyun.com/article/705239 1 什么是KeyDB? KeyDB是Redis的高性能分支,专注于多线程,内存效率和高吞吐量。除了多线程之外,KeyDB还具有仅在Redis Enterprise中可用的功能,例如Active Replication,FLASH存储支持以及一些根本不可用的功能,例如…

    Java 2023年4月25日
    00
  • Spring Boot应用程序中如何使用Keycloak详解

    Spring Boot应用程序中如何使用Keycloak详解 Keycloak是一个强大的、开源、易于使用的认证和授权管理解决方案。Spring Boot提供了与Keycloak的集成,可以轻松地保护和管理您的应用程序。 本文将介绍如何在Spring Boot应用程序中快速集成Keycloak,以便您的Web应用程序能够以安全的方式使用它。 准备工作 在开始…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部