springmvc 的攔截器

Springmvc的處理器攔截器類似于Servlet 開發(fā)中的過濾器Filter惜傲,用于對(duì)處理器進(jìn)行預(yù)處理和后處理屈芜。本文主要總結(jié)一下springmvc中攔截器是如何定義的,以及測試攔截器的執(zhí)行情況和使用方法娜搂。

1. springmvc攔截器的定義和配置

1.1 springmvc攔截器的定義

  在springmvc中鲜屏,定義攔截器要實(shí)現(xiàn)HandlerInterceptor接口,并實(shí)現(xiàn)該接口中提供的三個(gè)方法昔驱,如下:

//測試攔截器1

public class HandlerInterceptor1 implements HandlerInterceptor{

? ? @Override

? ? public boolean preHandle(HttpServletRequest request,

? ? ? ? ? ? HttpServletResponse response, Object handler) throws Exception {

? ? ? ? System.out.println("HandlerInterceptor1....preHandle");

? ? ? ? //false表示攔截疹尾,不向下執(zhí)行;true表示放行

? ? ? ? return true;

? ? }

? ? @Override

? ? public void postHandle(HttpServletRequest request,

? ? ? ? ? ? HttpServletResponse response, Object handler,

? ? ? ? ? ? ModelAndView modelAndView) throws Exception {

? ? ? ? System.out.println("HandlerInterceptor1....postHandle");

? ? }

? ? @Override

? ? public void afterCompletion(HttpServletRequest request,

? ? ? ? ? ? HttpServletResponse response, Object handler, Exception ex)

? ? ? ? ? ? throws Exception {

? ? ? ? System.out.println("HandlerInterceptor1....afterCompletion");

? ? }

}

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

  針對(duì)這三個(gè)方法骤肛,我做一下簡單的分析:

preHandle方法:進(jìn)入Handler方法之前執(zhí)行纳本。可以用于身份認(rèn)證腋颠、身份授權(quán)繁成。比如如果認(rèn)證沒有通過表示用戶沒有登陸,需要此方法攔截不再往下執(zhí)行(return false)秕豫,否則就放行(return true)朴艰。

postHandle方法:進(jìn)入Handler方法之后观蓄,返回ModelAndView之前執(zhí)行。可以看到該方法中有個(gè)modelAndView的形參评肆。應(yīng)用場景:從modelAndView出發(fā):將公用的模型數(shù)據(jù)(比如菜單導(dǎo)航之類的)在這里傳到視圖损合,也可以在這里同一指定視圖。

afterCompletion方法:執(zhí)行Handler完成之后執(zhí)行亲茅。應(yīng)用場景:統(tǒng)一異常處理回铛,統(tǒng)一日志處理等。

1.2 springmvc攔截器的配置

  在springmvc中克锣,攔截器是針對(duì)具體的HandlerMapping進(jìn)行配置的茵肃,也就是說如果在某個(gè)HandlerMapping中配置攔截,經(jīng)過該 HandlerMapping映射成功的handler最終使用該攔截器袭祟。比如验残,假設(shè)我們在配置文件中配置了的映射器是org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,那么我們可以這樣來配置攔截器:

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">

? ? <property name="interceptors">

? ? ? ? <list>

? ? ? ? ? ? <ref bean="handlerInterceptor1"/>

? ? ? ? ? ? <ref bean="handlerInterceptor2"/>

? ? ? ? </list>

? ? </property>

</bean>

<bean id="handlerInterceptor1" class="ssm.intercapter.HandlerInterceptor1"/>

<bean id="handlerInterceptor2" class="ssm.intercapter.HandlerInterceptor2"/>

1

2

3

4

5

6

7

8

9

10

  那么在springmvc中巾乳,如何配置類似于全局的攔截器呢您没?上面也說了,springmvc中的攔截器是針對(duì)具體的映射器的胆绊,為了解決這個(gè)問題氨鹏,springmvc框架將配置的類似全局的攔截器注入到每個(gè)HandlerMapping中,這樣就可以成為全局的攔截器了压状。配置如下:

