目录
拦截路径
- 拦截器可以通过需求,在配置类中配置不同的拦截路径
- 可以设置要拦截的路径以及不进行拦截的路径
-
package com.example.tlias.config; import com.example.tlias.Interceptor.LoginCheckInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration // todo 将该类标志为配置类 public class WebConfig implements WebMvcConfigurer { @Autowired private LoginCheckInterceptor loginCheckInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // todo 注册拦截器并知道拦截器要拦截的资源 registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login"); // todo 配置拦截的路径以及不拦截的路径 } }
-
- 可以设置要拦截的路径以及不进行拦截的路径
-
拦截路径 含义 举例 /* 一级路径 能匹配/depts、/emps、/login,不能匹配/depts/1 /** 任意级路径 能匹配/depts、/depts/1、depts/1/2 /depts/* /depts下的一级路径 能匹配/depts/1、不能匹配depts/1/2、/depts /depts/** /depts下的任意路径 能匹配/depts、/depts/1、depts/1/2,不能匹配/emps
执行流程
只有拦截器
-
在Spring Boot框架下,拦截器的执行流程如下:
-
当客户端发送请求到Spring Boot应用时,请求将首先经过DispatcherServlet。
-
DispatcherServlet会根据配置的URL映射规则,将请求分发给相应的Controller处理。
-
在请求到达Controller之前,拦截器将会被执行。拦截器的执行顺序与其添加的顺序有关,可以通过配置类中的
addInterceptors()
方法的顺序来控制拦截器的执行顺序。 -
在拦截器的
preHandle()
方法中,可以进行一些预处理操作,例如权限验证、参数校验等。如果在preHandle()
方法中返回false
,则表示拦截器终止请求的继续执行,后续的拦截器和Controller将不会被执行。 -
如果拦截器的
preHandle()
方法返回true
,则请求将继续向下执行,到达Controller进行业务处理。 -
在Controller处理完业务逻辑后,请求将返回到拦截器的
postHandle()
方法。在这里可以对响应结果进行处理,例如添加额外的响应头信息、修改响应内容等。 -
最后,请求将返回到拦截器的
afterCompletion()
方法。在这里可以进行一些清理操作,例如释放资源、记录日志等。afterCompletion()
方法将在请求完成后执行,无论是否发生异常。
-
-
总结起来,拦截器在Spring Boot框架下的执行流程是:DispatcherServlet -> 拦截器的preHandle() -> Controller -> 拦截器的postHandle() -> 拦截器的afterCompletion()。通过在拦截器的不同方法中实现相应的逻辑,可以在请求处理前后进行预处理和后处理操作。
过滤器和拦截器同时存在
-
在SpringBoot框架中,同时存在过滤器(Filter)和拦截器(Interceptor)时的执行流程如下:
- 当请求到达服务器时,首先会经过Servlet容器(tomcat等)的DispatcherServlet。
- DispatcherServlet会根据配置的过滤器链(Filter Chain)来依次执行过滤器。
- 过滤器链是按照配置的顺序依次执行的,每个过滤器都可以对请求进行处理或修改。
- 过滤器可以在请求到达Servlet之前或之后进行操作。
- 过滤器链的最后一个过滤器会将请求传递给下一个处理组件,例如Servlet或Controller。
- 当请求到达控制器(Controller)之前,首先会经过Servlet容器的DispatcherServlet。
- DispatcherServlet会根据配置的拦截器链(Interceptor Chain)来依次执行拦截器。
- 拦截器链是按照配置的顺序依次执行的,每个拦截器都可以在请求到达控制器之前或之后进行处理。
- 拦截器可以在请求到达控制器之前或之后进行操作。
- 拦截器链的最后一个拦截器会将请求传递给控制器(Controller)进行处理。
- 在控制器处理完请求后,请求会再次经过拦截器链中的拦截器,按照相反的顺序执行。
- 示例代码:
- 拦截器(Interceptor)
-
package com.example.tlias.Interceptor; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component // 将该类标记为组件交给IOC容器管理 public class LoginCheckInterceptor implements HandlerInterceptor { @Override // todo 在目标资源方法(控制类中的方法)执行之前执行,返回true:放行;返回false:不放行 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle()方法运行了"); return true; } @Override // todo 在目标资源方法执行之后执行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle()方法运行了"); } @Override // todo 在视图渲染完毕后执行,最后执行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion()发运行了"); } }
-
-
过滤器(Filter)
-
package com.example.tlias.Filter; import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter("/*") // todo 设置当前过滤器要拦截的请求 public class JWTFilter implements Filter { @Override// todo 初始化方法,Web服务器启动时,创建Filter时调用,只调用一次 public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); System.out.println("init初始化方法执行了"); } @Override // todo 拦截到请求时就会调用该方法,可调用多次 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("JWTFilter放行之前的逻辑"); // todo 放行请求,让其访问对应的资源 filterChain.doFilter(servletRequest, servletResponse); System.out.println("JWTFilter放行之后的逻辑"); } @Override // todo 销毁方法,服务器关闭时调用,只调用一次 public void destroy() { Filter.super.destroy(); System.out.println("destroy销毁方法执行了"); } }
-
-
首先启动项目
-
运行日志
- Filter过滤器中的init()初始化方法首先执行了
-
- 发送请求
- 运行日志
- 首先运行Filter中放行之前的逻辑,然后运行拦截器(Interceptor)中的preHandle()方法,返回值为true的话,就放行执行Web资源(Controller类),然后执行过滤器(Interceptor)中的potHandle()方法,然后执行Filter过滤器中放行后的逻辑。
- 运行日志
- 拦截器(Interceptor)