首先声明一下,这里所说的拦截器是 SpringMVC 的拦截器(HandlerInterceptor)。使用SpringMVC 拦截器需要做如下操作:
创建拦截器类需要实现 HandlerInterceptor在 xml 配置文件中配置该拦截器,具体配置代码如下: <mvc:interceptors> <mvc:interceptor> <!-- /test/** 这个是拦截路径以/test开头的所有的URL--> <mvc:mapping path="/**"/><!—这个是拦截所有的路径--> <!-- 配置拦截器类路径--> <bean class="cn.ljk.springmvc.controller.MyInterceptor"></bean> <!-- 配置不拦截器URL路径--> <mvc:exclude-mapping path="/fore/**"/> </mvc:interceptor> </mvc:interceptors> 12345678910因为在SpringBoot 中没有 xml 文件,所以SpringBoot 为我们提供 Java Config 的方式来配置拦截器。配置方式有2种:
继承 WebMvcConfigurerAdapter (官方已经不建议使用)实现 WebMvcConfigurer接下来开始 SpringBoot 整合拦截器操作详细介绍!
第一步:声明拦截器类
通过实现 HandlerInterceptor 来完成。具体代码如下:
public class LoginInterceptor implements HandlerInterceptor{} 1第二步:实现 HandlerInterceptor 3 个拦截方法
preHandle:Controller逻辑执行之前进行拦截postHandle:Controller逻辑执行完毕但是视图解析器还未进行解析之前进行拦截afterCompletion:Controller逻辑和视图解析器执行完毕进行拦截实际开发中 preHandle 使用频率比较高,postHandle 和 afterCompletion操作相对比较少。在下面的代码中 preHandle 方法中定义拦截所有访问项目 url 并进行日志信息记录。
postHandle 中在视图解析前进行拦截,通过 Model 再次添加数据到 Request域中。
afterCompletion 暂时没有想到使用场景,如果有使用过的场景可以在下面评论区中进行评论。
拦截器详细代码如下:
public class LoginInterceptor implements HandlerInterceptor{ <span class="token keyword">private</span> Logger log <span class="token operator">=</span> LoggerFactory<span class="token punctuation">.</span><span class="token function">getLogger</span><span class="token punctuation">(</span>LoginInterceptor<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//ControllerController逻辑执行之前</span> <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">preHandle</span><span class="token punctuation">(</span>HttpServletRequest request<span class="token punctuation">,</span> HttpServletResponse response<span class="token punctuation">,</span> Object handler<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"preHandle...."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> String uri <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getRequestURI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"uri:"</span><span class="token operator">+</span> uri<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>handler <span class="token keyword">instanceof</span> <span class="token class-name">HandlerMethod</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> HandlerMethod handlerMethod <span class="token operator">=</span> <span class="token punctuation">(</span>HandlerMethod<span class="token punctuation">)</span> handler<span class="token punctuation">;</span> log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"拦截 Controller:"</span><span class="token operator">+</span> handlerMethod<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"拦截方法:"</span><span class="token operator">+</span>handlerMethod<span class="token punctuation">.</span><span class="token function">getMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//Controller逻辑执行完毕但是视图解析器还未进行解析之前</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">postHandle</span><span class="token punctuation">(</span>HttpServletRequest httpServletRequest<span class="token punctuation">,</span> HttpServletResponse httpServletResponse<span class="token punctuation">,</span> Object o<span class="token punctuation">,</span> ModelAndView modelAndView<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"postHandle...."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Map<span class="token generics function"><span class="token punctuation"><</span>String<span class="token punctuation">,</span>Object<span class="token punctuation">></span></span>map<span class="token operator">=</span>modelAndView<span class="token punctuation">.</span><span class="token function">getModel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"msg"</span><span class="token punctuation">,</span><span class="token string">"postHandle add msg"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//Controller逻辑和视图解析器执行完毕</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">afterCompletion</span><span class="token punctuation">(</span>HttpServletRequest httpServletRequest<span class="token punctuation">,</span> HttpServletResponse httpServletResponse<span class="token punctuation">,</span> Object o<span class="token punctuation">,</span> Exception e<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"afterCompletion...."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>}
1234567891011121314151617181920212223242526272829303132第三步:Java Config 的方式来配置拦截器
继承 WebMvcConfigurerAdapter 方式
通过继承 WebMvcConfigurerAdapter 并重写 addInterceptors方法,通过其参数 InterceptorRegistry 将拦截器注入到 Spring的上下文中。
另外拦截路径和不拦截的路径通过InterceptorRegistry 的 addPathPatterns 和 excludePathPatterns 方法进行设置。
继承 WebMvcConfigurerAdapter 方式官方已经不建议使用,因为官方已将 WebMvcConfigurerAdapter 标记为@Deprecated 了。
@Deprecated public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { 12继承 WebMvcConfigurerAdapter 方式具体代码如下:
@Configuration public class InterceptorConfigByExtendsWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter{ <span class="token annotation punctuation">@Bean</span> <span class="token keyword">public</span> LoginInterceptor <span class="token function">loginInterceptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">LoginInterceptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addInterceptors</span><span class="token punctuation">(</span>InterceptorRegistry registry<span class="token punctuation">)</span> <span class="token punctuation">{</span> registry<span class="token punctuation">.</span><span class="token function">addInterceptor</span><span class="token punctuation">(</span><span class="token function">loginInterceptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addPathPatterns</span><span class="token punctuation">(</span><span class="token string">"/**"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">excludePathPatterns</span><span class="token punctuation">(</span><span class="token string">"/*.html"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>}
123456789101112实现 WebMvcConfigurer 方式
通过实现 WebMvcConfigurer 接口 并实现 addInterceptors方法,其他操作和继承 WebMvcConfigurerAdapter 方式一样。具体代码如下:
@Configuration public class InterceptorConfigByImplWebMvcConfigurer implements WebMvcConfigurer{ <span class="token annotation punctuation">@Bean</span> <span class="token keyword">public</span> LoginInterceptor <span class="token function">loginInterceptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">LoginInterceptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addInterceptors</span><span class="token punctuation">(</span>InterceptorRegistry registry<span class="token punctuation">)</span> <span class="token punctuation">{</span> registry<span class="token punctuation">.</span><span class="token function">addInterceptor</span><span class="token punctuation">(</span><span class="token function">loginInterceptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addPathPatterns</span><span class="token punctuation">(</span><span class="token string">"/**"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">excludePathPatterns</span><span class="token punctuation">(</span><span class="token string">"/*.html"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>}
123456789101112编写普通Controller,具体代码如下:
@Controller public class IndexController { <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/index"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> String <span class="token function">index</span><span class="token punctuation">(</span>ModelAndView modelAndView<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"index"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>}
123456789在 src/main/resource 下的 templates 目录下创建 IndexController 访问页面 index.ftl, 代码如下:
<h1>${msg}</h1> 1由于我这里使用的是 Freemarker 当页面使用,所以需要引入 freemarker starter依赖,具体点如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> 1234通过游览器访问 localhost:8080/sbe/index,具体访问效果如下:
如上图所示在视图解析前通过 Model 再次添加数据到 Request域中的msg 成功显示出来了!
日志输出信息如下:(拦截地址和拦截Controller 和具体方法进行日志输出)
2019-09-24 15:53:04.144 INFO 7732 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/sbe] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2019-09-24 15:53:04.145 INFO 7732 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2019-09-24 15:53:04.153 INFO 7732 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms 2019-09-24 15:53:04.155 INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor : preHandle.... 2019-09-24 15:53:04.155 INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor : uri:/sbe/index 2019-09-24 15:53:04.155 INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor : 拦截 Controller:cn.lijunkui.controller.IndexController 2019-09-24 15:53:04.155 INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor : 拦截方法:index 2019-09-24 15:53:04.156 INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor : postHandle.... 2019-09-24 15:53:04.161 INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor : afterCompletion.... 123456789SpringBoot 2 整合拦截器和整合 Filter的操作很像,都是通过一个注册类将其注入到Spring的上下文中,只不过Filter使用的是 FilterRegistrationBean 而 拦截器使用的是 InterceptorRegistry。
个人觉得比使用 xml 配置的方式更为简单了,如果你还没有在 SpringBoot 项目中使用过拦截器,赶快来操作一下吧!
具体代码示例请在我的GitHub 仓库 springbootexamples 中模块名为 spring-boot-2.x-interceptor 项目中进行查看
GitHub:https://github.com/zhuoqianmingyue/springbootexamples
</div> <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-095d4a0b23.css" rel="stylesheet"> </div> </article> <div class="postTime"> <div class="article-bar-bottom"> <div class="reward-user-box"> <span class="reward-word">有 <span class="num">0</span> 个人打赏</span> </div> </div> <span class="time"> 文章最后发布于: 2019-09-24 19:12:33 </span> </div>