學習SpringMVC——攔截器


  攔截器,顧名思義就是用來攔截的。

  那什么是攔截,又為什么要攔截。對於Spring MVC來說,攔截器主要的工作對象就是用戶的請求,攔截下來之后,我們可以在攔截的各個階段悉心呵護【為所欲為】。常見的比如可以做權限驗證,登錄系統后,系統獲取到你的請求然后分析下你的用戶權限,是Administrator還是User還是Guest。

 

主要相關類和方法

  HandlerExecutionChain

  該類主要由handler和handler interceptors組成

  HandlerMapping類通過getHandler方法會調用到該類

 

  HandlerInterceptor

  Spring MVC中對於一個請求可以添加多個攔截器,而這個攔截器集合中會鏈式調用這些攔截器。每個攔截器會執行固定順序的方法,而這些方法就定義在HandlerInterceptor類中。

  這是攔截器的一個基礎接口,里面有三個方法

 

boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

  使用時機:在處理請求之前

  應用場景:可以在該方法中放入一些初始化的操作,比如權限驗證,日志管理等

  注意:該方法的返回值是boolean類型,若返回值為true,則繼續調用后面的攔截器和目標方法,若返回為false,則不會調用后面的攔截器和目標方法,表示請求結束

 

void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception;

  使用時機:在調用目標方法之后,渲染視圖之前被調用。具體來說,是在調用了Controller中定義的方法之后,但在DispatcherServlet 處理視圖返回渲染結果之前被調用。

  應用場景:根據使用的時機就可以知道,該方法可以對Controller處理之后ModelAndView進行操作

  注意:當有多個interceptor的時候,對於preHandler的調用順序和postHandler的調用順序是恰恰想法的。

  舉例來說,現在有一個FirstInterceptor和一個SecondInterceptor,單獨調用FirstInterceptor的三個方法的順序為:

    FirstInterceptor.preHandle->HandlerAdapter.handle->FirstInterceptor.postHanle->DispatcherServlet.render->FirstInterceptor.afterCompletion。

  對於兩個interceptor的調用順序大致如下:

  可以總結出preHandler是先進先執行,而postHandler是先進后執行

 

void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception;

  使用時機:渲染視圖之后

  應用場景:釋放資源

 

具體應用

 

  新建攔截器類FirstInterceptor

  該類需實現HandlerInterceptor接口

package com.jackie.springmvc.interceptors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class FirstInterceptor implements HandlerInterceptor{

	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("Interceptor:afterCompletion");
		
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("Interceptor:postHandle");

		
	}

	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		System.out.println("Interceptor:preHandle");
		return true;
	}

}

  在三個方法中分別打印當前方法信息,通過執行,看這些方法是否執行以及執行的順序。

 

  配置springmvc.xml

<mvc:interceptors>
	<bean class="com.jackie.springmvc.interceptors.FirstInterceptor"></bean>
</mvc:interceptors>

 

  最后啟動tomcat服務,得到控制台輸出結果為:

    Interceptor:preHandle

    Interceptor:postHandle

    Interceptor:afterCompletion

 

  機智的你,可能會萌生一個想法,對於定義的這個FirstInterceptor,我並不想在任何場景下都要使用它,能不能再指定的場景下執行相應的攔截器,或者指定的場景下不執行呢,答案是肯定的!

  首先我們還是要新建另外一個攔截器SecondInterceptor

package com.jackie.springmvc.interceptors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class SecondInterceptor implements HandlerInterceptor{

	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("SecondInterceptor:afterCompletion");
		
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("SecondInterceptor:postHandle");

		
	}

	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		System.out.println("SecondInterceptor:preHandle");
		return true;
	}

}

  

  同時在springmvc.xml中添加

<mvc:interceptors>
	<bean class="com.jackie.springmvc.interceptors.FirstInterceptor"></bean>
	<!-- 配置攔截器(不)作用的路徑 -->
	<mvc:interceptor>
	<mvc:mapping path="/emps"/>
		<bean class="com.jackie.springmvc.interceptors.SecondInterceptor"></bean>
	</mvc:interceptor>
</mvc:interceptors>

 

  這樣我們在/emps下才能使SecondInterceptor有效,其他路徑的請求就不會觸發這個攔截器,效果如下:

 

 

至此,我們明白了:

  • 什么是攔截器
  • 攔截器的作用
  • 如何使用攔截器

 

如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!如果您想持續關注我的文章,請掃描二維碼,關注JackieZheng的微信公眾號,我會將我的文章推送給您,並和您一起分享我日常閱讀過的優質文章。

友情贊助

如果你覺得博主的文章對你那么一點小幫助,恰巧你又有想打賞博主的小沖動,那么事不宜遲,趕緊掃一掃,小額地贊助下,攢個奶粉錢,也是讓博主有動力繼續努力,寫出更好的文章^^。

    1. 支付寶                              2. 微信

                            


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM