第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Spring MVC 攔截器

1. 前言

說起 Spring MVC 框架的攔截器,就不得不提起原生 Servlet 中的過濾器,兩者的功能性質(zhì)是一樣的,但底層實(shí)現(xiàn)機(jī)制會(huì)有差異性。攔截器用到了代理設(shè)計(jì)模式,是 Spring AOP 的具體實(shí)際應(yīng)用。過濾器使用的是函數(shù)回調(diào)機(jī)制。

本節(jié)課程將和大家一起學(xué)習(xí) Spring MVC 中的攔截器。通過本節(jié)課程,你將了解到攔截器的工作模式及基礎(chǔ)原理。重點(diǎn)是要掌握攔截器的實(shí)現(xiàn)過程。

2. 攔截器的概念

攔截器是什么?

攔截器就是一個(gè)功能模塊,工作模式?jīng)Q定了其與眾不同:

  • 非侵入式: Spring MVC 的攔截器是 AOP 編程思想的實(shí)際應(yīng)用,可以在不影響服務(wù)對(duì)象代碼結(jié)構(gòu)的條件下提供附加功能;
  • 動(dòng)態(tài)裝配、拆卸: 需要時(shí)就裝配,不需要時(shí)可拆卸。與被服務(wù)的對(duì)象之間具有極低的耦合度。

2.1 攔截器的工作位置

Spring MVC 中的攔截器和 Servlet 中的過濾器的生命周期、以及服務(wù)的目標(biāo)有差異性。過濾器的生命周期由服務(wù)器維護(hù),當(dāng)請(qǐng)求包進(jìn)入服務(wù)器或響應(yīng)包即將離開服務(wù)器時(shí),過濾器將起作用。

過濾器是在 DispatcherServlet 之前或之后工作,攔截器是請(qǐng)求經(jīng)過 DispatcherServlet 后進(jìn)行攔截。

圖片描述

攔截器屬于 Spring MVC 組件,生命周期由 Spring 上下文容器對(duì)象維護(hù)。從細(xì)節(jié)上講,攔截器可以在用戶控制器之前、之后或視圖渲染完成之后行使攔截工作。

圖片描述

2.2 攔截器應(yīng)用場(chǎng)景

攔截器可以解決很多實(shí)際問題:

  • 日志記錄: 記錄請(qǐng)求信息的日志,以便進(jìn)行信息監(jiān)控、信息統(tǒng)計(jì)、計(jì)算 PV(Page View)等;
  • 權(quán)限檢查: 如登錄檢測(cè),進(jìn)入處理器前檢測(cè)用戶是否登錄,如果沒有直接返回到登錄頁面;
  • 性能監(jiān)控: 通過攔截器在進(jìn)入處理器之前記錄開始時(shí)間,在處理完后記錄結(jié)束時(shí)間,從而得到該請(qǐng)求的處理時(shí)間;
  • 通用行為: 讀取 cookie 得到用戶信息并將用戶對(duì)象放入請(qǐng)求,從而方便后續(xù)流程使用,還有如提取 Locale、Theme 信息等只要是多個(gè)處理器都需要的即可使用攔截器實(shí)現(xiàn)
  • OpenSessionInView:Hibernate,在進(jìn)入處理器打開 Session,在完成后關(guān)閉 Session。

除以上應(yīng)用場(chǎng)景之外,你可以根據(jù)自己的業(yè)務(wù)需要靈活選擇。

3. 自定義攔截器

Spring MVC 內(nèi)置有很多攔截器。這些攔截器提供的功能,基本上能夠滿足開發(fā)者完成常規(guī)開發(fā)。但是,需求總是瞬息變化的,開發(fā)者可以根據(jù)自己的業(yè)務(wù)需求自定義攔截器。

3.1 攔截器接口規(guī)范

自定義攔截器之前,首先要了解 Spring MVC 提供的攔截器接口,自定義攔截器必須遵循此接口規(guī)范。

