說明
分佈式環境下的session共享&自定義註解&攔截器,實現接口的動態登入攔截
1.相關maven依賴
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- spring session + redis --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
2)配置yml
spring
session:
store-type: redis #session交由redis保存
redis:
host: localhost
賬號&密碼
port: 6379
timeout: 3000
usePool: true
pool:
max-idle: 50
maxTotal: 100
database: 2
3)配置類
一.項目啓動類:
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = session的存活時間/秒)
@Bean//添加 public static ConfigureRedisAction configureRedisAction() { return ConfigureRedisAction.NO_OP; }
二.註冊攔截器
@Configuration public class WebConfigurer implements WebMvcConfigurer {
/** * 註冊攔截器 * * * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { //registry.addInterceptor(loggedInInterceptor).addPathPatterns("/**").excludePathPatterns("/login.ctrl");//添加請求路徑攔截,以及不包含的路徑(不攔截) //在註冊時不指定攔截路徑,通過攔截器中判斷是否函數帶有isLogin(自定義)的註解來攔截 registry.addInterceptor(loggedInInterceptor); } }
4)自定義註解與攔截器
/** * 自定義註解:接口攔截註解,配置在需要登入後訪問的controller層函數上 * */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface isLogin{ }
/**
* 攔截器
*/
@Component
public class LoggedInInterceptor implements HandlerInterceptor {
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 校驗session緩存用戶信息
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
IsLoggedin isLoggedin = handlerMethod.getMethodAnnotation(IsLoggedin.class);
if (isLoggedin == null) {// 函數上是否攜帶@isLogin 自定義註解,沒有則不攔截
return true;
}
Boolean result_status = false;
User user;
if (request.getSession().getAttribute("userInfo") != null) {
user = (User) request.getSession().getAttribute("userInfo");
if (user != null) {
result_status = true;
}
}
if (!result_status) {
if (request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
response.setStatus(444);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().print("{\"error\":\"未登錄,請先登錄。\"}");
response.flushBuffer();
}
else {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().print("{\"errorCode\":444}");
response.flushBuffer();
}
}
return result_status;
}
}
測試
1.登入接口成功後,將用戶信息放入session;
request.getSession().setAttribute("userInfo", userInfo);
2.在接口聲明時配置註解isLogin
@isLogin @RequestMapping(value = "/test.ctrl", method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public Map<String, Object> test(@RequestBody Map<String, Object> params) { // ... }