Skip to content

Commit b131aaf

Browse files
committed
spring boot 实现拦截器
1 parent 4bbb017 commit b131aaf

File tree

9 files changed

+312
-3
lines changed

9 files changed

+312
-3
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@
3333
3. **[Spring Boot 异常处理](./docs/advanced/springboot-handle-exception.md)**
3434
4. [使用 spring-boot-devtools 进行热部署](./docs/basis/spring-boot-devtools.md)
3535
5. **[ Spring Boot JPA 基础:常见操作解析](./docs/basis/springboot-jpa.md)**
36-
6. **[JPA 中非常重要的连表查询就是这么简单]()**
37-
7. [整合 SpringBoot+Mybatis](./docs/basis/springboot-mybatis.md)[SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./docs/basis/springboot-mybatis-mutipledatasource.md)
36+
6. **[JPA 中非常重要的连表查询就是这么简单](./docs/basis/springboot-jpa-lianbiao.md)**
37+
7. [SpringBoot 实现过滤器](./docs/basis/springboot-filter.md)
38+
8. [整合 SpringBoot+Mybatis](./docs/basis/springboot-mybatis.md)[SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./docs/basis/springboot-mybatis-mutipledatasource.md)
3839

3940
### 进阶
4041

docs/basis/springboot-filter.md

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
### 1. Filter 介绍
2+
3+
Filter 过滤器这个概念应该大家不会陌生,特别是对与从 Servlet 开始入门学 Java 后台的同学来说。那么这个东西我们能做什么呢?Filter 过滤器主要是用来过滤用户请求的,它允许我们对用户请求进行前置处理和后置处理,比如实现 URL 级别的权限控制、过滤非法请求等等。
4+
5+
如果我们需要自定义 Filter 的话非常简单,只需要实现 `javax.Servlet.Filter` 接口,然后重写里面的 3 个方法即可!
6+
7+
`Filter.java`
8+
9+
```java
10+
public interface Filter {
11+
12+
//初始化过滤器后执行的操作
13+
default void init(FilterConfig filterConfig) throws ServletException {
14+
}
15+
// 对请求进行过滤
16+
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
17+
// 销毁过滤器后执行的操作,主要用户对某些资源的回收
18+
default void destroy() {
19+
}
20+
}
21+
```
22+
23+
### 2. Filter是如何实现拦截的?
24+
25+
`Filter`接口中有一个叫做 `doFilter` 的方法,这个方法实现了对用户请求的过滤。具体流程大体是这样的:
26+
27+
1. 用户发送请求到 web 服务器,请求会先到过滤器;
28+
2. 过滤器会对请求进行一些处理比如过滤请求的参数、修改返回给客户端的 response 的内容、判断是否让用户访问该接口等等。
29+
3. 用户请求响应完毕。
30+
4. 进行一些自己想要的其他操作。
31+
32+
![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/filter1.png)
33+
34+
### 3. 如何自定义Filter
35+
36+
下面提供两种方法。
37+
38+
#### 3.1自己手动注册配置实现
39+
40+
自定义的 Filter 需要实现`javax.Servlet.Filter`接口,并重写接口中定义的3个方法。
41+
42+
`MyFilter.java`
43+
44+
```java
45+
/**
46+
* @author shuang.kou
47+
*/
48+
@Component
49+
public class MyFilter implements Filter {
50+
private static final Logger logger = LoggerFactory.getLogger(MyFilter.class);
51+
52+
@Override
53+
public void init(FilterConfig filterConfig) {
54+
logger.info("初始化过滤器:", filterConfig.getFilterName());
55+
}
56+
57+
@Override
58+
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
59+
//对请求进行预处理
60+
logger.info("过滤器开始对请求进行预处理:");
61+
HttpServletRequest request = (HttpServletRequest) servletRequest;
62+
String requestUri = request.getRequestURI();
63+
System.out.println("请求的接口为:" + requestUri);
64+
long startTime = System.currentTimeMillis();
65+
//通过 doFilter 方法实现过滤功能
66+
filterChain.doFilter(servletRequest, servletResponse);
67+
// 上面的 doFilter 方法执行结束后用户的请求已经返回
68+
long endTime = System.currentTimeMillis();
69+
System.out.println("该用户的请求已经处理完毕,请求花费的时间为:" + (endTime - startTime));
70+
}
71+
72+
@Override
73+
public void destroy() {
74+
logger.info("销毁过滤器");
75+
}
76+
}
77+
```
78+
79+
`MyFilterConfig.java`
80+
81+
```java
82+
@Configuration
83+
public class MyFilterConfig {
84+
@Autowired
85+
MyFilter myFilter;
86+
@Bean
87+
public FilterRegistrationBean<MyFilter> thirdFilter() {
88+
FilterRegistrationBean<MyFilter> filterRegistrationBean = new FilterRegistrationBean<>();
89+
90+
filterRegistrationBean.setFilter(myFilter);
91+
92+
filterRegistrationBean.setUrlPatterns(new ArrayList<>(Arrays.asList("/api/*")));
93+
94+
return filterRegistrationBean;
95+
}
96+
}
97+
```
98+
99+
#### 3.2 通过提供好的一些注解实现
100+
101+
在自己的过滤器的类上加上`@WebFilter` 然后在这个注解中通过它提供好的一些参数进行配置。
102+
103+
```java
104+
@WebFilter(filterName = "MyFilterWithAnnotation", urlPatterns = "/api/*")
105+
public class MyFilterWithAnnotation implements Filter {
106+
107+
......
108+
}
109+
```
110+
111+
另外,为了能让 Spring 找到它,你需要在启动类上加上 `@ServletComponentScan` 注解。
112+

