1. 过滤器
其实过滤器(Filter)跟Servlet很相似,都是java的一个组件。即请求发送到servlet之前,可以将其拦截和处理请求,也可以在serlvet结束工作之后,在响应发回之前处理响应,做一些事情。因此,可以理解为过滤器filter就是是拦截请求(request)和响应(response),并对传给请求资源的ServletRequest 或 ServletResponse 进行处理的一个对象。
1.1. 过滤器的使用场景
- 处理乱码问题;
- 统计request和response的时间,有助于我们分析代码的效率;
- 过滤非法请求路径
1.2. 过滤器的实现
依赖
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.3.5.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
具体实现
package com.example.filter;
import javax.servlet.*;
import java.io.IOException;
public class FirstFilter implements Filter{
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("进入第一个过滤器");
// 放行
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("第一个过滤器结尾工作");
}
}
将其纳入spring容器
package com.example.config;
import com.example.filter.FirstFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Configuration 是spring中的注解,它的作用:
* 1.将当前的类实例,然后纳入到IOC容器。
* 2.将其中的头顶上有 @Bean 的方法的返回值,纳入到IOC容器。
* @Component 也可以实现该功能
*
* 第一个bean纳入容器的方式相当于如下配置,id名是方法名
* <beans>
* <bean id=“webFilterConfig” class="org.example.config.WebFilterConfig"></bean>
* <bean id="getFirstFilter" class="org.example.filter.FirstFilter"></bean>
* </beans>
*
* 下面两种纳入容器方式选择其一,一般使用第二种
*/
@Configuration
public class WebFilterConfig {
// 将其纳入spring容器
@Bean
public FirstFilter firstFilter(){
return new FirstFilter();
}
// 设置其过滤器并纳入容器
@Bean
public FilterRegistrationBean<FirstFilter> filterRegistrationBean(){
FilterRegistrationBean<FirstFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new FirstFilter()); //将其注册
filterRegistrationBean.setName("firstFilter"); //设置过滤器名字
filterRegistrationBean.addUrlPatterns("/*"); //设置过滤范围
filterRegistrationBean.setOrder(1); //设置过滤等级,值越小越先过滤
return filterRegistrationBean;
}
}
2. 拦截器
在WebWork的中文文档的解释为—拦截器是动态拦截Action调用的对象。它提供了一种机制使开发者可以定义在一个Action执行的前后执行的代码,也可以在一个Action执行前阻止其执行。同时也提供了一种可以提取Action中可重用的部分的方式。
2.1 拦截器的使用场景
主要是对固定的controller进行拦截,可以指定其controller而不是针对所有controller
2.2 拦截器的实现
依赖
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.3.5.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
具体实现
package com.example.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FirstInterceptor implements HandlerInterceptor {
@Override
// 请求controller之前
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器");
return true;
}
@Override
// 请求controller之后
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("放行");
}
}
将其纳入spring容器
package com.example.config;
import com.example.interceptor.FirstInterceptor;
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 WebInterceptorConfig implements WebMvcConfigurer {
/**
* <mvc:interceptors>
* <mvc:interceptor>
* <!-- classpath:org/exmple/两个星星/*.xml, 这种语法在spring中叫 ant 语法 -->
* <mvc:mapping path="/user/**"></mvc:mapping>
* <mvc:mapping path="/person/**"></mvc:mapping>
* <mvc:exclude-mapping path="/user/edit"></mvc:exclude-mapping>
* <bean class="org.example.interceptor.UserInterceptor"></bean>
* </mvc:interceptor>
* </mvc:interceptors>
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 创建拦截器实例
FirstInterceptor firstInterceptor = new FirstInterceptor();
// 设置拦截器细节
registry.addInterceptor(firstInterceptor)
.addPathPatterns("/**/*")
.excludePathPatterns("/test");
}
}
3. 拦截器和过滤器的主要区别
- 实现原理不同:
过滤器和拦截器 底层实现方式大不相同,过滤器 是基于函数回调的,拦截器 则是基于Java的反射机制(动态代理)实现的。 - 使用范围不同:
过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用;而拦截器(Interceptor) 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。
参照https://www.zhihu.com/question/30212464/answer/1786967139