Servlet、Filter、Intecepter、Listener
本文介绍下SpringBoot中如何对这几者的注册与使用
SpringBoot有两种方式注册Servlet、Filter、Listener
1、代码注册:使用 ServletRegistrationBean、 FilterRegistrationBean 和 ServletListenerRegistrationBean进行注册;
2、 在 SpringBootApplication上添加@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册
Servlet
servlet是一个用户请求。
servlet的匹配规则:从精确到模糊,匹配到之后不会管其他
比如:servlet1的url-pattern 是/test,serlet2的url-pattern是/*,访问的url为 http://localhost:8080/test ,容器就会先进行全路径匹配,发现正好被servlet1精确匹配,就不会去管servlet2
1、通过@ServletComponentScan自动扫描注册
①在springboot入口程序除添加 @ServletComponentScan
1 |
|
②使用@WebServlet自定义Servlet,配置请求路径为/demo/servlet1
可配置参数如下

代码如下:
1 |
|
请求结果:

2、通过@ServletRegistrationBean注解注册
① 自定义Servler,此时只需继承HttpServlet即可
1 | public class MyServlet2 extends HttpServlet { |
② 使用 ServletRegistrationBean注入bean
注意:添加@Configuration是定义配置类,将ServletRegistrationBean注入容器即可实现Servlet
1 |
|
请求结果:

Filter
Filter:过滤器,对请求进行过滤,可对请求、响应进行修改。
完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
多个过滤器组成过滤器调用链,按设置顺序执行,形成Filter链。
Filter的作用:
- 在请求到达Servlet之前,拦截客户传来的请求
- 可以对请求进行检查、判断,亦可以进行修改
- 在请求到达客户端之前,拦截响应
- 可以对响应进行检查、判断、修改
1、通过@ServletComponentScan自动扫描注册
① 在springboot入口程序除添加 @ServletComponentScan
② 使用@WebFilter 配置处理全部url的Filter
1 |
|
运行结果:启动时会执行init()方法,拦截到对应请求时执行doFilter(),web应用关闭时执行destroy()方法

doFilter()方法是过滤器的和核心方法,实现该方法就可以实现对用户请求进行预处理,也可以实现对服务器响应进行处理,他们的分界线为是否调用chain.doFilter(),执行该方法之前,对用户请求进行预处理,执行该方法之后,对服务器响应进行后处理

destroy:

2、使用FilterRegistrationBean
使用@Bean注入
1
2
3
4
5
6
7
8
9
10
public class RegistrationConfiguration {
public FilterRegistrationBean myFilter2(){
FilterRegistrationBean<MyFilter2> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new MyFilter2());
filterRegistrationBean.addUrlPatterns("/hello","/test","/demo/servlet2");
return filterRegistrationBean;
}
}MyFilter2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class MyFilter2 implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter2 init....");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("MyFilter2 doFilter....former...");
chain.doFilter(request, response);
System.out.println("MyFilter2 doFilter....after...");
}
public void destroy() {
System.out.println("myFilter destroy....");
}
}请求结果就不贴图了,测试结果与MyFilter类似。
Listener
首先Listener是只能是以下几个接口的实现类,其中包括4个 EventListeners( ServletContextAttributeListener、ServletRequestAttributeListener、ServletRequestListener、HttpSessionAttributeListener)和2个 LifecycleListeners(ServletContextListener、HttpSessionListener);
- ServletContextAttributeListener监听对ServletContext属性的操作,比如增加、删除、修改属性。
- ServletContextListener监听ServletContext。当创建ServletContext时,激发contextInitialized(ServletContextEvent sce)方法;当销毁ServletContext时,激发contextDestroyed(ServletContextEvent sce)方法。
- HttpSessionListener监听HttpSession的操作。当创建一个Session时,激发session Created(HttpSessionEvent se)方法;当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。
- HttpSessionAttributeListener监听HttpSession中的属性的操作。当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se) 方法。
1、通过@ServletComponentScan自动扫描注册
使用ServletListenerRegistrationBean注入bean
自定义Listener
1
2
3
4
5
6
7
8
9
10
11
12
public class MyListener1 implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
System.out.println("MyListener1 contextInitialized.....");
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("MyListener1 contextDestroyed....");
}
}运行结果:

2、通过@ServletListenerRegistrationBean 注册
手动注册bean
1
2
3
4
5
6
7
public class RegistrationConfiguration {
public ServletListenerRegistrationBean myListener2(){
return new ServletListenerRegistrationBean(new MyListener2());
}
}自定义Listener
1
2
3
4
5
6
7
8
9
10
11public class MyListener2 implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
System.out.println("MyListener2 contextInitialized.....");
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("MyListener2 contextDestroyed....");
}
}结果:

以上可得出三的运行顺序:Listener>Filter>Servlet
Intercepter
拦截器只会处理DispatcherServlet处理的url
1 | public class MyInterceptor implements HandlerInterceptor { |
注册拦截器
1 |
|
浏览器访问 http://localhost:8080/demo/servlet1 此时MyInterceptor不会拦截,因为被自定义Servlet处理。
访问其他未被自定义Servlet匹配的url,可以看到MyInterceptor输出。
Intercepter生命周期详见: https://www.cnblogs.com/junzi2099/p/8022058.html