<!-- 配置攔截器 -->

<mvc:interceptors>

? ? <!-- 多個(gè)攔截器仆抵,按順序執(zhí)行 -->? ? ? ?

? ? <mvc:interceptor>

? ? ? ? <mvc:mapping path="/**"/> <!-- 表示攔截所有的url包括子url路徑 -->

? ? ? ? <bean class="ssm.interceptor.HandlerInterceptor1"/>

? ? </mvc:interceptor>

? ? <mvc:interceptor>

? ? ? ? <mvc:mapping path="/**"/>

? ? ? ? <bean class="ssm.interceptor.HandlerInterceptor2"/>

? ? </mvc:interceptor>

? ? <mvc:interceptor>

? ? ? ? <mvc:mapping path="/**"/>

? ? ? ? <bean class="ssm.interceptor.HandlerInterceptor3"/>

? ? </mvc:interceptor>

</mvc:interceptors>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

  一般我們都用這種配置,<mvc:mapping>中指定要攔截的url即可。

2. springmvc攔截器的執(zhí)行測試

  仿照上面的HandlerInterceptor1再寫兩個(gè)攔截器镣丑,HandlerInterceptor2和HandlerInterceptor3还栓,配置是按照上面這個(gè)配置。然后我們來測試一下三個(gè)攔截器的執(zhí)行情況传轰,并做相關(guān)總結(jié)剩盒。

2.1 三個(gè)攔截器都放行

  也就是說,我們將三個(gè)攔截器的preHandle方法中返回值都改成true慨蛙,來測試一下攔截器的執(zhí)行順序辽聊,測試結(jié)果如下:

HandlerInterceptor1….preHandle

HandlerInterceptor2….preHandle

HandlerInterceptor3….preHandle

HandlerInterceptor3….postHandle

HandlerInterceptor2….postHandle

HandlerInterceptor1….postHandle

HandlerInterceptor3….afterCompletion

HandlerInterceptor2….afterCompletion

HandlerInterceptor1….afterCompletion

  根據(jù)打印的結(jié)果做一個(gè)總結(jié):當(dāng)所有攔截器都放行的時(shí)候,preHandle方法是按照配置的順序執(zhí)的期贫;而另外兩個(gè)方法按照配置的順序逆向執(zhí)行的跟匆。

2.2 有一個(gè)攔截器不放行

  我們將第三個(gè)攔截器的preHandle方法中返回值改成false,前兩個(gè)還是true通砍,來測試一下攔截器的執(zhí)行順序玛臂,測試結(jié)果如下:

HandlerInterceptor1….preHandle

HandlerInterceptor2….preHandle

HandlerInterceptor3….preHandle

HandlerInterceptor2….afterCompletion

HandlerInterceptor1….afterCompletion

根據(jù)打印的結(jié)果做一個(gè)總結(jié):

  1. 由于攔截器1和2放行,所以攔截器3的preHandle才能執(zhí)行封孙。也就是說前面的攔截器放行迹冤,后面的攔截器才能執(zhí)行preHandle。

  2. 攔截器3不放行虎忌,所以其另外兩個(gè)方法沒有被執(zhí)行泡徙。即如果某個(gè)攔截器不放行,那么它的另外兩個(gè)方法就不會(huì)背執(zhí)行膜蠢。

  3. 只要有一個(gè)攔截器不放行堪藐,所有攔截器的postHandle方法都不會(huì)執(zhí)行,但是只要執(zhí)行過preHandle并且放行的挑围,就會(huì)執(zhí)行afterCompletion方法礁竞。

2.3 三個(gè)攔截器都不放行

  這種情況其實(shí)可以參考上面的情況了,是一個(gè)特例杉辙,也看一下運(yùn)行結(jié)果:

HandlerInterceptor1….preHandle

  很明顯模捂,就只執(zhí)行了第一個(gè)攔截器的preHandle方法,因?yàn)槎疾环判凶嗨玻詻]有一個(gè)執(zhí)行postHandle方法和afterCompletion方法枫绅。

