javascript
008--【SpringBoot】过滤器,拦截器,切面
0、 參考網(wǎng)址:
- 攔截器和過濾器的區(qū)別:https://www.jianshu.com/p/7bd0cad17f23
- Interceptor使用:https://blog.csdn.net/weixin_36927395/article/details/81067146
1、過濾器,攔截器,切面
- 1.過濾器(Filter):所謂過濾器顧名思義是用來過濾的,Java的過濾器能夠?yàn)槲覀兲峁┫到y(tǒng)級(jí)別的過濾,也就是說,能過濾所有的web請(qǐng)求,
這一點(diǎn),是攔截器無法做到的。在Java Web中,你傳入的request,response提前過濾掉一些信息,或者提前設(shè)置一些參數(shù),然后再傳入servlet或
者struts的action進(jìn)行業(yè)務(wù)邏輯,比如過濾掉非法url(不是login.do的地址請(qǐng)求,如果用戶沒有登陸都過濾掉),或者在傳入servlet或者struts
的action前統(tǒng)一設(shè)置字符集,或者去除掉一些非法字符(聊天室經(jīng)常用到的,一些罵人的話)。filter 流程是線性的,url傳來之后,檢查之后,
可保持原來的流程繼續(xù)向下執(zhí)行,被下一個(gè)filter, servlet接收。 - 2.監(jiān)聽器(Listener):Java的監(jiān)聽器,也是系統(tǒng)級(jí)別的監(jiān)聽。監(jiān)聽器隨web應(yīng)用的啟動(dòng)而啟動(dòng)。Java的監(jiān)聽器在c/s模式里面經(jīng)常用到,它
會(huì)對(duì)特定的事件產(chǎn)生產(chǎn)生一個(gè)處理。監(jiān)聽在很多模式下用到,比如說觀察者模式,就是一個(gè)使用監(jiān)聽器來實(shí)現(xiàn)的,在比如統(tǒng)計(jì)網(wǎng)站的在線人數(shù)。
又比如struts2可以用監(jiān)聽來啟動(dòng)。Servlet監(jiān)聽器用于監(jiān)聽一些重要事件的發(fā)生,監(jiān)聽器對(duì)象可以在事情發(fā)生前、發(fā)生后可以做一些必要的處理。 - 3.攔截器(Interceptor):java里的攔截器提供的是非系統(tǒng)級(jí)別的攔截,也就是說,就覆蓋面來說,攔截器不如過濾器強(qiáng)大,但是更有針對(duì)性。
Java中的攔截器是基于Java反射機(jī)制實(shí)現(xiàn)的,更準(zhǔn)確的劃分,應(yīng)該是基于JDK實(shí)現(xiàn)的動(dòng)態(tài)代理。它依賴于具體的接口,在運(yùn)行期間動(dòng)態(tài)生成字節(jié)碼。
攔截器是動(dòng)態(tài)攔截Action調(diào)用的對(duì)象,它提供了一種機(jī)制可以使開發(fā)者在一個(gè)Action執(zhí)行的前后執(zhí)行一段代碼,也可以在一個(gè)Action執(zhí)行前阻止其
執(zhí)行,同時(shí)也提供了一種可以提取Action中可重用部分代碼的方式。在AOP中,攔截器用于在某個(gè)方法或者字段被訪問之前,進(jìn)行攔截然后再之前或
者之后加入某些操作。java的攔截器主要是用在插件上,擴(kuò)展件上比如 Hibernate Spring Struts2等,有點(diǎn)類似面向切片的技術(shù),在用之前先要在
配置文件即xml,文件里聲明一段的那個(gè)東西。
2、過濾器
- 以上可知:過濾器和攔截器有時(shí)可以實(shí)現(xiàn)相同的功能,比如登錄鑒權(quán)
,但是這個(gè)并不是Spring推薦的;
Filter特性:
- Filter在程序啟動(dòng)的時(shí)候啟動(dòng)一次
- 不能擁有service對(duì)象,數(shù)據(jù)源,事務(wù)管理
- 可以攔截靜態(tài)資源(可以才是它的存在意義)
- 結(jié)合SpringMVC內(nèi)置的filter做參考:https://www.cnblogs.com/a8457013/p/8260867.html
基于以上,
1)我們可以對(duì)資源類文件進(jìn)行攔截(設(shè)定字符編碼)
2)進(jìn)行URL級(jí)別的訪問控制(并非登錄這一種控制,是不是內(nèi)部接口,是否允許外部接口調(diào)用)
3)。。。
Filter使用:
1、創(chuàng)建Filter
public class TimeFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) {System.out.println("過濾器初始化");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("過濾器執(zhí)行了");long start2 = System.currentTimeMillis();filterChain.doFilter(servletRequest, servletResponse);long time = System.currentTimeMillis() - start2;System.out.println("過濾器執(zhí)行的時(shí)間是 :" + time);System.out.println("過濾器執(zhí)行結(jié)束");}@Overridepublic void destroy() {System.out.println("過濾器銷毀了");} }2、web.xml中配置(可以配置多個(gè),從上到下執(zhí)行)
<!-- 自定義過濾器 --> <filter> <filter-name>firstfilter</filter-name> <filter-class>com.filter.filterFirst</filter-class> <!-- 設(shè)置初始化參數(shù) --> <init-param> <param-name>nofilterpath</param-name> <param-value>login</param-value> </init-param> </filter> <filter-mapping> <filter-name>firstfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>3、訪問順序:
4、生命周期
生命周期
3、攔截器
攔截器使用
1、創(chuàng)建Interceptor
public class TestInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {System.out.println("preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {System.out.println("postHandle");}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {System.out.println("afterCompletion");} }2、在web.xml中配置
<!-- 配置攔截器 --><mvc:interceptors><!-- 全局的攔截器 --><bean class="com.xcy.interceptor.HandlerInterceptor1" /><!-- 指定路徑攔截器,按順序執(zhí)行 --><mvc:interceptor><mvc:mapping path="/api/user/**" /> <bean class="com.xcy.interceptor.HandlerInterceptor2" /></mvc:interceptor><mvc:interceptor><mvc:mapping path="/api/person/**" /><bean class="com.xcy.interceptor.HandlerInterceptor3" /></mvc:interceptor></mvc:interceptors>3、調(diào)用鏈
攔截器和過濾器執(zhí)行順序:
1).Filter.init();
2).Filter.doFilter(); before doFilter
3).HandlerInterceptor.preHandle();
4).Controller方法執(zhí)行
5).HandlerInterceptor.postHandle();
6).DispatcherServlet視圖渲染
7).HandlerInterceptor.afterCompletion();
8).Filter.doFilter(); after doFilter
9).Filter.destroy();
preHandle是在請(qǐng)求到達(dá)Controller之前實(shí)現(xiàn),可進(jìn)行用戶校驗(yàn)登錄等操作,返回true后,請(qǐng)求到達(dá)Controller層;postHandle方法是在執(zhí)行完Controller層代碼之后,DispatcherServlet進(jìn)行視圖的渲染之前
執(zhí)行,因此可以對(duì)ModelAndView 對(duì)象進(jìn)行處理;afterCompletion方法是在DispatcherServlet進(jìn)行視圖的渲染之后執(zhí)行調(diào)用,主要是進(jìn)行一些資源清理等工作。
注:只能對(duì)Controller請(qǐng)求進(jìn)行攔截,對(duì)一些靜態(tài)資源無法攔截。
4、過濾器和攔截器的區(qū)別
過濾器和攔截器的區(qū)別:
①攔截器是基于java的反射機(jī)制的,而過濾器是基于函數(shù)回調(diào)。
②攔截器不依賴與servlet容器,過濾器依賴與servlet容器。
③攔截器只能對(duì)action請(qǐng)求起作用,而過濾器則可以對(duì)幾乎所有的請(qǐng)求起作用。
④攔截器可以訪問action上下文、值棧里的對(duì)象,而過濾器不能訪問。
⑤在action的生命周期中,攔截器可以多次被調(diào)用,而過濾器只能在容器初始化時(shí)被調(diào)用一次。
⑥攔截器可以獲取IOC容器中的各個(gè)bean,而過濾器就不行,這點(diǎn)很重要,在攔截器里注入一個(gè)service,可以調(diào)用業(yè)務(wù)邏輯。
5、總結(jié)
- 在這篇博客里有一個(gè)理論:
其實(shí)我感覺這種理解方式也是對(duì)的,因?yàn)樵赟pringBoot中使用時(shí),貌似就是這種概念!
總結(jié)
以上是生活随笔為你收集整理的008--【SpringBoot】过滤器,拦截器,切面的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于web出现此问题:index:25
- 下一篇: Unexpected token o i