springboot+redis+session相同用户只能登陆一次,前者会被挤下线(类似QQ)
程序员文章站
2022-04-03 09:54:01
1.springbootWeb项目引包 org.springframework.boot spring-boot-starter-data-redis ....
1.springbootWeb项目
- 引包
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- .yml文件配置redis信息
#redis配置信息
spring:
redis:
host: 127.0.0.1
port: 6379
password: 123456
jedis:
pool:
max-active: 8
max-idle: 500
max-wait: -1
min-idle: 0
lettuce:
shutdown-timeout: 0
2.项目登录接口
@Autowired
private RedisTemplate<String,String> redisTemplate;
@ApiOperation(value = "登录")
@PostMapping(value = "/login")
public RestResult<DatagoUser> login(@RequestBody DatagoUser datagoUser, HttpServletRequest request) {
String kl = MD5andKL.KL(datagoUser.getPassword());
datagoUser.setPassword(kl);
datagoUser = datagoUserService.login(datagoUser);
if (datagoUser != null) {
if (datagoUser.getStatus().equals(true)) {
DatagoRole datagoRole = roleService.selectByRole(datagoUser.getRoleId());
datagoUser.setType(datagoRole.getType());
datagoUser.setLastLoginTime(new Date());
datagoUser.setLastLoginIp(UserContext.getIp2());
datagoUser.setSessionId(request.getRequestedSessionId());
datagoUserService.updateByPrimaryKeySelective(datagoUser);
// UserContext.setUser(datagoUser);
//主要核心代码
request.getSession().setAttribute("user",datagoUser.getId());
redisTemplate.opsForValue().set(datagoUser.getId(),request.getSession().getId());
return RestResultUtil.genSuccessResult(datagoUser);
} else {
return RestResultUtil.failed("用户被禁用,请联系管理员!!!");
}
} else {
return RestResultUtil.failed("用户密码异常,请重新输入!!!");
}
}
3.拦截器(2个类)
package com.datago.robot.common.interceptor;
import com.datago.robot.common.utils.RestResult;
import com.datago.robot.common.utils.Utils;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* @author HB
*/
@Component
@Slf4j
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 1.在调用控制器方法前,拦截
* <p>
* 返回值为false,代表拦截
* 返回值为true,代表放行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("---------------------开始进入请求地址拦截----------------------------");
//注释掉为了swagger-ui接口测试可以正常使用
// DatagoUser user = (DatagoUser) UserContext.getSession().getAttribute("user");
String user = (String) request.getSession().getAttribute("user");
RestResult restResult = new RestResult();
if (Utils.isNotEmpty(user)) {
//检测redis中是否含有sessionId
String loginSessionId = redisTemplate.opsForValue().get(request.getSession().getAttribute("user"));
if (loginSessionId != null && loginSessionId.equals(request.getSession().getId())) {
return true;
} else {
restResult.setMessage("该账号在另一台设备上登录,您被强制下线,请您重新登陆!!!");
}
} else {
restResult.setMessage("请您先进行登录");
}
restResult.setCode(-2);
response.setCharacterEncoding("utf-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write(JSONObject.fromObject(restResult).toString());
return false;
}
/**
* 2.在调用控制器方法后,拦截(在生成视图之前)
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.info("=============进入拦截器了,请求处理后,渲染ModelAndView前调用。=================================");
// TODO Auto-generated method stub
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* 3.在视图生成之后(后台所有所有逻辑都完成后)
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("=============进入拦截器了,渲染ModelAndView后调用。=================================");
// TODO Auto-generated method stub
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
package com.datago.robot.common.interceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* @ProjectName powerFind
* @Package com.datago.robot.common.config
* @Name WebConfigurer
* @Author HB
* @Date 2021/2/18 10:20
* @Version 1.0
*/
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Autowired
LoginHandlerInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// TODO Auto-generated method stub
// addPathPatterns("/**") 表示拦截所有的请求,
// excludePathPatterns("/login", "/register") 表示除了登陆与注册之外,因为登陆注册不需要登陆也可以访问
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/",
//登录接口
"/datagoUser/login",
//导出报名人员excel文件接口
"/file/**",
//展示活动照片接口
"/activityImage/**",
"/activity/getIsActivityCount",
"/activity/getActivityCount",
"/image/imageFileSave",
"/activity/importShowTemplate",
"/activity/templatePersonDownload",
"/honor/importShowTemplate",
"/honor/templatePersonDownload"
);
}
}
4.写的有点。。。,欢迎留言一同探讨学习。
5.要想拿来自己用必须要修改业务逻辑代码,方可使用;楼主比较懒,就直接拷贝来了,不喜么怪。。。。
6.最后再共享下,redis资源(也可在博主资源下载中进行下载)
- 博主CSDN资源
https://download.csdn.net/download/sinat_37239798/15542982
- 博主百度网盘资源
链接:https://pan.baidu.com/s/1Uh6fsriyGpb8xDwx94ew7g
提取码:1234
复制这段内容后打开百度网盘手机App,操作更方便哦
本文地址:https://blog.csdn.net/sinat_37239798/article/details/114304314
上一篇: 【数算-26】平衡二叉树【AVL】