java中的Filter(过滤器)和Intercepter(拦截器)的认知
一、过滤器的配置
- 首先,从认知方面看,如果自己真的对Filter和Intercepter 不熟悉或者忘记的话可以自己在IDEA中编写Demo进行查看两个的区别,这也是自己动手去认知的过程。首先从Filter开始
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("TestFilter init 完成");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("执行TestFilter doFIlter");
}
@Override
public void destroy() {
System.out.println("TestFilter destroy");
}
}
以上代码在项目启动的时候会初始化FIlter。
ps:如果Filter要使请求继续被处理,就一定要调用filterChain.doFilter()!
代码很直观的看出Filter是基于Servlet。我们点击Filter的源码进行查看,看看里面是干了什么。比如注释什么的解释的很清楚。执行流程如下:
过滤器的应用场景:
以下是来自Filter的官方解释
Filters are configured in the deployment descriptor of a web application
Examples that have been identified for this design are
- Authentication Filters //身份验证过滤器
- Logging and Auditing Filters // 记录和审计过滤器
- Image conversion Filters // 图像转换过滤器
- Data compression Filters //数据压缩过滤器
- Encryption Filters //加密过滤器
- Tokenizing Filters //标记过滤器
- Filters that trigger resource access events //触发资源访问事件的过滤器
- XSL/T filters //XSLT 过滤器
- Mime-type chain Filter
- 配置Filter交给Spring管理
方式1
使用@Component+@Order
在TestFilter 类上加@Compoent 和@Order(1) 注解 即可把当前的Filter交给Spring管理。当有多个Filter时,这里的@Order(1)注解会指定执行顺序,数字越小,越优先执行,如果只写@Order,默认顺序值是Integer.MAX_VALUE。
@Component + @Order 注解方式配置简单,支持自定义 Filter 顺序。缺点是只能拦截所有URL,不能通过配置去拦截指定的 URL。
方式2
使用@WebFilter+@ServletComponentScan
@ServletComponentScan 可加在当前Filter类上,也可加在启动类上。
方式3
使用javaConfig配置类
@Configuration
public class FilterConfig {
@Bean
public FilterBean filterBean(){
FilterBean <TestFilter> bean = new FilterBean<>();
bean.setOrder(1);
bean.setFilter(new TestFilter());
// 匹配"/test/"下面的所有url
bean.addUrlPatterns("/test/*");
return bean;
}
@Bean
public FilterBean2 filterBean2(){
FilterBean2 <TestFilter2> bean = new FilterBean2<>();
bean.setOrder(2);
bean.setFilter(new TestFilter2());
// 匹配所有url
bean.addUrlPatterns("/*");
return bean;
}
}
使用@Component/@Order 注解 和 使用Config配置Filter的对比
首先定义两个Filter ,一个是使用@Component/@Order 一个是使用配置文件FilterRegistrationBean
@Component
@Order(-1)
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("TestFilter init 完成");
}
/**
* 需要忽略的地址
*/
private static final String[] IGNORES = new String[]{
"/"
};
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
long start = System.currentTimeMillis();
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("TestFilter Execute cost="+(System.currentTimeMillis()-start));
}
@Override
public void destroy() {
System.out.println("TestFilter destroy销毁");
}
}
FilterRegistrationBeanConfig配置类
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new LogCostFilter());
registration.addUrlPatterns("/*");
registration.setName("LogCostFilter");
registration.setOrder(2);
return registration;
}
}
public class LogCostFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
long start = System.currentTimeMillis();
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("Execute cost="+(System.currentTimeMillis()-start));
}
}
执行结果是根据设置的优先级来的。
注意说明:使用@WebFilter注解的属性
属性名 | 类型 | 描述 |
---|---|---|
filterName | String | 指定过滤器的 name 属性,等价于filter-name |
value | String[] | 该属性等价于 urlPatterns 属性。但是两者不应该同时使用 |
urlPatterns | String[] | 指定一组过滤器的 URL 匹配模式。等价于 标签。 |
servletNames | String[] | 指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中 的取值。 |
dispatcherTypes | DispatcherType | 指定过滤器的转发模式。具体取值包括: ASYNC、ERROR、FORWARD、INCLUDE、REQUEST。 |
initParams | WebInitParam[] | 指定一组过滤器初始化参数,等价于 标签。 |
asyncSupported | boolean | 声明过滤器是否支持异步操作模式,等价于 标签。 |
description | String | 该过滤器的描述信息,等价于 标签。 |
displayName | String | 该过滤器的显示名,通常配合工具使用,等价于 标签。 |
执行顺序
比如:
encodingFilter.java
permissionFilter.java
先执行encodingFilter.java在执行permissionFilter.java
二、拦截器的配置
- 首先我们实现拦截器类:
public class TestInterceptor implements HandlerInterceptor {
long start = System.currentTimeMillis();
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
start = System.currentTimeMillis();
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
这里我们需要实现HandlerInterceptor这个接口,这个接口包括三个方法,
- preHandle是请求执行前执行的,
- postHandler是请求结束执行的,但只有preHandle方法返回true的时候才会执行,
- afterCompletion是视图渲染完成后才执行,同样需要preHandle返回true,该方法通常用于清理资源等工作。除了实现上面的接口外,我们还需对其进行配置:
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
这里我们继承了WebMVCConfigurerAdapter,在进行静态资源目录配置的时候我们用到过这个类。这里我们重写了addInterceptors这个方法,进行拦截器的配置,主要配置项就两个,一个是指定拦截器,第二个是指定拦截的URL。现在我们再启动系统访问任意一个URL即可。
最新文章
- Sicily 1151: 简单的马周游问题(DFS)
- C# ADO.NET编写简单的图书馆管理软件
- Jquery 随便写些知识点
- How to take partial screenshot with Selenium WebDriver in python
- 转:随机函数 C++中rand()函数的用法
- Win7中隐藏的上帝模式——GodMode
- JAVA多线程学习1
- 认识FiddlerScript
- hdu 4666 Hyperspace
- 宣布与 NBC 合作直播索契冬季奥运
- 屏幕编程 F4的帮组用法
- HDU更多的学校比赛9场 HDU 4965Fast Matrix Calculation【矩阵运算+数学技巧】
- Windows 下安装 Oracle 12c 教程
- 【Android Studio安装部署系列】四、Android SDK目录和作用分析
- 关于freemarker 空变量的接收以及类型转换 笔记
- java和maven环境变量设置,Tomcat部署
- Mac定时关机、重启、休眠命令行
- java对PDF文档的各种操作
- transform子元素,绝对定位失效
- 2017年浙江工业大学大学生程序设计迎新赛预赛 H - 栗酱的文明
热门文章
- react 高效高质量搭建后台系统 系列 —— 表格的封装
- HTML5 + canvas 汽车赛道,飙车游戏(附源码)
- C++_关键字explicit
- 代码随想录算法训练营day12 | leetcode 239. 滑动窗口最大值 347.前 K 个高频元素
- echart4和echarts5同时引入方法
- el-input只能输入数字和小数
- 张量局部保留投影TensorLPP
- Reverse for &#39;blog_detail.html&#39; not found.解决方法
- 把逗号分隔的String字符串转List<;Integer>;
- 面向对象程序设计第三次blog