|
| 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 | + |
| 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 | + |
0 commit comments