3. 攔截器的使用

  從第二種情況來看,比如現(xiàn)在要寫一個(gè)統(tǒng)一異常處理的邏輯硼端,那么要將該攔截器放在攔截器鏈的第一個(gè)位置并淋,且一定要放行,因?yàn)橹挥蟹判辛苏渥颍艜?huì)去執(zhí)行afterCompletion县耽,而且放在攔截器鏈的第一個(gè)的話句喷,afterCompletion方法會(huì)最后執(zhí)行,才能在里面執(zhí)行統(tǒng)一異常處理的邏輯兔毙。

  再比如唾琼,登陸認(rèn)證攔截器,放在攔截器鏈接中第一個(gè)位置(如果有統(tǒng)一異常處理澎剥,那么應(yīng)該放在統(tǒng)一異常處理的后面)锡溯。權(quán)限校驗(yàn)攔截器,放在登陸認(rèn)證攔截器之后(因?yàn)榈顷懲ㄟ^后才校驗(yàn)權(quán)限)哑姚。

  這里寫一個(gè)登陸驗(yàn)證的攔截器來說明一下如何使用springmvc的攔截器祭饭。

3.1 需求

  首先看一下需求:我們要攔截啥,攔截到了要干啥叙量。思路如下:

1倡蝙、用戶請求url

2、攔截器進(jìn)行攔截校驗(yàn)

如果請求的url是公開地址(無需登陸即可訪問的url)绞佩,讓放行寺鸥。

如果用戶session不存在,則跳轉(zhuǎn)到登陸頁面品山。

如果用戶session存在則放行胆建,繼續(xù)操作。

3.2 實(shí)現(xiàn)登陸的Controller方法

//登陸

@RequestMapping("/login")

public String login(HttpServletRequest request, String username, String password) throws Exception {

? ? //實(shí)際中要去和數(shù)據(jù)庫匹配的

? ? //....

? ? //這里就假設(shè)登陸成功了

? ? HttpSession session = request.getSession();

? ? session.setAttribute("username", username);

? ? return "redirect:queryItems.action";

}

//退出

@RequestMapping("/logout")

public String logout(HttpServletRequest request) throws Exception {

? ? HttpSession session = request.getSession();

? ? session.invalidate();

? ? return "redirect:queryItems.action";

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

3.2 登陸驗(yàn)證攔截器的實(shí)現(xiàn)

//測試攔截器1

public class LoginInterceptor implements HandlerInterceptor{

? ? //進(jìn)入Handler方法之前執(zhí)行

? ? //可以用于身份認(rèn)證谆奥、身份授權(quán)眼坏。如果認(rèn)證沒有通過表示用戶沒有登陸拂玻,需要此方法攔截不再往下執(zhí)行酸些,否則就放行

? ? @Override

? ? public boolean preHandle(HttpServletRequest request,

? ? ? ? ? ? HttpServletResponse response, Object handler) throws Exception {

? ? ? ? //獲取請求的url

? ? ? ? String url = request.getRequestURI();

? ? ? ? //判斷url是否公開地址(實(shí)際使用時(shí)將公開地址配置到配置文件中)

? ? ? ? //這里假設(shè)公開地址是否登陸提交的地址

? ? ? ? if(url.indexOf("login.action") > 0) {

? ? ? ? ? ? //如果進(jìn)行登陸提交,放行

? ? ? ? ? ? return true;

? ? ? ? }

? ? ? ? //判斷session

? ? ? ? HttpSession session = request.getSession();

? ? ? ? //從session中取出用戶身份信息

? ? ? ? String username = (String) session.getAttribute("username");

? ? ? ? if(username != null) {

? ? ? ? ? ? return true;

? ? ? ? }

? ? ? ? //執(zhí)行到這里表示用戶身份需要驗(yàn)證檐蚜,跳轉(zhuǎn)到登陸頁面

? ? ? ? request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);

? ? ? ? return false;

? ? }

? ? //節(jié)省空間魄懂,省略另外兩個(gè)方法不寫了,也不用處理

}

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

然后配置該攔截器:

