1.当前获取token是这么取得
因为在高并发情况下使用getLoginUserInfo获取用户信息是会错乱的因为httpServletRequest是公共的如
protected HttpServletRequest httpServletRequest;这种获取方式
@PostMapping("/wxCurrentUser")
@ApiOperation(value = "获取小程序当前用户信息")
@EncryptionAccess
public GatewayResp<UserInfoResp> wxCurrentUser(){
log.info("个人页面从token中获取用户信息="+JSON.toJSONString(getLoginUserInfo()));
return GatewayResp.ok(getLoginUserInfo());
}
protected HttpServletRequest httpServletRequest;
/**
* 根据token获取登录用户信息
*/
public UserInfoResp getLoginUserInfo() {
String token = httpServletRequest.getHeader("token");
if (StringUtils.isNotEmpty(token) && token.contains("|")) {
token = token.split("\\|")[0];
}
String accessToken = redisTemplate.opsForValue().get(token);
return JSON.parseObject(accessToken, UserInfoResp.class);
}
2.解决方案
在当前接口种获取token
如:
@PostMapping("/wxCurrentUser")
@ApiOperation(value = "获取小程序当前用户信息")
@EncryptionAccess
public GatewayResp<UserInfoResp> wxCurrentUser(){
log.info("个人页面从token中获取用户信息="+JSON.toJSONString(getLoginUserInfo(HttpServletRequest request)));
return GatewayResp.ok(getLoginUserInfo(httpServletRequest.getHeader("token")));
}
/**
* 获取登陆用户信息
*/
public UserInfoResp getLoginUserInfo(String token) {
String accessToken = redisTemplate.opsForValue().get(token);
if (StringUtils.isBlank(accessToken)) {
return getLoginUserInfo();
}
return JSON.parseObject(accessToken, UserInfoResp.class);
}
这样就变为单独线程获取token,能有效得阻止信息错乱
第二种方案
使用LoginUserThreadLocal 来做高并发用户存取
package com.chinaunicom.standard.product.ucenter.provider.api.intercepter;
import com.chinaunicom.standard.product.ucenter.domain.resp.UserInfoResp;
/**
* <p>
* 获取当前登录用户ThreadLocal
* </p>
*
* @author zhaomingleiGlobalExceptionHandler
* @since 2020-09-17
*/
public class LoginUserThreadLocal {
// 记录保存
private static final ThreadLocal<UserInfoResp> localPage = new ThreadLocal<>();
/**
* 设定当前登录用户
*/
public static void set(UserInfoResp user){
localPage.set(user);
}
/**
* 取得登录的用户
* @return
*/
public static UserInfoResp get(){
UserInfoResp user = localPage.get();
localPage.remove();
return user;
}
}
把用户信息放在LoginUserThreadLocal中
LoginUserThreadLocal.set(userInfoResp);
获取用户信息
public UserInfoResp getLoginUserInfo() {
String token = httpServletRequest.getHeader("token");
/*if (StringUtils.isNotEmpty(token) && token.contains("|")) {
token = token.split("\\|")[0];
}
String accessToken = redisTemplate.opsForValue().get(token);
UserInfoResp userInfoResp = JSON.parseObject(accessToken, UserInfoResp.class);
log.info("当前线程:{},token:{},用户信息:{}",Thread.currentThread().getId(),token,userInfoResp.getUserName());
return userInfoResp;*/
UserInfoResp userInfoResp = LoginUserThreadLocal.get();
log.info("当前线程:{},token:{},用户信息:{}",Thread.currentThread().getId(),token,userInfoResp);
return userInfoResp;
}