引言
在做后台管理系統時,要進入功能頁需要判斷一下用戶是否登錄,此時就體現出攔截器的作用了。
springBoot實現攔截器主要有三步:
- 編寫一個攔截器實現HandlerInterceptor接口,並實現preHandle攔截方法
- 將攔截器注冊到容器中(實現WebMvcConfigurer接口,並重寫addInterceptors方法)
- 編寫攔截器規則【注意靜態資源的攔截】
內容
編寫一個web項目,訪問/main路徑時候,要判斷是否登錄,登錄即可進入,否則跳回登錄頁面並給予提示。
攔截器:
package com.xiao.boot.interceptor;
import com.xiao.boot.bean.User.User;
import org.omg.PortableInterceptor.Interceptor;
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;
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 {
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
if (user == null){
// 攔截
request.setAttribute("msg","請先登錄");
request.getRequestDispatcher("/").forward(request,response);
return false;
}
// 放行
return true;
}
/**
* 目標方法執行后
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 頁面渲染以后
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
配置攔截器。注意要將靜態資源放行
package com.xiao.boot.config;
import com.xiao.boot.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//標明配置類
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
// 添加攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") //攔截所有,包括靜態資源
.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); //放行
}
}
登錄的controller
package com.xiao.boot.controller;
import com.sun.org.apache.xpath.internal.operations.Mod;
import com.xiao.boot.bean.User.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpSession;
@Controller
public class UserController {
@GetMapping(value = {"/","/login"})
public String loginPage(){
return "login";
}
@PostMapping(value = "/login")
public String main(User user, HttpSession session,Model model){
if (!StringUtils.isEmpty(user.getUserName()) && user.getPassword().equals("123456")){
session.setAttribute("user",user);
return "redirect:/main.html";
}else {
model.addAttribute("msg","賬號或密碼錯誤");
return "login";
}
}
@GetMapping(value = "/main.html")
public String mainPage(HttpSession session, Model model){
return "main";
}
}
結果
首先進入登錄頁面

直接訪問main,被攔截,並且提示登錄

輸入賬號和密碼進行登錄

攔截器原理
- 根據當前請求,找到HandlerExecutionChain【可以處理請求的handler以及handler的所有 攔截器】
- 先來順序執行 所有攔截器的preHandle方法
- 如果當前攔截器prehandler返回為true。則執行下一個攔截器的preHandle
- 如果當前攔截器返回為false。直接倒序執行所有已經執行了的攔截器的afterCompletion;
- 如果任何一個攔截器返回false。直接跳出不執行目標方法
- 所有攔截器都返回True。執行目標方法
- 倒序執行所有攔截器的postHandle方法。
- 前面的步驟有任何異常都會直接倒序觸發 afterCompletion
- 頁面成功渲染完成以后,也會倒序觸發 afterCompletion