<!-- 配置攔截器 -->

<mvc:interceptors>

? ? <!-- 多個(gè)攔截器闯第,按順序執(zhí)行 -->? ?

? ? <mvc:interceptor>

? ? ? ? <mvc:mapping path="/**"/> <!-- 攔截所有的url包括子url路徑 -->

? ? ? ? <bean class="ssm.interceptor.LoginInterceptor"/>

? ? </mvc:interceptor>

? ? <!-- 其他攔截器 -->

</mvc:interceptors>

1

2

3

4

5

6

7

8

9

  這樣當(dāng)我們?nèi)我庹埱笠粋€(gè)url的時(shí)候市栗,就會(huì)被剛剛我們定義的攔截器給捕獲到,然后會(huì)判斷是否session中有用戶信息咳短,沒有的話就會(huì)跳到登陸頁面讓我們登陸:

<form action="${pageContext.request.contextPath }/login.action" method="post">

? ? 用戶名:<input type="text" name="username" /><br>

? ? 密碼:<input type="password" name="password" /><br>

? ? <input type="submit" name="提交" />

</form>

1

2

3

4

5

攔截器的使用基本上就總結(jié)到這了填帽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市咙好,隨后出現(xiàn)的幾起案子篡腌,更是在濱河造成了極大的恐慌,老刑警劉巖勾效,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘹悼,死亡現(xiàn)場離奇詭異叛甫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杨伙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門其监,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人限匣,你說我怎么就攤上這事抖苦。” “怎么了米死?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵睛约,是天一觀的道長。 經(jīng)常有香客問我哲身,道長辩涝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任勘天,我火速辦了婚禮怔揩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘脯丝。我一直安慰自己商膊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布宠进。 她就那樣靜靜地躺著晕拆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪材蹬。 梳的紋絲不亂的頭發(fā)上实幕,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音堤器,去河邊找鬼昆庇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛闸溃,可吹牛的內(nèi)容都是我干的整吆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辉川,長吁一口氣:“原來是場噩夢啊……” “哼表蝙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起乓旗,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤府蛇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后寸齐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體欲诺,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抄谐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扰法。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛹含。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖塞颁,靈堂內(nèi)的尸體忽然破棺而出浦箱,到底是詐尸還是另有隱情,我是刑警寧澤祠锣,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布酷窥,位于F島的核電站,受9級(jí)特大地震影響伴网,放射性物質(zhì)發(fā)生泄漏蓬推。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一澡腾、第九天 我趴在偏房一處隱蔽的房頂上張望沸伏。 院中可真熱鬧,春花似錦动分、人聲如沸毅糟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姆另。三九已至,卻和暖如春坟乾,著一層夾襖步出監(jiān)牢的瞬間迹辐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工糊渊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留右核,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓渺绒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親菱鸥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宗兼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一、簡介 SpringMVC 的攔截器處理器類似于Servlet開發(fā)中的過濾器Filter氮采,用于對(duì)處理器進(jìn)...
    守住陽光閱讀 1,118評(píng)論 0 0
  • 姓名: 李小娜 [嵌牛導(dǎo)讀]: SpringMVC 中的Interceptor 攔截器也是相當(dāng)重要和相當(dāng)有用的殷绍,...
    n184閱讀 3,166評(píng)論 0 4
  • 轉(zhuǎn):https://blog.csdn.net/xiaoyaotan_111/article/details/53...
    神豪VS勇士贏閱讀 1,082評(píng)論 0 3
  • 對(duì)于java中的思考的方向,1必須要看前端的頁面鹊漠,對(duì)于前端的頁面基本的邏輯主到,如果能理解最好茶行,不理解也要知道幾點(diǎn)。 ...
    神尤魯?shù)婪?/span>閱讀 815評(píng)論 0 0
  • 本文作者:鐘昕靈登钥,叩丁狼高級(jí)講師畔师。原創(chuàng)文章,轉(zhuǎn)載請注明出處牧牢。 前言 Spring MVC屬于SpringFrame...
    叩丁狼教育閱讀 3,296評(píng)論 1 4