Filter和Interceptor

Filter过滤器和拦截器Interceptor

1. 简介

过滤器和拦截器,在功方面很类似,但在具体实现方面差距还是很大;

过滤器出现的时间早于拦截器

2. 添加依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

3. 过滤器

需求: 统计每个ip访问某个controller的次数

3.1 编写逻辑

注意filter的包路径为 javax.servlet.*

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.health.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

@WebFilter(urlPatterns = "/*") //表示拦截的范围
public class Myfilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//将接口转为实现类
HttpServletRequest request = (HttpServletRequest) servletRequest;
//通过getRemoteAddr 获取客户端 IP 地址
String ip = request.getRemoteAddr();
//获取会话对象
HttpSession session = request.getSession();
//从 HttpSession 对象中获取指定名称的属性值。
Integer count = (Integer) session.getAttribute("count");
//如果count为null则默认1不为null则自增
count = Objects.isNull(count)?1:++count;
System.out.println("ip:"+ip+"\tcount:"+count);
//将新的count值存入session中
session.setAttribute("count", count);

filterChain.doFilter(servletRequest, servletResponse);
}
}

3.2 在启动类加上注解

@ServletComponentScan(basePackages = "org.example.filter")

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan(basePackages = "org.example.filter")
public class TestApplication {

public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}

3.拦截器

需求: 统计每个ip访问某个controller的次数

3.1 编写逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package org.example;


import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;

public class MyInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//通过getRemoteAddr 获取客户端 IP 地址
String ip = request.getRemoteAddr();
//获取会话对象
HttpSession session = request.getSession();
//从 HttpSession 对象中获取指定名称的属性值。
Integer count = (Integer) session.getAttribute("count");
//如果count为null则默认1不为null则自增
count = Objects.isNull(count)?1:++count;
System.out.println("ip:"+ip+"\tcount:"+count);
//将新的count值存入session中
session.setAttribute("count", count);

//true表示放行
return true;
}
}

3.2 添加配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.example.config;

import org.example.MyInterceptor;
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 interceptorConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
MyInterceptor myInterceptor = new MyInterceptor();
registry.addInterceptor(myInterceptor) //加入拦截器
.addPathPatterns("/**") //加入拦截范围
.excludePathPatterns("/user/login"); //不需要拦截的路径
}
}

x.总结

  1. Filter依赖于Servlet容器,属于Servlet规范的一部分,而Interceptor依赖于SpringMvC框架
  2. Filter的生命周期由Servlet容器管理,而Interceptor通过IOC容器来管理,可通过注入等方式来获取其Bean的实例
  3. Filter可拦截所有web资源(包括Jsp, Servlet,静态资源),而Interceptor则只拦截Controller.

Filter和Interceptor
http://example.com/2024/01/26/过滤器和拦截器/
作者
kangkang
发布于
2024年1月26日
许可协议