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

Sprinboot添加自定義攔截器后視圖解析失敗問(wèn)題
我在使用Springboot2.0通過(guò)重載WebMvcConfigurationSupport和使用注解@Configuration的方法添加自定義攔截器后會(huì)出現(xiàn)一個(gè)bug,就是我們?cè)赼pplication.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);
}
}我推測(cè)應(yīng)當(dāng)是WebMvcConfigurationSupport 中創(chuàng)建了新的視圖解析器,既然如此,我就直接自定義一個(gè)ViewResolver 放到WebMvcConfigurationSupport中,問(wèn)題得到解決。
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";//視圖的內(nèi)容類型。
/**
* 配置 視圖解析器
* @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;
}到此這篇關(guān)于Springboot中的自定義攔截器及原理詳解的文章就介紹到這了,更多相關(guān)Springboot自定義攔截器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決IDEA提示:MVC DispatcherServlet servlet contex
在SSM整合配置Spring時(shí)出現(xiàn)錯(cuò)誤,需刪除多余配置文件并重新導(dǎo)入,若屬性解析失敗,清除緩存重啟IDEA,個(gè)人經(jīng)驗(yàn),供參考2025-08-08
Java利用Socket類實(shí)現(xiàn)TCP通信程序
TCP通信能實(shí)現(xiàn)兩臺(tái)計(jì)算機(jī)之間的數(shù)據(jù)交互,通信的兩端,要嚴(yán)格區(qū)分為客戶端與服務(wù)端,下面我們就來(lái)看看Java如何利用Socket類實(shí)現(xiàn)TCP通信程序吧2024-02-02
SpringMVC 數(shù)據(jù)校驗(yàn)方法(必看篇)
下面小編就為大家?guī)?lái)一篇SpringMVC 數(shù)據(jù)校驗(yàn)方法(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
淺談一下RabbitMQ、Kafka和RocketMQ消息中間件對(duì)比
這篇文章主要介紹了淺談一下RabbitMQ、Kafka和RocketMQ消息中間件對(duì)比,消息中間件屬于分布式系統(tǒng)中一個(gè)字系統(tǒng),關(guān)注于數(shù)據(jù)的發(fā)送和接收,利用高效可靠的異步信息傳遞機(jī)制對(duì)分布式系統(tǒng)中的其余各個(gè)子系統(tǒng)進(jìn)行集成,需要的朋友可以參考下2023-05-05

