Web開發中,我們除了使用 Filter 來過濾請web求外,還可以使用Spring提供的HandlerInterceptor(攔截器)。
HandlerInterceptor 的功能跟過濾器類似,但是提供更精細的的控制能力:在request被響應之前、request被響應之后、視圖渲染之前以及request全部結束之后。我們不能通過攔截器修改request內容,但是可以通過拋出異常(或者返回false)來暫停request的執行。
實現 UserRoleAuthorizationInterceptor 的攔截器有:
ConversionServiceExposingInterceptor
CorsInterceptor
LocaleChangeInterceptor
PathExposingHandlerInterceptor
ResourceUrlProviderExposingInterceptor
ThemeChangeInterceptor
UriTemplateVariablesHandlerInterceptor
UserRoleAuthorizationInterceptor
其中 LocaleChangeInterceptor 和 ThemeChangeInterceptor 比較常用。
配置攔截器也很簡單,Spring 為什么提供了基礎類WebMvcConfigurerAdapter ,我們只需要重寫 addInterceptors 方法添加注冊攔截器。
實現自定義攔截器只需要3步:
1、創建我們自己的攔截器類並實現 HandlerInterceptor 接口。
2、創建一個Java類繼承WebMvcConfigurerAdapter,並重寫 addInterceptors 方法。
2、實例化我們自定義的攔截器,然后將對像手動添加到攔截器鏈中(在addInterceptors方法中添加)。
PS:本文重點在如何在Spring-Boot中使用攔截器,關於攔截器的原理請大家查閱資料了解。
代碼示例:
package com.kfit.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; /** * 自定義攔截器1 * * @author Angel */ publicclass MyInterceptor1 implements HandlerInterceptor { @Override publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(">>>MyInterceptor1>>>>>>>在請求處理之前進行調用(Controller方法調用之前)"); returntrue;// 只有返回true才會繼續向下執行,返回false取消當前請求 } @Override publicvoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println(">>>MyInterceptor1>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)"); } @Override publicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println(">>>MyInterceptor1>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)"); } }
com.kfit.interceptor.MyInterceptor2.java
package com.kfit.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; /** * 自定義攔截器2 * * */ public class MyInterceptor2 implements HandlerInterceptor { @Override publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(">>>MyInterceptor2>>>>>>>在請求處理之前進行調用(Controller方法調用之前)"); returntrue;// 只有返回true才會繼續向下執行,返回false取消當前請求 } @Override publicvoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println(">>>MyInterceptor2>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)"); } @Override publicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println(">>>MyInterceptor2>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)"); } }
Com.kfit.config.MyWebAppConfigurer.java
package com.kfit.config; import com.kfit.interceptor.MyInterceptor1; import com.kfit.interceptor.MyInterceptor2; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class MyWebAppConfigurer extends WebMvcConfigurerAdapter { @Override publicvoid addInterceptors(InterceptorRegistry registry) { // 多個攔截器組成一個攔截器鏈 // addPathPatterns 用於添加攔截規則 // excludePathPatterns 用戶排除攔截 registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**"); registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**"); super.addInterceptors(registry); } }
然后在瀏覽器輸入地址: http://localhost:8080/index 后,控制台的輸出為:
>>>MyInterceptor1>>>>>>>在請求處理之前進行調用(Controller方法調用之前)
>>>MyInterceptor2>>>>>>>在請求處理之前進行調用(Controller方法調用之前)
>>>MyInterceptor2>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)
>>>MyInterceptor1>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)
>>>MyInterceptor2>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)
>>>MyInterceptor1>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)
---------------------
HandlerInterceptor攔截登陸的實現
@Component public class MyHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String name= (String) request.getSession().getAttribute("LoginName"); if (!name.isEmpty()){ request.getRequestDispatcher("/main.html").forward(request,response); return false; }else { request.getRequestDispatcher("/login.html").forward(request, response); return true; } } }
實現攔截方法從而判斷使否含有Session值 該方法在請求之前執行
@Controller public class HelloController { @RequestMapping("login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, HttpSession session){ if (username.equals("123")&password.equals("123")){ session.setAttribute("LoginName",username); return "redirect:main"; }else{ return "login"; } } --------------------- 作者:小灬羅 來源:CSDN 原文:https://blog.csdn.net/luojingwei1997/article/details/80554672 版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
