Springboot项目快速实现拦截器功能

针对“Springboot项目快速实现拦截器功能”,我可以提供以下完整攻略:

1. 引入依赖

在pom.xml中添加如下依赖:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>2.4.3</version>
</dependency>

2. 编写拦截器

在springBoot中,实现自定义拦截器需要实现HandlerInterceptor接口,该接口包含三个方法:

  • preHandle():在请求处理之前进行调用(Controller方法调用之前)。
  • postHandle():请求处理之后进行调用,但是在视图被渲染之前,即在返回ModelAndView之前调用(Controller方法调用之后)。
  • afterCompletion():在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要用于清理资源等工作)。

下面给出一个简单的示例代码,可以实现对请求的耗时进行统计的功能:

public class TimeInterceptor implements HandlerInterceptor {
  private static final Logger logger = LoggerFactory.getLogger(TimeInterceptor.class);

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      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");
      logger.info("请求耗时:{} ms", System.currentTimeMillis() - startTime);
  }

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

3. 注册拦截器

在springBoot中,需要通过WebMvcConfigurer来注册拦截器,示例代码如下:

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
      registry.addInterceptor(new TimeInterceptor()).addPathPatterns("/**");
  }
}

其中,addPathPatterns("/**")表示需要拦截所有请求。

示例1

在上面的示例中,我们只是简单地打印了请求的耗时。现在我们来看一个更加实际一些的例子。

需求:拦截需要登录的接口,只有在登录状态下才能访问。

首先,我们需要在HttpServletRequest中获取session中的信息判断是否登录,示例代码如下:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    HttpSession session = request.getSession();
    Object user = session.getAttribute("userInfo");
    if (user == null) {
        response.sendRedirect("/login");
        return false;
    }
    return true;
}

在上面代码中,我们判断了session中是否存在userInfo信息,如果不存在,则跳转到登录页面。如果存在,则直接返回true,表示继续执行下面的接口方法。

示例2

除了判断登录状态外,我们还可以在拦截器中进行一些其他的业务逻辑,在这里我们思考一个接口访问频率限制的问题。

需求:拦截某个接口,如果一段时间内(比如1秒钟)请求的次数超过一定的阈值(比如10次),则拒绝该请求。

通过使用redis记录该接口的访问次数,并配合定时任务刷新次数,可以实现该功能。具体实现代码如下:

public class RequestLimitInterceptor implements HandlerInterceptor {
  private static final Logger logger = LoggerFactory.getLogger(RequestLimitInterceptor.class);

  private RedisTemplate<String, Integer> redisTemplate;

  @Autowired
  public void setRedisTemplate(RedisTemplate<String, Integer> redisTemplate) {
      this.redisTemplate = redisTemplate;
  }

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      String requestUri = request.getRequestURI();
      String redisKey = "req_limit:" + requestUri;

      // 访问次数加1
      Integer count = redisTemplate.opsForValue().get(redisKey);
      if (count == null) {
          redisTemplate.opsForValue().set(redisKey, 1, 1, TimeUnit.SECONDS);
      } else {
          if (count > 10) {
              response.getWriter().write("请求过于频繁");
              logger.warn("请求过于频繁,URI={}", requestUri);
              return false;
          } else {
              redisTemplate.opsForValue().increment(redisKey, 1);
          }
      }
      return true;
  }

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

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

其中,我们使用了redis来记录该接口的访问次数,并设置了1秒钟的过期时间。当访问次数超过10次时,直接返回错误信息。

总结

上述就是实现自定义拦截器的完整攻略,包括引入依赖、编写拦截器、注册拦截器以及两个示例。需要注意的是,在实际项目中,我们还需要考虑一些其他的问题,比如拦截器的执行顺序、多个拦截器的综合作用等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot项目快速实现拦截器功能 - Python技术站

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

相关文章

  • 为Java应用程序添加退出事件响应

    为Java应用程序添加退出事件响应可以通过以下步骤完成: 步骤一:创建一个ShutdownHook线程 在Java中,我们可以创建一个特殊的线程来处理应用程序退出时的清理工作,这个线程称为ShutdownHook线程。我们需要在应用程序启动时创建这个线程,并且在应用程序退出时执行它所要完成的清理工作。 可以使用以下代码创建一个ShutdownHook线程: …

    Java 2023年6月15日
    00
  • idea hibernate jpa 生成实体类的实现

    一、背景 在Java开发中,使用Hibernate和JPA框架是十分常见的,而手动编写实体类的过程比较繁琐,也容易出现错误。因此,我们可以使用IDEA来帮助我们自动生成实体类。 二、环境要求 IDEA集成开发环境 Hibernate框架和JPA的支持 三、具体步骤 添加Hibernate和JPA的支持 在新建项目或者已有项目的配置文件中,打开“Externa…

    Java 2023年5月20日
    00
  • 详解@ConfigurationProperties实现原理与实战

    详解@ConfigurationProperties实现原理与实战 什么是@ConfigurationProperties @ConfigurationProperties是Spring Boot提供的一种基于类型安全的配置方式。它可以方便地将properties文件中的属性映射到Java Bean中。可以通过@ConfigurationProperties…

    Java 2023年6月16日
    00
  • Java基础知识精通二维数组的应用

    关于“Java基础知识精通二维数组的应用”的完整攻略,我将详细介绍如下: 一、了解什么是二维数组 在Java中,二维数组是指由多个一维数组组成的数组,每个一维数组又包含多个元素,相当于一个表格或矩阵。 二维数组的定义格式如下: 类型[][] 数组名 = new 类型[行数][列数]; 例如: int[][] arr = new int[3][2]; //定义…

    Java 2023年5月26日
    00
  • Java +Tomcat + SpringMVC实现页面访问示例解析

    Java + Tomcat + SpringMVC实现页面访问示例解析 Java + Tomcat + SpringMVC是一种常见的Web开发技术栈,它们可以协同工作来实现Web应用程序的开发。本文将详细讲解如何使用Java + Tomcat + SpringMVC实现页面访问,并提供两个示例来说明如何实现这一过程。 步骤一:搭建开发环境 在开始使用Jav…

    Java 2023年5月17日
    00
  • java8时间 yyyyMMddHHmmss格式转为日期的代码

    下面是详细的攻略。 1. 确定需求 首先,我们需要明确我们的需求是将一个以yyyyMMddHHmmss格式表示的日期时间字符串转换成日期对象。 2. 寻找合适的API 根据Java8的官方文档,我们可以使用java.time.format.DateTimeFormatter类中的parse方法进行字符串解析,将字符串转换为java.time.LocalDat…

    Java 2023年5月20日
    00
  • 详解数据库连接的URL的写法及总结

    详解数据库连接的URL的写法及总结攻略分为以下几个部分: URL格式介绍 URL参数介绍 常用数据库URL示例 URL格式介绍 数据库连接URL的格式通常如下所示: protocol://username:password@hostname:port/databasename?option1=value1&option2=value2 其中,各部分的…

    Java 2023年6月16日
    00
  • servlet之session工作原理简介_动力节点Java学院整理

    我来讲解一下。 Servlet之Session工作原理简介 什么是Session Session是服务器端技术,用于在服务器端保存客户端的数据。 Session的原理 客户端第一次访问服务器时,服务器会创建一个session,并将session的id返回给客户端,客户端在接下来的请求中会将这个id带上。 服务器接收到客户端请求后,根据客户端带来的id找到对应…

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