Springboot中的自定義攔截器及原理詳解
攔截器機制
攔截器主要是用于在用戶請求控制中,對于請求識別,鑒權,以及區(qū)分資源是否可以被目標方法調用的安全機制。 要實現攔截器,SpringMvc 已經幫我集成好了,只需要實現 HandlerInterceptor 的接口,如果我們要寫一個攔截器,就要實現這個 HandlerInterceptor 這個攔截器的標準接口;
攔截器使用場景
我們常用于購物網站,比如說京東商城中,加入購物車之后,如果要結算,就會跳轉到登錄界面,這個就是攔截器的作用,判斷是否已經登錄成功,區(qū)別訪問的路徑,細節(jié)就在接口的三個方法中; 適用場景:登錄,鑒權,靜態(tài)資源訪問等 我們就以登錄舉例子,如果說用戶要訪問個人信息,驗證當前是否已經登錄,可以是 token 是否合法然后沒有就要攔截器到未登錄的頁面,開始登錄操作;
package com.atspring.config;
import com.atspring.intercepter.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 配置web請求中的設置
*/
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
/**
* 1.編寫一個攔截器,注冊到容器中,addInterceptors
* 2.指定攔截規(guī)則,如果攔截所有,所有資源包括靜態(tài)資源都會被攔截
* @param registry
*/
//webconfig中的增加攔截器的方法,只需要重寫就可以
@Override
public void addInterceptors(InterceptorRegistry registry) {
// LoginInterceptor loginInterceptor=new LoginInterceptor();
// registry.addInterceptor(loginInterceptor);
registry.addInterceptor(new LoginInterceptor())
//添加攔截器攔截的路徑,/**全部放行,但在實際項目中可能是域名 /lucas/**
.addPathPatterns("/**")
//放行靜態(tài)資源,以及登錄
.excludePathPatterns("/login","/css/**","/image/**","/js/**");
}
}配置攔截器:
package com.atspring.intercepter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 登錄檢查
* 1.配置攔截器攔截哪些請求,
* 2.把配置放在容器中Aop
*/
public class LoginInterceptor implements HandlerInterceptor {
/**
* 處理方法之前,資源請求,
* 檢查等
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登錄檢查,這里就利用session簡單的存儲了
HttpSession session=request.getSession();
Object loginUser = session.getAttribute("loginUser");
if (loginUser!=null){
//放行
return true;
}
//攔截成功
request.setAttribute("message","請先登錄");
//轉發(fā)到登錄頁面去登錄,并且返回
request.getRequestDispatcher("/login").forward(request,response);
return false;
}
/**
* 處理方法之后,未返回頁面之前
* 對于數據處理
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* 請求執(zhí)行完成之后,
* 對資源的關閉等
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}攔截器原理
- 根據當前請求,找到 HandlerExecutionChain【可以處理請求的 handler 以及 handler 的所有 攔截器】
- 先來順序執(zhí)行 所有攔截器的 preHandle 方法
- 如果當前攔截器 prehandler 返回為 true。則執(zhí)行下一個攔截器的 preHandle
- 如果當前攔截器返回為 false。直接 倒序執(zhí)行所有已經執(zhí)行了的攔截器的 afterCompletion;
- 如果任何一個攔截器返回 false。直接跳出不執(zhí)行目標方法
- 所有攔截器都返回 True。執(zhí)行目標方法
- 倒序執(zhí)行所有攔截器的 postHandle 方法。
- 前面的步驟有任何異常都會直接倒序觸發(fā) afterCompletion
- 頁面成功渲染完成以后,也會倒序觸發(fā) afterCompletion

Sprinboot添加自定義攔截器后視圖解析失敗問題
我在使用Springboot2.0通過重載WebMvcConfigurationSupport和使用注解@Configuration的方法添加自定義攔截器后會出現一個bug,就是我們在application.properties配置的視圖解析失效 我在application.properties的配置如下:
server.port=8086 server.servlet.context-path=/ spring.mvc.view.prefix=/views/ spring.mvc.view.suffix=.jsp
我的InterceptorConfig 代碼如下:
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
@Autowired
private LoginHandlerInterceptor loginHandlerInterceptor;
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
super.addViewControllers(registry);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 判斷用戶是否登錄的攔截器
registry.addInterceptor(loginHandlerInterceptor).addPathPatterns("/*/*");
super.addInterceptors(registry);
}
}我推測應當是WebMvcConfigurationSupport 中創(chuàng)建了新的視圖解析器,既然如此,我就直接自定義一個ViewResolver 放到WebMvcConfigurationSupport中,問題得到解決。
private static final String VIEW_PREFIX = "/views/";// 視圖前綴
private static final String VIEW_SUFFIX = ".jsp";// 視圖后綴
private static final String VIEW_CONTENT_TYPE = "text/html;charset=UTF-8";//視圖的內容類型。
/**
* 配置 視圖解析器
* @return
*/
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setCache(true);
resolver.setPrefix(VIEW_PREFIX);
resolver.setSuffix(VIEW_SUFFIX);
resolver.setExposeContextBeansAsAttributes(true);
resolver.setContentType(VIEW_CONTENT_TYPE);
return resolver;
}到此這篇關于Springboot中的自定義攔截器及原理詳解的文章就介紹到這了,更多相關Springboot自定義攔截器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解決IDEA提示:MVC DispatcherServlet servlet contex
在SSM整合配置Spring時出現錯誤,需刪除多余配置文件并重新導入,若屬性解析失敗,清除緩存重啟IDEA,個人經驗,供參考2025-08-08
淺談一下RabbitMQ、Kafka和RocketMQ消息中間件對比
這篇文章主要介紹了淺談一下RabbitMQ、Kafka和RocketMQ消息中間件對比,消息中間件屬于分布式系統中一個字系統,關注于數據的發(fā)送和接收,利用高效可靠的異步信息傳遞機制對分布式系統中的其余各個子系統進行集成,需要的朋友可以參考下2023-05-05

