在上一篇中Redis实战之session共享,我们知道了通过Redis实现session共享了,那么token怎么续命呢?怎么刷新用户呢?本来咱们就通过拦截器来实现这两个功能。
登录拦截器优化:
先来看看现在拦截器情况:
拦截流程:
当拦截器拦截需要拦截到的url时候,才会在拦截器中更新用户token的过期时间。那如果,访问了不被拦截的路径,就不会给token续命的。这样就会导致用户token过期,而重新登录的。这样是不对的。
拦截了哪些路径?在config/MvcConfig中
当访问以上这些路径的是,就不会自动更新用户的token过期时间了。
优化:我们可以在现有拦截器签名价格拦截器:
将获取用户,存放threadLocal及刷新token放到新的拦截器中。
第一个拦截器就叫做:刷新token拦截器;第二个拦截器就叫做:用户拦截器
创建刷新token的拦截器:
import cn.hutool.core.bean.BeanUtil; import com.hmdp.dto.UserDTO; import com.hmdp.utils.UserHolder; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; import java.util.concurrent.TimeUnit; import static com.hmdp.constants.RedisConstants.LOGIN_USER_TOKEN_KEY; import static com.hmdp.constants.RedisConstants.LOGIN_USER_TOKEN_TTL; /** * @author 凯哥Java * @description 刷新用户token的烂机器 * @company */ public class RefreshTokenInterceptor implements HandlerInterceptor { private StringRedisTemplate stringRedisTemplate; /** * 因为这个类不能被spring管理,所以不能直接注入RedisTemplate对象。通过构造函数传递 * * @param stringRedisTemplate */ public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) { this.stringRedisTemplate = stringRedisTemplate; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //1:从请求中获取到token String token = request.getHeader("authorization"); if (StringUtils.isEmpty(token)) { return true; } //2:基于token获取redis中用户对象 String key = LOGIN_USER_TOKEN_KEY + token; Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key); //3:判断 if (userMap.isEmpty()) { return true; } //将map转对象 UserDTO user = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false); UserHolder.saveUser(user); //刷新token的过期时间 stringRedisTemplate.expire(key, LOGIN_USER_TOKEN_TTL, TimeUnit.MINUTES); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { UserHolder.removeUser(); } }
修改用户拦截器:
import com.hmdp.utils.UserHolder; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author 凯哥Java * @description 登录拦击器 * @company */ public class UserInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //判断是否需要拦截 if (UserHolder.getUser() == null) { response.setStatus(401); return false; } return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { UserHolder.removeUser(); } }
修改MvcCofig。将两个拦截器添加进去,并设置拦截顺序:
import com.hmdp.interceptor.RefreshTokenInterceptor; import com.hmdp.interceptor.UserInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.annotation.Resource; /** * @author 凯哥Java * @description mvn的配置-添加拦截器 * @company */ @Configuration public class MvcConfig implements WebMvcConfigurer { @Resource private StringRedisTemplate stringRedisTemplate; @Override public void addInterceptors(InterceptorRegistry registry) { //登录拦截器 registry.addInterceptor(new UserInterceptor()) .excludePathPatterns( "/shop/**", "/voucher/**", "/shop-type/**", "/upload/**", "/blog/hot", "/user/code", "/user/login" ).order(1); //刷新token拦截器 registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0); } }
相关推荐
redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-...
tomcat-redis-session-manager-2.0.0.jar jedis-2.5.2.jar commons-pool2-2.2.jar 2.修改 conf 目录下的 context.xml 文件 host="localhost" port="6379" database="0" maxInactiveInterval="60" /> ...
session 共享 tomcat-redis-session-manager 所需要的jar 和 redis-data-cache.properties文件 (绝对可用) 已经完整测试
tomcat-redis-session-manager-1.2-tomcat-7.jar 和tomcat的context.xml配置文件。 2.7.2版包含 commons-pool2-2.4.1.jar jedis-2.7.2.jar tomcat-redis-session.jar 和tomcat的context.xml配置文件
Tomcat8亲测可用 tomcat-redis-session-manager的jar包 修改了tomcat-redis-session-manager源码进行的编译生成的jar包
apache-tomcat-8.0.14_8081/apache-tomcat-8.0.14_8082为两个tomcat 服务器,修改目录中context.xml中redis连接地址和密码,直接可以在本地运行tomcat-->start.bat,直接访问...
压缩文件包括tomcat-redis-session-manager-master-2.0.0.jar、jedis-2.7.3.jar、commons-pool2-2.3.jar三个jar包使用方法请参照https://github.com/jcoleman/tomcat-redis-session-manager。apache-tomcat-8.5.33....
tomcat-redis-session-manager-2.0.0.jar
所需的tomcat-redis-session-manager所有的jar包下载。测试环境JDK1.8,Tomact8
用于配置 tomcat-redis-session-manager
使用tomcat-redis-session-manager进行统一session管理所需jar包,包括tomcat6-jdk6、tomcat7-jdk7、tomcat8-jdk8
赠送jar包:spring-session-data-redis-2.0.4.RELEASE.jar; 赠送原API文档:spring-session-data-redis-2.0.4.RELEASE-javadoc.jar; 赠送源代码:spring-session-data-redis-2.0.4.RELEASE-sources.jar; 赠送...
因tomcat7使用redis共享session,其他的包存在问题,自己编译后处理通过。 该包是在https://github.com/jcoleman/tomcat-redis-session-manager 将源码编译后的包。
tomcat redis session共享,支持tomcat7 jdk7、tomcat8 jdk7、tomcat8 jdk8、tomcat8.5 jdk7、tomcat9 jdk8
基于redis缓存的session共享使用的jar包。 tomcat集群环境下(通常是借助于nginx),利用这个session共享策略可以共享同一个session。从而保证客户端iip发生变化时(session相同),不会重新登录。
tomcat-redis-session-manager-2.0.0jar包实现session共享问题