首先聲明一下,這裏所說的攔截器是 SpringMVC 的攔截器 HandlerInterceptor。使用SpringMVC 攔截器須要作以下操做:html
<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>
由於在SpringBoot 中沒有 xml 文件,因此SpringBoot 爲咱們提供 Java Config 的方式來配置攔截器。配置方式有2種:java
接下來開始 SpringBoot 整合攔截器操做詳細介紹!git
第一步:聲明攔截器類github
經過實現 HandlerInterceptor 來完成。具體代碼以下:web
public class LoginInterceptor implements HandlerInterceptor{}
第二步:實現 HandlerInterceptor 3 個攔截方法spring
實際開發中 preHandle使用頻率比較高,postHandle 和 afterCompletion操做相對比較少。springboot
在下面的代碼中 preHandle 方法中定義攔截全部訪問項目 URL並進行日誌信息記錄。postHandle 中在視圖解析前進行攔截,經過 Model 在次添加數據Request域中。mvc
afterCompletion 暫時沒有想到使用場景,若是有使用過的場景能夠在下面評論區中進行評論。
攔截器詳細代碼以下:app
public class LoginInterceptor implements HandlerInterceptor{ private Logger log = LoggerFactory.getLogger(LoginInterceptor.class); //ControllerController邏輯執行以前 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("preHandle...."); String uri = request.getRequestURI(); log.info("uri:"+ uri); if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; log.info("攔截 Controller:"+ handlerMethod.getBean().getClass().getName()); log.info("攔截方法:"+handlerMethod.getMethod().getName()); } return true; } //Controller邏輯執行完畢可是視圖解析器還爲進行解析以前 @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { log.info("postHandle...."); Map<String,Object>map=modelAndView.getModel(); map.put("msg","postHandle add msg"); } //Controller邏輯和視圖解析器執行完畢 @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { log.info("afterCompletion...."); } }
第三步:Java Config 的方式來配置攔截器ide
繼承 WebMvcConfigurerAdapter 方式
經過繼承 WebMvcConfigurerAdapter並重寫 addInterceptors方法,經過其參數 InterceptorRegistry將攔截器注入到 Spring的上下文中。
另外攔截路徑和不攔截的路徑經過InterceptorRegistry 的 addPathPatterns和 excludePathPatterns方法進行設置。
這種方式官方已經不建議使用,由於官方已將 WebMvcConfigurerAdapter 標記爲@Deprecated 了。
@Deprecated public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
繼承 WebMvcConfigurerAdapter 方式具體代碼以下:
@Configuration public class InterceptorConfigByExtendsWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter{ @Bean public LoginInterceptor loginInterceptor(){ return new LoginInterceptor(); } public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor()).addPathPatterns("/**").excludePathPatterns("/*.html"); } }
實現 WebMvcConfigurer 方式
經過實現 WebMvcConfigurer 接口並實現 addInterceptors方法,其餘操做和繼承 WebMvcConfigurerAdapter方式同樣。具體代碼以下:
```java @Configuration public class InterceptorConfigByImplWebMvcConfigurer implements WebMvcConfigurer{ @Bean public LoginInterceptor loginInterceptor(){ return new LoginInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor()).addPathPatterns("/**").excludePathPatterns("/*.html"); } } ```
編寫普通Controller,具體代碼以下:
@Controller public class IndexController { @GetMapping("/index") public String index(ModelAndView modelAndView){ return "index"; } }
在 src/main/resource 下的 templates目錄下建立 IndexController訪問頁面 index.ftl, 代碼以下:
<h1>${msg}</h1>
因爲我這裏使用的是 Freemarker當頁面使用,說以須要引入 Freemarker starter依賴,具體點以下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
經過遊覽器訪問 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....
SpringBoot 2 整合攔截器和整合 Filter的操做很像,都是經過一個註冊類將其注入到Spring的上下文中,只不過Filter使用的是 FilterRegistrationBean 而 攔截器使用的是 InterceptorRegistry。
我的以爲比使用 xml 配置的方式更爲簡單了,若是你尚未在 SpringBoot 項目中使用過攔截器,趕快來操做一下吧!
具體代碼示例請在個人GitHub 倉庫 springbootexamples 中模塊名爲 spring-boot-2.x-interceptor 項目中進行查看