Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

weixin-java-miniapp使用WxMaRedisConfigImpl存储token时,报空指针 #1198

Closed
jsnjfz opened this issue Sep 10, 2019 · 6 comments
Closed

Comments

@jsnjfz
Copy link

jsnjfz commented Sep 10, 2019

简要描述

weixin-java-miniapp使用WxMaRedisConfigImpl存储token时,启动后第一次调用WxMaServiceImpl的getAccessToken报空指针

模块版本情况

  • WxJava 模块名: weixin-java-miniapp
  • WxJava 版本号:3.5.0

详细描述

使用WxMaRedisConfigImpl存储redis时,如果是启动后第一次调用WxMaServiceImpl的getAccessToken方法时,会报空指针,我看WxMpInRedisConfigStorage是用redis的ttl过期时间来处理的,即使是没有设置也不会返回空指针,会返回int值。WxMaRedisConfigImpl是单独设置了一个key,value,猜想第一次的时候没有设置expire,所以会报空指针。(accessToken值已写入redis)
另外顺带问下WxMaRedisConfigImpl支持多个小程序么,因为看redis中存储的结构也和WxMpInRedisConfigStorage不同

日志

https://paste.ubuntu.com/p/kMR848v6WQ/

@binarywang
Copy link
Owner

WxMaRedisConfigImpl 仅供参考,默认应该是只支持一个的,你自己扩展下即可支持多个

@binarywang
Copy link
Owner

#1100 @winter4666 有空帮忙看下吧,这个类应该是你实现的。

@winter4666
Copy link

看你贴的异常信息:

java.lang.NullPointerException: null
	at cn.binarywang.wx.miniapp.config.impl.WxMaRedisConfigImpl.getExpireFromRedis(WxMaRedisConfigImpl.java:89) ~[weixin-java-miniapp-3.5.0.jar!/:na]

WxMaRedisConfigImpl类的第89行报了错误,而这个类的第89行代码是:

try (Jedis jedis = jedisPool.getResource()) {

初步判定是你使用WxMaRedisConfigImpl类的时候没有使用setJedisPool设置jedisPool,可以检查下你使用该类的代码,或者把代码贴上来看看。

@jsnjfz
Copy link
Author

jsnjfz commented Sep 11, 2019

我已经加了断点远程调试了,就是在getExpireFromRedis报错的,这个时候redis里面并没有expire的值,setJedisPool我肯定是set的,不然运行都运行不起来
代码:
JedisPool 做成一个bean,然后

@Autowired
private JedisPool jedisPool;

@Bean
public WxMaConfig wxMaConfig() {
    WxMaRedisConfigImpl config = new WxMaRedisConfigImpl();
    config.setJedisPool(jedisPool);
    config.setAppid(wxMaProperties.getConfigs().get(3).getAppid());
    config.setSecret(wxMaProperties.getConfigs().get(3).getSecret());
    config.setToken(wxMaProperties.getConfigs().get(3).getToken());
    config.setAesKey(wxMaProperties.getConfigs().get(3).getAesKey());
    config.setMsgDataFormat(wxMaProperties.getConfigs().get(3).getMsgDataFormat());
    return config;
}

@winter4666
Copy link

下面是getExpireFromRedis方法的代码:

  private long getExpireFromRedis(String key) {
    try (Jedis jedis = jedisPool.getResource()) {
      String expire = jedis.hget(getRedisKey(key), HASH_EXPIRE_FIELD);
      return expire == null ? 0 : Long.parseLong(expire);
    }
  }

可以看到这一行String expire = jedis.hget(getRedisKey(key), HASH_EXPIRE_FIELD);是从redis里面取expire值,而即使redis里面没有存这个expire(也就是第一次取的时候),实际上这一行代码也不会报错,而是会返回一个空值。
然后紧接着下一行代码return expire == null ? 0 : Long.parseLong(expire);这里是判了空的,假如expirenull,这个方法会以0返回,其实也不会有异常。

@jsnjfz
Copy link
Author

jsnjfz commented Sep 11, 2019

看了你的代码,确实如你说的,我再断点看下

@jsnjfz jsnjfz closed this as completed Sep 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants