package net.bocan.springboot.config;
import net.bocan.springboot.intecpter.LoginIntercepter;
import net.bocan.springboot.intecpter.RoleIntercepter;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* web mvc 配置類
*/
@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//需要攔截的請求 第一個斜杆後面星號代表目錄 第二個斜杆後面 代表具體方法 這樣寫可以攔截 所有跟api相關的請求
registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/*/**")
.excludePathPatterns("/login/login_out"); //被排除的請求
// 還可以配置多個攔截器
registry.addInterceptor(new RoleIntercepter()).addPathPatterns("/api/*/**")
.excludePathPatterns("/home");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
package net.bocan.springboot.intecpter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 登錄攔截器
*/
public class LoginIntercepter implements HandlerInterceptor {
/**
* 在請求發出後 ---進入具體方法之前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("LoginIntercepter------->preHandle");
//System.out.println("調用的uri: " + request.getRequestURI());
// System.out.println("調用的url: " + request.getRequestURL());
//通常用於檢測權限 拿token ,驗證是否有登錄過 或者已登錄過 協同緩存一起使用
//String username = request.getParameter("username");
//String accessToken = request.getHeader("access_token");
// .... 具體業務邏輯
//if(...) 如果不符合條件 就不放行
//response.getWriter().print("fail");
//測試多個攔截器的調用流程
String username = request.getParameter("username");
System.out.println(username);
if(!"parker".equals(username)){ //攔截器只調用了 LoginIntercepter的 preHandle方法
//響應一個提示信息 返回給客戶端
response.getWriter().print("fail");
return false;
}
//代表放行 return true;
return HandlerInterceptor.super.preHandle(request,response,handler);
}
/**
* 調用方法後,方法走完 渲染視圖前
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("LoginIntercepter ----- postHandle");
HandlerInterceptor.super.postHandle(request,response,handler,modelAndView);
}
/**
* 整個請求走完 (用於資源整理)
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("LoginIntercepter ----- afterCompletion");
}
}
package net.bocan.springboot.intecpter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
* 角色 攔截器 測試 多個攔截器的效果
*/
public class RoleIntercepter implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("roleIntercepter ------ preHandle");
//測試多個攔截器的調用流程
String role = request.getParameter("role");
// System.out.println(username);
if(Objects.isNull(role)){
//攔截
response.getWriter().print("fail");
return false;
}
return HandlerInterceptor.super.preHandle(request,response,handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("roleIntercepter ------ postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("roleIntercepter ------ afterCompletion");
}
}
package net.bocan.springboot.controller;
import net.bocan.springboot.common.JsonData;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(value = "/api")
public class LoginController {
/**
* 結果
* LoginIntercepter------->preHandle
* parker
* roleIntercepter ------ preHandle
* 進入登錄方法 -----
* 用戶名:parker 密碼:123456
* roleIntercepter ------ postHandle
* LoginIntercepter ----- postHandle
* roleIntercepter ------ afterCompletion
* LoginIntercepter ----- afterCompletion
* @param username
* @param password
* @param rememberMe
* @return
*/
@PostMapping(value = "/user/login")
@ResponseBody
public JsonData login(String username,String password,Boolean rememberMe){
JsonData jsonData = new JsonData();
System.out.println("進入登錄方法 -----");
System.out.println("用戶名:"+username+" 密碼:"+password);
jsonData.put("username",username);
jsonData.put("password",password);
jsonData.put("rememberMe",rememberMe);
jsonData.success();
return jsonData;
}
}
//如果一切正常
//輸出結果是 如下
LoginIntercepter------->preHandle
parker
roleIntercepter ------ preHandle
進入登錄方法 -----
用戶名:parker 密碼:123456
roleIntercepter ------ postHandle
LoginIntercepter ----- postHandle
roleIntercepter ------ afterCompletion
LoginIntercepter ----- afterCompletion
調用順序 從上到下
LoginIntercepter (preHandle) 方法
| ( return true 繼續往下走 ) / false 直接 返回
RoleIntercepter ------ (preHandle) 方法
| (return true 繼續往下走 進入具體方法) / false 調用 LoginIntercepter ----- (afterCompletion方法) 在返回
具體的 Method 業務代碼
|
RoleIntercepter ------ postHandle(方法)
|
LoginIntercepter ----- postHandle (方法)
|
RoleIntercepter ------ afterCompletion (方法) (通常用於清理資源)
|
LoginIntercepter ----- afterCompletion(方法) (通常用於清理資源)
像漢堡包 對稱
皮 --- 》 生菜 --》 沙拉 --》雞肉片(具體方法) --》沙拉 ---》 生菜 ---》皮
高速收費站 (假設來去都走一條路線)
車 --》收費站1 ----》 收費站2 -- 目的地 ---》收費站2 ---》收費站1