-
1 # Java程式設計師鄭州
-
2 # 梁碼事
給你寫了一個例子,拒絕複製貼上。直接看例子,兩步就可以。
第一,定義攔截器
第二,註冊攔截器
上面攔截器就是攔截列印所有請求。
注意攔截器類和註冊類的註解。
-
3 # java架構設計
SpringBoot中可以使用Intercept和Filter兩種方式來實現攔截器。本文主要給大家講解一下這兩種方式的實現方式以及Filter和Intercept的區別。
Intercept實現方式先定義一個攔截器類,需要繼承HandlerInterceptor介面,點選這個介面可以看到有三個方法可以被實現,之所以說可以被實現,因為這三個方法被default修飾了,也就是非必須實現,接口裡面已經有了這個介面的預設實現,這是java8的新特性。
所以當我們建立一個自定義的攔截器類的時候,是可以選擇是否去實現其中的方法,比如大多數的情況下,我們只需要實現preHandler這個方法就可以滿足我們的業務了,那麼postHandle和afterCompletion方法就不需要實現了:
定義好攔截器類後,需要把這個攔截器載入到攔截器鏈中,所以我們需要WebConfig類,這個類需要實現WebMvcConfigurer介面類:
ok,一個攔截器就新增好了~
WebMvcConfigurer的作用就是為我們實現了通用的攔截器,我們如果想新增一些業務相關的攔截器,那麼就實現這個介面類,然後像上面這樣操作即可。
Filter實現方式Filter實現還是之前的Servlet方式,先定義一個TestFilter類繼承Filter介面:
然後再定義一個FilterConf類,把這個TestFilter註冊到過濾器鏈中:
大家可以看到這裡面有一個FilterRegistrationBean類,這個類就是SpringBoot為大家提供的過濾器,只要把你自定義的Filter新增到這裡來就可以了,大家也可以自己去實現以下,然後點選上面這些方法看看FilterRegistrationBean為我們做了哪些事情。
如果有多個過濾器怎麼辦呢?
這個方法就是設定過濾器的優先順序,可以根據業務需要定製自己的攔截器的執行順序。
Filter和Intercept的區別上面就是為大家帶來的在SpringBoot中實現攔截器的兩種方式,通常我們在做API專案的時候,可以在介面請求之前校驗前端傳遞過來的token是否合法,也可以在這裡設定是否允許跨域。跨域的知識大家有興趣也可以學習一下,還是很有意思的。
這裡再和大家一起學習下過濾器和攔截器的區別,面試中也經常會有這樣的面試題:
Filter是基於函式回撥,而Intercept是基於java的反射機制;
Filter是servlet的技術,而Intercept是註冊在spring容器中,它不依賴servlet容器
Filter可以攔截幾乎所有的請求(包含對靜態資源的請求),而Intercept只攔截action請求(不攔截靜態資源請求)
Filter不能訪問action上下文及值棧裡的物件,而Intercept都是可以的;
Intercept可以獲取spring容器裡的物件,而Filter是不行的;
Intercept在action的生命週期內是可以多次呼叫,而Filter只在容器初始化時被呼叫一次。
瞭解了以上的區別之後,相信大家在實際開發使用過程中便可以根據不同的業務場景具體是選擇Filter還是Intercept就能心中有數了。
-
4 # 鮑家大少
1 首先我們簡單的定義一個Controller類
@RestController
public class LoginController {
@PostMapping("/login")
public String Login(@RequestParam("Username") String username,
@RequestParam("Password") String password,
Map<String,Object> map, HttpSession session){
if(!StringUtils.isEmpty(username) && "123456".equals(username))
{
session.setAttribute("loginUser",username);
return "true";
}
else
{
return "false";
}
}
@GetMapping("/login")
public String Login(HttpServletRequest request){
HttpSession session = request.getSession();
request.getRequestURI();
session.setAttribute("User","User");
return "登入";
}
}
2 寫一個LoginHandlerInterceptor 類繼承了HandlerInterceptor 來實現攔截器的作用。
其中有三個方法:
preHandle:該方法在處理請求之前進行呼叫,就是在執行Controller的任務之前。如果返回true就繼續往下執行,返回false就放棄執行。
postHandle:該方法將在請求處理之後,DispatcherServlet進行檢視返回渲染之前進行呼叫,可以在這個方法中對Controller 處理之後的ModelAndView 物件進行操作。
afterCompletion:該方法也是需要當前對應的Interceptor的preHandle方法的返回值為true時才會執行,該方法將在整個請求結束之後,也就是在DispatcherServlet 渲染了對應的檢視之後執行。用於進行資源清理。
/**
* 登入檢查,
*/
public class LoginHandlerInterceptor implements HandlerInterceptor {
/**
* 該方法在處理請求之前進行呼叫,就是在執行Controller的任務之前。
* 如果返回true就繼續往下執行,返回false就放棄執行。
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("------preHandle-----------");
HttpSession session=request.getSession();
return true;
// if(session.getAttribute("User")!=null){
// return true;
// }
// String url = "/index.html";
// request.getRequestDispatcher(url).forward(request,response);
// return false;
}
/**
* 該方法將在請求處理之後,DispatcherServlet進行檢視返回渲染之前進行呼叫,
* 可以在這個方法中對Controller 處理之後的ModelAndView 物件進行操作。
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
//
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("------postHandle-----------");
}
/**
* 該方法也是需要當前對應的Interceptor的preHandle方法的返回值為true時才會執行,
* 該方法將在整個請求結束之後,也就是在DispatcherServlet 渲染了對應的檢視之後執行。
* 用於進行資源清理。
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("------afterCompletion-----------");
}
}
3 配置檔案
好了。我們再寫一個配置檔案。把這個LoginHandlerInterceptor 新增到容器中讓他在程式啟動的時候自動注入。
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Bean
public LoginHandlerInterceptor getLoginInerceptor(){
return new LoginHandlerInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("---addInterceptors---");
LoginHandlerInterceptor sessionInterceptor=new LoginHandlerInterceptor();
registry.addInterceptor(sessionInterceptor).addPathPatterns("/login/**")
.excludePathPatterns("/verify");
}
}
大功告成,我們來看看三者的執行順序:
-
5 # 程式猿W
如何擴充套件springmvc的配置(springboot提我們自己配置的springmvc的功能不丟失的情況下) 比如我需要使用自己定義的攔截器我們需要自己寫一個配置類 繼承 WebMvcConfigurerAdapter 需要什麼元件就註冊什麼元件
定製攔截器分為以下兩種:
(1) 使用springmvc 的攔截器
(2) 使用filter實現過濾器
如何往容器中新增一個攔截器第一步:建立一個攔截器
第二步:註冊攔截器
往容器中增加一個過濾器也可以使用AOP 來實現攔截器
filter/攔截器/aop的區別filter:只能攔截url,不能獲取方法名稱攔截器:能獲取url ,獲取方法名稱,不能獲取方法引數aop: 可以獲取到引數
回覆列表
實現自定義攔截器只需要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後每次都要重新發布,那開發效率就會太低了。
這個兩個配置很重要!