出现问题:
调用远程服务对用户token进行验证时
public String checkToken(String token) {
String userTokenKey = userCacheKeyBuilder.buildUserPhoneKey(token);
String userId = String.valueOf(redisTemplate.opsForValue().get(userTokenKey));
if (StringUtils.hasText(userId)) {
return userId;
}
return null;
}
String userId = userRPCSService.checkToken(cookieValue);
log.info("Token 验证结果: {}", userId);
if (!StringUtils.hasText(userId)) {
log.info("携带的Token已失效");
return errorMessageResponse(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
2024-08-13T00:55:12.445+08:00 INFO 33008 --- [nio-8888-exec-4] c.y.gateway.filter.AuthorizationFilter : 请求路径: /user/queryUser
2024-08-13T00:55:12.445+08:00 INFO 33008 --- [nio-8888-exec-4] c.y.gateway.filter.AuthorizationFilter : 携带的Token: 930ae646-c98a-4933-ae50-6462cb88f933
2024-08-13T00:55:12.742+08:00 INFO 33008 --- [nio-8888-exec-4] c.y.gateway.filter.AuthorizationFilter : Token 验证结果: null
2024-08-13T00:55:12.742+08:00 INFO 33008 --- [nio-8888-exec-4] c.y.gateway.filter.AuthorizationFilter : 当前登录的用户ID: null
结果:验证userId为空就执行相关代码,可是不执行,跳过相关代码,这是怎么回事呢?
经过长达3个小时的努力,终于解决,其实在判断是否为空的时候,我们应该将所需条件都考虑进去。
解决办法:
-
检查 Redis 返回值的类型:
- 确保从 Redis 获取的值是你期望的类型。
String.valueOf()
将null
转换为字符串"null"
,所以如果 Redis 中没有对应的值,你需要处理这种情况。
- 确保从 Redis 获取的值是你期望的类型。
-
处理
null
值:- 直接调用
String.valueOf()
可能会导致问题,因为String.valueOf(null)
会返回"null"
,不是实际的null
。你可以先检查获取的值是否为null
,然后再转换。
- 直接调用
-
改进代码逻辑:
- 更直接地检查 Redis 返回值,并且只在值不为空时返回
userId
。
- 更直接地检查 Redis 返回值,并且只在值不为空时返回
修改后的代码:
public String checkToken(String token) {
String userTokenKey = userCacheKeyBuilder.buildUserPhoneKey(token);
// 从 Redis 获取值
Object value = redisTemplate.opsForValue().get(userTokenKey);
// 检查值是否为空,并转换为字符串
if (value != null && StringUtils.hasText(value.toString())) {
return value.toString();
}
return null;
}
另外一种解决办法相关代码:
public String checkToken(String token) {
String userTokenKey = userCacheKeyBuilder.buildUserPhoneKey(token);
#直接判断是否存在key,再返回
if (Boolean.TRUE.equals(redisTemplate.hasKey(userTokenKey))) {
return String.valueOf(redisTemplate.opsForValue().get(userTokenKey));
}
return null;
}