過濾器屬於Servlet范疇的API,與spring 沒什么關系。
Web開發中,我們除了使用 Filter 來過濾請web求外,還可以使用Spring提供的HandlerInterceptor(攔截器)。
HandlerInterceptor 的功能跟過濾器類似,但是提供更精細的的控制能力:在request被響應之前、request被響應之后、視圖渲染之前以及request全部結束之后。我們不能通過攔截器修改request內容,但是可以通過拋出異常(或者返回false)來暫停request的執行。
實現 UserRoleAuthorizationInterceptor 的攔截器有:
ConversionServiceExposingInterceptor
CorsInterceptor
LocaleChangeInterceptor
PathExposingHandlerInterceptor
ResourceUrlProviderExposingInterceptor
ThemeChangeInterceptor
UriTemplateVariablesHandlerInterceptor
UserRoleAuthorizationInterceptor
其中 LocaleChangeInterceptor 和 ThemeChangeInterceptor 比較常用。
1、創建我們自己的攔截器類並實現 HandlerInterceptor 接口
package me.shijunjie.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class MyInterceptor1 implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println(">>>MyInterceptor1>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)"); } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println(">>>MyInterceptor1>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)"); } @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println(">>>MyInterceptor1>>>>>>>在請求處理之前進行調用(Controller方法調用之前)"); return true;// 只有返回true才會繼續向下執行,返回false取消當前請求 } }
package me.shijunjie.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class MyInterceptor2 implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println(">>>MyInterceptor2>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)"); } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println(">>>MyInterceptor2>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)"); } @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println(">>>MyInterceptor2>>>>>>>在請求處理之前進行調用(Controller方法調用之前)"); return true;// 只有返回true才會繼續向下執行,返回false取消當前請求 } }
2、創建一個Java類繼承WebMvcConfigurerAdapter,並重寫 addInterceptors 方法。
實例化我們自定義的攔截器,然后將對像手動添加到攔截器鏈中(在addInterceptors方法中添加)。
實例化我們自定義的攔截器也可以交給spring來做,可以用autowired來注入
package me.shijunjie.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import me.shijunjie.interceptor.MyInterceptor1; import me.shijunjie.interceptor.MyInterceptor2; @Configuration public class MyWebAppConfiguer extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**"); registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**"); super.addInterceptors(registry); } }
入口
package me.shijunjie.testspringboot2; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ServletComponentScan("me.shijunjie") @ComponentScan("me.shijunjie") public class App { /* *//** * 注冊Servlet.不需要添加注解:@ServletComponentScan * @return *//* @Bean public ServletRegistrationBean myServlet1(){ return new ServletRegistrationBean(new MyServlet1(),"/myServlet/*"); }*/ public static void main( String[] args ) { SpringApplication.run(App.class, args); } }