實(shí)現(xiàn)handlerinterceptor接口或者繼承handlerinterceptor的子類,比如spring 已經(jīng)提供的實(shí)現(xiàn)了handlerinterceptor 接口的抽象類handlerinterceptoradapter ,下面講實(shí)現(xiàn)其接口的寫法,先看一下這個(gè)接口的三個(gè)方法.
- 方法prehandle: 顧名思義,該方法將在請求處理之前進(jìn)行調(diào)用,在controller之前執(zhí)行。springmvc 中的interceptor 是鏈?zhǔn)降恼{(diào)用的,在一個(gè)應(yīng)用中或者說是在一個(gè)請求中可以同時(shí)存在多個(gè)interceptor 。每個(gè)interceptor 的調(diào)用會(huì)依據(jù)它的聲明順序依次執(zhí)行,而且最先執(zhí)行的都是interceptor 中的prehandle 方法,所以可以在這個(gè)方法中進(jìn)行一些前置初始化操作或者是對當(dāng)前請求的一個(gè)預(yù)處理,比如說獲取cookie的值或者判斷是否已經(jīng)登錄,也可以在這個(gè)方法中進(jìn)行一些判斷來決定請求是否要繼續(xù)進(jìn)行下去。該方法的返回值是布爾值boolean 類型的,當(dāng)它返回為false 時(shí),表示請求結(jié)束,后續(xù)的interceptor 和controller 都不會(huì)再執(zhí)行;當(dāng)返回值為true 時(shí)就會(huì)繼續(xù)調(diào)用下一個(gè)interceptor 的prehandle 方法,如果已經(jīng)是最后一個(gè)interceptor 的時(shí)候就會(huì)是調(diào)用當(dāng)前請求的controller 方法。
- 方法posthandle:由prehandle 方法的解釋我們知道這個(gè)方法包括后面要說到的aftercompletion 方法都只能是在當(dāng)前所屬的interceptor 的prehandle 方法的返回值為true 時(shí)才能被調(diào)用。posthandle 方法,顧名思義就是在當(dāng)前請求進(jìn)行處理之后,也就是controller 方法調(diào)用之后執(zhí)行,但是它會(huì)在dispatcherservlet 進(jìn)行視圖返回渲染之前被調(diào)用,所以我們可以在這個(gè)方法中對controller 處理之后的modelandview 對象進(jìn)行操作,比如說設(shè)置cookie,返回給前端。posthandle 方法被調(diào)用的方向跟prehandle 是相反的,也就是說先聲明的interceptor 的posthandle 方法反而會(huì)后執(zhí)行
- 方法aftercompletion:該方法也是需要當(dāng)前對應(yīng)的interceptor 的prehandle 方法的返回值為true 時(shí)才會(huì)執(zhí)行。顧名思義,該方法將在整個(gè)請求結(jié)束之后,也就是在dispatcherservlet 渲染了對應(yīng)的視圖之后執(zhí)行。這個(gè)方法的主要作用是用于進(jìn)行資源清理工作的。
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
@component public class authinterceptor implements handlerinterceptor { private static final string token_cookie = "token" ; @autowired private userdao userdao; @override public boolean prehandle(httpservletrequest req, httpservletresponse res, object handler) throws exception { map<string, string[]> map = req.getparametermap(); map.foreach((k,v) ->req.setattribute(k, joiner.on( "," ).join(v))); string requesturi = req.getrequesturi(); if (requesturi.startswith( "/static" ) || requesturi.startswith( "/error" )) { return true ; } cookie cookie = webutils.getcookie(req, token_cookie); if (cookie != null && stringutils.isnoneblank(cookie.getvalue())) { user user = userdao.getuserbytoken(cookie.getvalue()); if (user != null ) { req.setattribute(commonconstants.login_user_attribute, user); usercontext.setuser(user); } } return true ; } @override public void posthandle(httpservletrequest req, httpservletresponse res, object handler, modelandview modelandview) throws exception { string requesturi = req.getrequesturi(); if (requesturi.startswith( "/static" ) || requesturi.startswith( "/error" )) { return ; } user user = usercontext.getuser(); if (user != null && stringutils.isnoneblank(user.gettoken())) { string token = requesturi.startswith( "logout" )? "" : user.gettoken(); cookie cookie = new cookie(token_cookie, token); cookie.setpath( "/" ); cookie.sethttponly( false ); res.addcookie(cookie); } } @override public void aftercompletion(httpservletrequest req, httpservletresponse response, object handler, exception ex) throws exception { usercontext.remove(); } } |
總結(jié)
以上所述是小編給大家介紹的springmvc攔截器執(zhí)行順序及各方法作用詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對服務(wù)器之家網(wǎng)站的支持!
原文鏈接:https://www.cnblogs.com/xiangkejin/archive/2018/07/25/9368984.html