一攔截器
一、攔截器(Interceptor)
定義:在面向切面程式設計中應用的,在方法執行之前或者之後,進行攔截,添加某些操作;基于java的反射機制實作的。攔截是aop的一種實作政策。
在webWork中,攔截器是動态攔截Action調用的對象,提供了一種機制使開發者可以定義在一個Action執行的前後執行的代碼,也可以在一個Action執行前阻止其
執行。同時,也提供了一種可以提取Action中可重用的部分的方式。
攔截器從Action中抽出了很多功能,大量減少了Actin中的代碼,抽取出的公共方法可以更好的重用。
當我們送出對Action的請求時,ServletDispatcher會根據請求,排程并執行相應的Action;在此Action執行之前,調用被Interceptor截取,Interceptor
在Action執行前後執行。
二、在ssm中的實作
SpringMVC 中的Interceptor 攔截請求是通過HandlerInterceptor 來實作的。主要有兩種方式:
第一種: 定義的Interceptor類 實作Spring 的HandlerInterceptor 接口,或者是這個類繼承實作了HandlerInterceptor 接口的類,比如Spring 已經提供的實作了
HandlerInterceptor 接口的抽象類HandlerInterceptorAdapter ;
第二種: 定義的Interceptor類, 實作Spring的WebRequestInterceptor接口,或者是繼承實作了WebRequestInterceptor的類。
三、在springboot中的實作
第一種: 建立類 LogCostInterceptor 實作 HandlerInterceptor 接口;
建立配置類WebConfiguration 繼承 WebMvcConfigurationSupport (或者 WebMvcConfigurerAdapter);添加 @Configuration注解;
@Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {
private Logger logger = LoggerFactory.getLogger(WebConfiguration.class);
@Override
public void addInterceptors(InterceptorRegistry registry){
// 多個攔截器組成一個攔截器鍊
// addPathPatterns 用于添加攔截規則
// excludePathPatterns 使用者排除攔截
registry.addInterceptor(new LogCostInterceptor()).addPathPatterns().excludePathPatterns("/swagger-ui.html");
}
}
四、 攔截器中三個方法的詳細解釋
SpringMvc的過濾器是鍊式的,在一個應用中或者一個請求中可以有多個Interceptor,執行順序按照聲明中的順序執行,先執行每個過濾器中的preHandle方法。
1) preHandle 在請求controller之前執行,可以在方法中進行一些初始化操作或者是對目前請求的一個預處理,也可以設定一些判斷決定請求是否要繼續下去。
傳回結果如果是true,則執行後續的Interceptor中的preHandle和controller,
如果是false,表示請求結束。
2) postHandle 在preHandle執行為true後,執行該方法。在controller執行之後,在DispatcherServlet進行視圖傳回渲染之前被調用;在這個方法中可以對
ModelAndView對象進行處理。postHandle的執行順序在鍊式中和preHandle的執行順序是相反的,先執行preHandle的過濾器的postHandle後執行。
3) afterCompletion preHandle執行為true後執行。 該方法在整個請求結束之後,在DispatcherServlet渲染了對應的視圖之後執行。
作用: 進行資源清理工作。
二 攔截器
一 、定義:
filter 實作了 javax.servlet.filter接口的伺服器端程式;
二、 用途:
設定字元集、控制權限、控制轉向、業務邏輯判斷等
三、 工作原理:
在web.xml檔案配置需要攔截的用戶端請求,它會幫你攔截到請求,此時你可以對請求或相應統一設定編碼、簡化操作;同時可以進行邏輯判斷,如使用者是否已經登入、有沒有權限通路該頁面等等。
随着web應用啟動而啟動,隻需要初始化一次,以後就可以攔截相關請求,隻有當web應用停止或重新部署的時候才銷毀。
Filter 主要使用者對使用者請求進行預處理,也可以對HttpServletResponse進行後處理,是個典型的處理鍊。
四、 流程:
filter對使用者請求進行預處理,将請求交給Servlet進行處理并生成響應,最後Filter再對伺服器響應進行後處理。
五、 用處:
在HttpServletRequest到達Servlet之前,攔截客戶的HttpServletRequest。
根據需要檢查HttpServletRequest,也可以修改HttpServletRequest頭和資料。
在HttpServletResponse到達用戶端之前,攔截HttpServletResponse。
根據需要檢查HttpServletResponse,也可以修改HttpServletResponse頭和資料。
六、 種類:
使用者授權的Filter:Filter負責檢查使用者請求,根據請求過濾使用者非法請求。
日志Filter:詳細記錄某些特殊的使用者請求。
負責解碼的Filter:包括對非标準編碼的請求解碼。
能改變XML内容的XSLT Filter等。
Filter可以負責攔截多個請求或響應;一個請求或響應也可以被多個Filter攔截。
七、 使用:
1 建立Myfilter類繼承Filter
重寫 init 和 doFilter
② 在init方法中初始化自定義參數,參數名稱可以設定為此時的 url,對其執行過濾,也就是放過;
③ 在doFilter中可以進行認證鑒權處理,之後執行相應的邏輯;
也可以進行跨域的設定;
在doFilter中 chain.doFilter(req, res)是對請求和響應處理的分界線,執行該方法之前,即對使用者請求進行預處理;執行該方法之後,即對伺服器響應進行後處理
1)第一種方案
a: 在Myfilter類 添加注解 @WebFilter ,可以添加 @Order(1)多個Myfilter的時候 按照順序執行
@WebFilter的一些參數值
( filterName = "Myfilter", urlPatterns = "/snow/api/*",
initParams = { @WebInitParam(name = "url", value = "/snow/api/login")}
)
filterName 攔截的位址 initParams 放過的位址,不需要檢測
b: 在springboot的啟動類上添加 @ServletComponentScan
2)第二種方案
a: 在Myfilter類 添加注解 @Component,交給spring容器處理
b: 建立一個config類,添加注解
public class config {
@Bean
public FilterRegistrationBean webAuthFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(myfilte());
registration.setName("Myfilter");
registration.addUrlPatterns("/snow/api/*");
registration.addInitParameter("url", "/snow/api/login");
registration.setOrder(0); //設定順序
return registration;
}
@Bean
public Filter myfilter() {
return new Myfilter();
}
三 過濾器和攔截器的比較
一、差別和不同
相同:都是AOP程式設計思想的實作。
不同點:
使用範圍不同 過濾器隻能使用再web應用程式,也就是在servlet容器中; 攔截器即可以使用在web應用中,也可以使用在
javaSE的各種環境。
使用的資源不同 攔截器是spring的元件,被spring管理,可以使用spring的任何資源包括:Servive對象、事務管理、資料源等,
通過IOC注入到容器即可。過濾器不可以。
使用的深度(範圍)不同 過濾器隻在Servlet前後起作用;攔截器可以深入到方法前後、異常抛出前後等,具有更大的彈性。
執行順序不同 Filter是被Server(比如tomcat、netty)調用; Interceptor被spring調用; 是以Filter在Interceptor前面執行。
使用選擇 在spring架構的實作中,優先選擇使用攔截器。
二、 過濾器和攔截器的執行流程圖