listener、filter、servlet、interceptor在springboot中执行顺序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了listener、filter、servlet、interceptor在springboot中执行顺序相关的知识,希望对你有一定的参考价值。
参考技术A 本地访问 http://localhost:8080/my ,查看日志信息,如下:执行顺序如下:
1.项目 run 时, filter 开始 init
2.浏览器发送 get 请求, listener 开始 init
3. filter 执行 doFilter 方法
4. servlet 执行 doGet 方法
5. interceptor 开始依次执行 preHandle 、 postHandle 、 afterCompletion 方法
6. listener 执行 requestDestroyed 方法, get 请求结束
7.项目 down 掉, filter 执行 destroy 方法
filter,servlet,listener,interceptor
在SpringBootApplication上使用@ServletComponentScan注解后,
Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。
过滤器
默认使用的4个
在启动打印出来的日志里有:
-
Filter ‘requestContextFilter‘ configured for use
-
-
Filter ‘characterEncodingFilter‘ configured for use
-
Filter ‘formContentFilter‘ configured for use
优先级
低位值意味着更高的优先级。自定义Filter,避免和默认的Filter优先级一样,不然会冲突。
作用(使用场景)
-
比如用户验证。
-
如果涉及页面跳转,filter就不适合 前后端分离的情况。
启动类 加上 注解
@ServletComponentScan
自定义的filter
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter(urlPatterns = "/api/*") public class LoginFilter implements Filter /** * 容器加载的时候调用 */ @Override public void init(FilterConfig filterConfig) throws ServletException System.out.println("init loginFilter"); /** * 请求被拦截的时候进行调用 */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException System.out.println("doFilter loginFilter"); HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; String username = request.getParameter("username"); if ("xdclass".equals(username)) filterChain.doFilter(request, response); else response.sendRedirect("/index.html"); // 重定向 @Override public void destroy() System.out.println("destroy loginFilter");
测试
添加controller的访问方法。
@GetMapping(value="/api/v1/account") public Object account() params.put("money", "1000"); return params;
访问 http://localhost:8080/api/v1/account?username=xdclass
"money": "1000"
测试通过。
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(urlPatterns = "/v1/api/test/customs", name = "userServlet") public class UserServlet extends HttpServlet @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException resp.getWriter().print("custom sevlet"); resp.getWriter().flush(); resp.getWriter().close(); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException this.doGet(req, resp);
启动类 加上 @ServletComponentScan , 和 过滤器的使用 很像。
@WebListener public class RequestListener implements ServletRequestListener @Override public void requestDestroyed(ServletRequestEvent sre) // TODO Auto-generated method stub System.out.println("======requestDestroyed========"); @Override public void requestInitialized(ServletRequestEvent sre) System.out.println("======requestInitialized========"); 、
1、老方法,jdk8之前
继承 WebMvcConfigurerAdapter
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class CustomOldWebMvcConfigurer extends WebMvcConfigurerAdapter
@Override
public void addInterceptors(InterceptorRegistry registry)
registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/");
super.addInterceptors(registry);
2、jdk8之后的新方法
使用 implements WebMvcConfigurer
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 CustomWebMvcConfigurer implements WebMvcConfigurer
@Override
public void addInterceptors(InterceptorRegistry registry)
registry.addInterceptor(new LoginIntercepter())
.addPathPatterns("/api/login/**");
WebMvcConfigurer.super.addInterceptors(registry);
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LoginIntercepter implements HandlerInterceptor /** * 进入controller方法之前 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception System.out.println("LoginIntercepter------->preHandle"); // String token = request.getParameter("access_token"); // // response.getWriter().print("fail"); return HandlerInterceptor.super.preHandle(request, response, handler); /** * 调用完controller之后,视图渲染之前 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception System.out.println("LoginIntercepter------->postHandle"); HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); /** * 整个完成之后,通常用于资源清理 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception System.out.println("LoginIntercepter------->afterCompletion"); HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
小结
-
-
Filter在只在Servlet前后起作用,而Interceptor能够深入到方法前后、异常抛出前后等。
-
依赖于Servlet容器即web应用中,而Interceptor不依赖于Servlet容器所以可以运行在多种环境。
-
在接口调用的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。
-
Filter和Interceptor的执行顺序 过滤前->拦截前->action执行->拦截后->过滤后。
以上是关于listener、filter、servlet、interceptor在springboot中执行顺序的主要内容,如果未能解决你的问题,请参考以下文章
filter,servlet,listener,interceptor
sprintboot 整合Servlet,Filter,Listener
SpringBoot中使用Servlet,Filter,Listener
springBoot:web开发-Servlets, Filters, listeners