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後每次都要重新發布,那開發效率就會太低了。
這個兩個配置很重要!
好了,釋出執行