source-code/basis/springboot-filter/src/main/java/github/javaguide/springbootfilter/SpringbootFilterApplication.java

+2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import org.springframework.boot.SpringApplication;
44
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.boot.web.servlet.ServletComponentScan;
56

67
@SpringBootApplication
8+
@ServletComponentScan
79
public class SpringbootFilterApplication {
810

911
public static void main(String[] args) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package github.javaguide.springbootfilter.config;
2+
3+
import github.javaguide.springbootfilter.filter.MyFilter;
4+
import github.javaguide.springbootfilter.filter.MyFilter2;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.boot.web.servlet.FilterRegistrationBean;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.context.annotation.Configuration;
9+
10+
import java.util.ArrayList;
11+
import java.util.Arrays;
12+
13+
@Configuration
14+
public class MyFilterConfig {
15+
@Autowired
16+
MyFilter myFilter;
17+
18+
@Autowired
19+
MyFilter2 myFilter2;
20+
21+
@Bean
22+
public FilterRegistrationBean<MyFilter> myFilter() {
23+
FilterRegistrationBean<MyFilter> filterRegistrationBean = new FilterRegistrationBean<>();
24+
filterRegistrationBean.setOrder(1);
25+
filterRegistrationBean.setFilter(myFilter);
26+
filterRegistrationBean.setUrlPatterns(new ArrayList<>(Arrays.asList("/api/*")));
27+
28+
return filterRegistrationBean;
29+
}
30+
31+
@Bean
32+
public FilterRegistrationBean<MyFilter2> myFilter2() {
33+
FilterRegistrationBean<MyFilter2> filterRegistrationBean = new FilterRegistrationBean<>();
34+
filterRegistrationBean.setOrder(2);
35+
filterRegistrationBean.setFilter(myFilter2);
36+
filterRegistrationBean.setUrlPatterns(new ArrayList<>(Arrays.asList("/api/*")));
37+
38+
return filterRegistrationBean;
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package github.javaguide.springbootfilter.filter;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.stereotype.Component;
6+
7+
import javax.servlet.Filter;
8+
import javax.servlet.FilterChain;
9+
import javax.servlet.FilterConfig;
10+
import javax.servlet.ServletException;
11+
import javax.servlet.ServletRequest;
12+
import javax.servlet.ServletResponse;
13+
import javax.servlet.http.HttpServletRequest;
14+
import java.io.IOException;
15+
16+
/**
17+
* @author shuang.kou
18+
*/
19+
@Component
20+
public class MyFilter implements Filter {
21+
private static final Logger logger = LoggerFactory.getLogger(MyFilter.class);
22+
23+
@Override
24+
public void init(FilterConfig filterConfig) {
25+
logger.info("初始化过滤器");
26+
}
27+
28+
@Override
29+
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
30+
//对请求进行预处理
31+
logger.info("过滤器开始对请求进行预处理:");
32+
HttpServletRequest request = (HttpServletRequest) servletRequest;
33+
String requestUri = request.getRequestURI();
34+
System.out.println("请求的接口为:" + requestUri);
35+
long startTime = System.currentTimeMillis();
36+
//通过 doFilter 方法实现过滤功能
37+
filterChain.doFilter(servletRequest, servletResponse);
38+
// 上面的 doFilter 方法执行结束后用户的请求已经返回
39+
long endTime = System.currentTimeMillis();
40+
System.out.println("该用户的请求已经处理完毕,请求花费的时间为:" + (endTime - startTime));
41+
}
42+
43+
@Override
44+
public void destroy() {
45+
logger.info("销毁过滤器");
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package github.javaguide.springbootfilter.filter;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.stereotype.Component;
6+
7+
import javax.servlet.Filter;
8+
import javax.servlet.FilterChain;
9+
import javax.servlet.FilterConfig;
10+
import javax.servlet.ServletException;
11+
import javax.servlet.ServletRequest;
12+
import javax.servlet.ServletResponse;
13+
import javax.servlet.http.HttpServletRequest;
14+
import java.io.IOException;
15+
16+
/**
17+
* @author shuang.kou
18+
*/
19+
@Component
20+
public class MyFilter2 implements Filter {
21+
private static final Logger logger = LoggerFactory.getLogger(MyFilter2.class);
22+
23+
@Override
24+
public void init(FilterConfig filterConfig) {
25+
logger.info("初始化过滤器2");
26+
}
27+
28+
@Override
29+
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
30+
//对请求进行预处理
31+
logger.info("过滤器开始对请求进行预处理2:");
32+
HttpServletRequest request = (HttpServletRequest) servletRequest;
33+
String requestUri = request.getRequestURI();
34+
System.out.println("请求的接口为2:" + requestUri);
35+
long startTime = System.currentTimeMillis();
36+
//通过 doFilter 方法实现过滤功能
37+
filterChain.doFilter(servletRequest, servletResponse);
38+
// 上面的 doFilter 方法执行结束后用户的请求已经返回
39+
long endTime = System.currentTimeMillis();
40+
System.out.println("该用户的请求已经处理完毕,请求花费的时间为2:" + (endTime - startTime));
41+
}
42+
43+
@Override
44+
public void destroy() {
45+
logger.info("销毁过滤器2");
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package github.javaguide.springbootfilter.filter;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
import javax.servlet.Filter;
7+
import javax.servlet.FilterChain;
8+
import javax.servlet.FilterConfig;
9+
import javax.servlet.ServletException;
10+
import javax.servlet.ServletRequest;
11+
import javax.servlet.ServletResponse;
12+
import javax.servlet.annotation.WebFilter;
13+
import javax.servlet.http.HttpServletRequest;
14+
import java.io.IOException;
15+
16+
@WebFilter(filterName = "MyFilterWithAnnotation", urlPatterns = "/api/annotation/*")
17+
public class MyFilterWithAnnotation implements Filter {
18+
19+
private static final Logger logger = LoggerFactory.getLogger(MyFilterWithAnnotation.class);
20+
21+
@Override
22+
public void init(FilterConfig filterConfig) {
23+
logger.info("初始化过滤器");
24+
}
25+
26+
@Override
27+
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
28+
//对请求进行预处理
29+
logger.info("过滤器开始对请求进行预处理:");
30+
HttpServletRequest request = (HttpServletRequest) servletRequest;
31+
String requestUri = request.getRequestURI();
32+
System.out.println("请求的接口为:" + requestUri);
33+
long startTime = System.currentTimeMillis();
34+
//通过 doFilter 方法实现过滤功能
35+
filterChain.doFilter(servletRequest, servletResponse);
36+
// 上面的 doFilter 方法执行结束后用户的请求已经返回
37+
long endTime = System.currentTimeMillis();
38+
System.out.println("该用户的请求已经处理完毕,请求花费的时间为:" + (endTime - startTime));
39+
}
40+
41+
@Override
42+
public void destroy() {
43+
logger.info("销毁过滤器");
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package github.javaguide.springbootfilter.web;
2+
3+
import org.springframework.web.bind.annotation.GetMapping;
4+
import org.springframework.web.bind.annotation.RequestMapping;
5+
import org.springframework.web.bind.annotation.RestController;
6+
7+
@RestController
8+
@RequestMapping("/api")
9+
public class MyController {
10+
11+
@GetMapping("/hello")
12+
public String getHello() throws InterruptedException {
13+
Thread.sleep(1000);
14+
return "Hello";
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-

0 commit comments

Comments
 (0)