public interface HandlerInterceptor {
	/**
	 * 用戶控制器之前攔截,實(shí)現(xiàn)用戶控制器數(shù)據(jù)的預(yù)處理工作,第三個(gè)參數(shù)為響應(yīng)的用戶控制器
	 */
	default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		return true;
	}
	/**
	 *對(duì)用戶控制器處理后的數(shù)據(jù)再進(jìn)一步處理
	 */
	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}

	/**
	 * 視圖解析器對(duì) View 渲染完成后對(duì)最后結(jié)果進(jìn)行處理
	 */
	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}
}

Spring MVC 提供有攔截器適配器,適配器對(duì)攔截器接口做了簡(jiǎn)單封裝。

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor{
	//……
}

3.2 自定義流程

開發(fā)者可以通過實(shí)現(xiàn)接口或繼承適配器這 2 種方式開發(fā)自己的攔截器。如自定義一個(gè)攔截器,監(jiān)控控制器處理時(shí)間。

  1. 自定義攔截器類;
public class MyInterceptor extends HandlerInterceptorAdapter {
   	private long startTimer;
	private long endTimer;
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
   	//調(diào)用控制器之前的時(shí)間
   	startTimer = System.currentTimeMillis();
	 return true;
   }
   
   @Override
   public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,   ModelAndView modelAndView) throws Exception {
        //控制器處理完成后的時(shí)間
     	endTimer = System.currentTimeMillis();
		System.out.println(endTimer-startTimer);
   }

   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
      //輸出頁面渲染完成后的時(shí)間
      System.out.println("完成攔截器工作");
   }
}
  1. 通過攔截器配置告訴 Spring 它的存在。配置方式有 2 種:

注解方式: 打開 WebConfig 文件,添加如下代碼。

public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
	MyInterceptor myInterceptor = new MyInterceptor();
	registry.addInterceptor(myInterceptor).addPathPatterns("/student/*");
}

Tips: 此攔截器僅對(duì) /student/* 請(qǐng)求地址有效。

xml 方式:

<mvc:interceptors>
     <mvc:interceptor>
         <mvc:mapping path="需要攔截的路徑"/>
        <bean class="自定義interceptor全路徑名">
 </mvc:interceptor>
</mvc:interceptors>

Tips:本課程以注解為主,XML 在這里只做簡(jiǎn)要介紹。

  1. 編寫測(cè)試控制器;
@RequestMapping("/student")
public class StudentAction {
	@RequestMapping("/test")
	public String interceptor() {
		return "index";
	}
}
  1. 測(cè)試攔截是否能正常工作。
    發(fā)布項(xiàng)目,啟動(dòng) tomcat 服務(wù)器,在瀏覽器中輸入 http://localhost:8888/sm-demo/student/test ,查看控制臺(tái)上的輸出。
    圖片描述

3.3 攔截器鏈

所謂攔截器鏈,指多個(gè)攔截器一起協(xié)作工作,攔截器一起工作時(shí),請(qǐng)注意攔截器中的各個(gè)方法之間的調(diào)用順序。

圖片描述

前面攔截器的 preHandle 方法的返回值會(huì)影響后面的攔截器和控制器是否正常工作:

  • 如果返回 true 表示繼續(xù)流程,可繼續(xù)調(diào)用下一個(gè)攔截器或進(jìn)入控制器;
  • 如果返回 false 表示流程中斷,如登錄身份檢查失敗。不會(huì)繼續(xù)調(diào)用其他的攔截器或處理器。

Tips : 如果第一個(gè)攔截器的 preHandle 方法返回 true,則會(huì)進(jìn)入第二個(gè)攔截器。如果第二個(gè)攔截器的 preHandle 方法 返回 false,則直接進(jìn)入第一個(gè)攔截器的 afterCompletion 方法。

4. 小結(jié)

本章節(jié)和大家講解了 Spring MVC 的攔截器,需要大家掌握攔截的工作原理以及實(shí)現(xiàn)自定義攔截器。特別注意的是要理解多個(gè)攔截器在一起協(xié)作工作時(shí)方法之間是如何調(diào)用的。