1. 程式人生 > >spring boot最新教程(十):在spring boot中使用攔截器

spring boot最新教程(十):在spring boot中使用攔截器

       前一篇博文對過濾器的定義做了說明,過濾器屬於Servlet範疇的API,與Spring 沒什麼關係。Web開發中,我們除了使用 Filter 來過濾請web求外,還可以使用Spring提供的HandlerInterceptor(攔截器)。HandlerInterceptor 的功能跟過濾器類似,但是提供更精細的的控制能力:在request被響應之前、request被響應之後、檢視渲染之前以及request全部結束之後。我們不能通過攔截器修改request內容,但是可以通過丟擲異常(或者返回false)來暫停request的執行。

      配置攔截器也很簡單,Spring 為什麼提供了基礎類WebMvcConfigurerAdapter ,我們只需要重寫 addInterceptors方法添加註冊攔截器。
實現自定義攔截器只需要3步:
1、建立我們自己的攔截器類並實現 HandlerInterceptor 介面或繼承HandlerInterceptorAdapter。
2、建立一個Java類繼承WebMvcConfigurerAdapter,並重寫 addInterceptors 方法。
3、例項化我們自定義的攔截器,然後將對像手動新增到攔截器鏈中(在addInterceptors方法中新增)。
說明:本文重點在如何在Spring-Boot中使用攔截器,關於攔截器的原理請大家查閱資料瞭解。

建立攔截器

==========================LoginTimeInterceptor.java============================

package com.wx.Interceptor;

import java.util.Calendar;

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

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class LoginTimeInterceptor extends HandlerInterceptorAdapter{
	private int startTime;
	private int endTime;
	//依賴注入,請看配置檔案
	public void setStartTime(int startTime) {
		this.startTime = startTime;
	}

	public void setEndTime(int endTime) {
		this.endTime = endTime;
	}
	//在控制器執行前呼叫
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		System.out.println("執行preHandle方法-->01");
		Calendar cal = Calendar.getInstance();
		//獲得當前時間對應的小時數,例如:12:05-->12,13:15-->13
		int hour = cal.get(Calendar.HOUR_OF_DAY);
		if (startTime <= hour && hour < endTime) {
			return true;  //通過攔截器,繼續執行請求
		} else {//給定的時間之外禁止登入
			request.setAttribute("msg", "非登入時段");
			request.getRequestDispatcher("Login.jsp").forward(request, response);
			return false;  //沒有通過攔截器,返回登入頁面
		}
	}
	//在後端控制器執行後呼叫
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("執行postHandle方法-->02");
		super.postHandle(request, response, handler, modelAndView);
	}
	//整個請求執行完成後呼叫
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("執行afterCompletion方法-->03");
		super.afterCompletion(request, response, handler, ex);
	}
}

知識講解:此攔截器作用:如果使用者沒有在8-18點登入,則重定向到登入頁面。注意:
(1)攔截器必須繼承HandlerInterceptorAdapter類
(2)preHandle方法在後端控制器執行前被呼叫,postHandle方法在後端
控制器執行後被呼叫;afterCompletion方法在整個請求處理完成後被呼叫。
(3) preHandle方法:返回true,對映處理器執行鏈將繼續執行;當返回false時,DispatcherServlet處理器認為攔截器已經處理完了請求,而不
繼續執行執行鏈中的其它攔截器和處理器。它的API文件解釋如下:true if the execution chainshould proceed with the next interceptor or the handler itself. Else,DispatcherServlet assumes that this interceptor has already dealt with theresponse itself.
(4)這三個方法都是相同的引數,Object handler引數可以轉化成一個後端控制器物件,比如這裡可以轉換成LoginControl物件。

新增攔截器

package com.wx.boot;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.wx.Interceptor.LoginTimeInterceptor;

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter{
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		//這裡可以新增多個攔截器
		registry.addInterceptor(new LoginTimeInterceptor()).addPathPatterns("/**");
		super.addInterceptors(registry);
	}
}
附,這裡新增了2個全域性配置
server.port=8080
server.servlet-path=*.php
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
logging.level.org.springframework=INFO
#配置ContextPath
server.context-path=/BootInterceptor
#jsp,servlet修改後無需重新發布
server.jsp-servlet.init-parameters.development=true
一個是配置Context-path

      Spring boot預設是/ ,這樣直接通過http://ip:port/就可以訪問到index頁面,如果要修改為http://ip:port/path/ 訪問
的話,那麼需要在Application.properties檔案中加入server.context-path = /你的path,比如:spring-boot,那麼訪問
地址就是http://ip:port/spring-boot 路徑。

第二個是配置jsp,servlet修改後無需重新發布

      如果修改jsp後每次都要重新發布,那開發效率就會太低了。

這個兩個配置很重要!

好了,釋出執行