springboot自定義攔截器的方法
攔截器應(yīng)該分屬于web框架的組件,每個(gè)框架提供的自己的支持,實(shí)現(xiàn)方式也就不同。例如Struts和Spring,以下是Spring 的攔截器總結(jié),它是基于動(dòng)態(tài)代理(反射)實(shí)現(xiàn)的。
Spring 中聲明攔截器需要實(shí)現(xiàn) HandlerInterceptor 接口,當(dāng)然也可以通過(guò)繼承HandlerInterceptorAdapter 抽象類,HandlerInterceptorAdapter也是實(shí)現(xiàn)了HandlerInterceptor 接口。
攔截器中有四個(gè)方法:
preHandle:在Controller中的方法之前執(zhí)行,決定是否放行,return true表示放行。一旦放行其對(duì)應(yīng)的afterCompletion就一定會(huì)執(zhí)行。
postHandle:Controller中的方法處理完之后,DispatcherServlet進(jìn)行視圖的渲染之前,也就是說(shuō)在這個(gè)方法中你可以對(duì)ModelAndView進(jìn)行操作
afterCompletion:DispatcherServlet進(jìn)行視圖的渲染之后
afterConcurrentHandlingStarted:與異步相關(guān)
下面通過(guò)代碼實(shí)踐,備注了是否放行和異常對(duì)攔截器內(nèi)方法執(zhí)行的影響結(jié)論。其實(shí)只需對(duì)方法執(zhí)行的時(shí)機(jī)進(jìn)行分析,我們就可以得出相同的結(jié)論。
如果想深入了解每個(gè)方法的執(zhí)行時(shí)機(jī),可以閱讀SpringMVC的 DispatcherServlet 源碼
@Component
public class InterceptorTwo extends HandlerInterceptorAdapter {
?
? ? /**
? ? * handler 對(duì)應(yīng)@RequestMapping對(duì)應(yīng)的controller對(duì)象
? ? */
? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
? ? ? ? //這里我們是沒(méi)辦法拿到方法參數(shù)的,parameters是空的,但是可以拿到controller種注入的bean
? ? ? ? //可以斷點(diǎn)驗(yàn)證
? ? ? ? HandlerMethod handlerMethod = (HandlerMethod)handler;
? ? ? ? MethodParameter [] parameters = handlerMethod.getMethodParameters();
? ? ? ? return true;//放行
? ? }
?
? ? @Override
? ? public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
? ? ? ? //在攔截器鏈中,只要有一個(gè)不放行的,所有的postHandle都不會(huì)執(zhí)行
? ? ? ? //如果Controller方法拋異常了,所有的postHandle也不會(huì)執(zhí)行
? ? ? ? System.out.println("postHandle");
? ? }
?
? ? @Override
? ? public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
? ? ? ? //只要對(duì)應(yīng)的preHandle放行了就一定會(huì)執(zhí)行,Controller方法拋異常也不會(huì)影響
? ? ? ? System.out.println("afterCompletion");
? ? }
?
? ? @Override
? ? public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
? ? ? ? System.out.println("afterConcurrentHandlingStarted");
? ? }
}使攔截器生效
//Springboot 是1.x版本的項(xiàng)目中是extends WebMvcConfigurerAdapter ,代碼也是一樣的
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
?
? ? @Autowired
? ? private SourceAccessInterceptor interceptor;
? ? @Autowired
? ? private InterceptorOne interceptorOne;
? ? @Override
? ? public void addInterceptors(InterceptorRegistry interceptorRegistry) {
? ? ? ? //1.加入的順序就是攔截器執(zhí)行的順序,設(shè)置@Order也不會(huì)影響
? ? ? ? //2.按順序執(zhí)行所有攔截器的preHandle
? ? ? ? //3.所有的preHandle 執(zhí)行完再反向執(zhí)行全部postHandle 最后是反向執(zhí)行afterCompletion,
? ? ? ? //如果其中有一個(gè)未放行,或者拋異常了會(huì)影響執(zhí)行順序嗎?怎樣影響
? ? ? ? interceptorRegistry.addInterceptor(interceptor).addPathPatterns("/**");
? ? ? ? interceptorRegistry.addInterceptor(interceptorOne);
? ? }
}應(yīng)用示例
這個(gè)攔截器是用來(lái)攔截請(qǐng)求是否有攜帶token的,如果請(qǐng)求未攜帶token,將會(huì)302重定向到登錄界面。
@Component
public class AuthInterceptor extends HandlerInterceptorAdapter {?
??
? ? @Autowired
? ? private JwtUtil jwtUtil;
?
? ? @Value("${login.url}")
? ? private String loginUrl;
?
? ? /**
? ? ?* 驗(yàn)證access_token
? ? ?*
? ? ?* @param request ?請(qǐng)求
? ? ?* @param response 響應(yīng)
? ? ?* @param handler ?處理器controller
? ? ?*/
? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
?
? ? ? ? HandlerMethod handlerMethod = (HandlerMethod) handler;
? ? ? ? //WithoutToken是我自定義的注解,標(biāo)注在方法上,表示不需要驗(yàn)證token
? ? ? ? if (handlerMethod.getMethod().isAnnotationPresent(WithoutToken.class)) {
? ? ? ? ? ? //不需要驗(yàn)證token
? ? ? ? ? ? return true;
? ? ? ? } else {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? //校驗(yàn)jwt
? ? ? ? ? ? ? ? String access_token = request.getHeader("access_token");
? ? ? ? ? ? ? ? jwtUtil.verifierToken(access_token);
? ? ? ? ? ? ? ? //獲取用戶信息
? ? ? ? ? ? ? ? final String account = jwtUtil.getAccount(access_token);
? ? ? ? ? ? ? ? //TODO 可以在這里查詢用戶信息,然后將用戶信息設(shè)置到線程變量
? ? ? ? ? ? ? ??
? ? ? ? ? ? } catch (NullPointerException | JWTVerificationException e) {
? ? ? ? ? ? ? ? //TODO 重定向到登陸頁(yè)
? ? ? ? ? ? ? ? response.sendRedirect(loginUrl);
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? return true;
?
? ? ? ? }
? ? }
}以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解決阿里代碼規(guī)范檢測(cè)中方法缺少javadoc注釋的問(wèn)題
這篇文章主要介紹了解決阿里代碼規(guī)范檢測(cè)中方法缺少javadoc注釋的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
如何在Spring?Boot中使用MyBatis訪問(wèn)數(shù)據(jù)庫(kù)
MyBatis可以通過(guò)簡(jiǎn)單的XML或者注解來(lái)配置和映射原始類型,接口,和Java POJO為數(shù)據(jù)庫(kù)中記錄,使用MyBatis幫助我們解決各種問(wèn)題,本文介紹如何在Spring?Boot中使用MyBatis訪問(wèn)數(shù)據(jù)庫(kù),感興趣的朋友一起看看吧2023-11-11
SpringSecurity+JWT實(shí)現(xiàn)登錄流程分析
Spring Security 是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問(wèn)控制框架,它是為Java應(yīng)用程序設(shè)計(jì)的,特別是那些基于Spring的應(yīng)用程序,下面給大家介紹SpringSecurity+JWT實(shí)現(xiàn)登錄流程,感興趣的朋友一起看看吧2024-12-12
Java socket通訊實(shí)現(xiàn)過(guò)程及問(wèn)題解決
這篇文章主要介紹了Java socket通訊實(shí)現(xiàn)過(guò)程及問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
springboot項(xiàng)目啟動(dòng)自動(dòng)跳轉(zhuǎn)到瀏覽器的操作代碼
這篇文章主要介紹了springboot項(xiàng)目啟動(dòng)自動(dòng)跳轉(zhuǎn)到瀏覽器的操作代碼,本文圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-03-03
Springboot Thymeleaf實(shí)現(xiàn)HTML屬性設(shè)置
這篇文章主要介紹了Springboot Thymeleaf實(shí)現(xiàn)HTML屬性設(shè)置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2007-11-11
springboot 設(shè)置局域網(wǎng)訪問(wèn)的實(shí)現(xiàn)步驟
Spring Boot是一個(gè)開(kāi)源Java-based框架,用于創(chuàng)建獨(dú)立的、生產(chǎn)級(jí)別的Spring應(yīng)用,它旨在簡(jiǎn)化Spring應(yīng)用的初始搭建及開(kāi)發(fā)過(guò)程,通過(guò)提供各種自動(dòng)配置的starter包,Spring Boot使得項(xiàng)目配置變得簡(jiǎn)單快速,感興趣的朋友一起看看吧2024-02-02
SpringBoot從0到1整合銀聯(lián)無(wú)跳轉(zhuǎn)支付功能附源碼
這篇文章主要介紹了SpringBoot從0到1整合銀聯(lián)無(wú)跳轉(zhuǎn)功能支付附源碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11

