jfinal的Redis插件为啥存取数据用二进制byte形式

错觉 发布于 2015/08/03 21:34
阅读 2K+
收藏 0

@JFinal 你好,想跟你请教个问题:

在使用redis插件的时候,发现了一些莫名其妙的空指针错误,都是来自FST的,查看源码才发现jfinal存取redis数据都用bytes方式,

1. 请问这样有什么好处吗?

2. 我用redis-cli都查看不到真实数据了,怎么搞啊?

3. incr之后取值就报错?

例如:

先执行:

        Cache redis = Redis.use();
        Long errCnt = redis.incr(key);  //用于记录验证码错误次数
然后再执行:

        redis.get(key);        

就报如下错误:(应该是反序列化时候出现了错误,不知道为啥)

Exception in thread "main" java.lang.RuntimeException: java.io.IOException: java.lang.NullPointerException
at com.jfinal.plugin.redis.serializer.FstSerializer.valueFromBytes(FstSerializer.java:69)
at com.jfinal.plugin.redis.Cache.valueFromBytes(Cache.java:1161)
at com.jfinal.plugin.redis.Cache.get(Cache.java:87)
at com.app.common.util.ErrCntKit.isOverErrCntLimit(ErrCntKit.java:34)
at com.app.common.util.ErrCntKit.main(ErrCntKit.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.io.IOException: java.lang.NullPointerException
at org.nustaq.serialization.FSTObjectInput.readObject(FSTObjectInput.java:241)
at com.jfinal.plugin.redis.serializer.FstSerializer.valueFromBytes(FstSerializer.java:66)
... 9 more
Caused by: java.lang.NullPointerException
at org.nustaq.serialization.FSTObjectInput.readObjectWithHeader(FSTObjectInput.java:350)
at org.nustaq.serialization.FSTObjectInput.readObjectInternal(FSTObjectInput.java:325)
at org.nustaq.serialization.FSTObjectInput.readObject(FSTObjectInput.java:305)
at org.nustaq.serialization.FSTObjectInput.readObject(FSTObjectInput.java:239)
... 10 more

4. 必须在get前执行if(redis.exists())判断是否存在,如果不存在就异常,都是这个bytes和FST的事情,能不能简单点弄个是否存取用bytes的开关啊,我知道咋改,不过希望jfinal加入这个开关。

加载中
0
错觉
错觉

我现在只能换会Jedis的形式,如下:

        Cache redis = Redis.use();
        Jedis jedis = redis.getJedis();
        String errCntStr = jedis.get(key);
        redis.close(jedis);

我真郁闷

0
石头哥哥
石头哥哥
其实jfinal和 redis插件  这个 没有必然联系 ,既然 存在这个插件 自己定制 写一个还不是可以,别被这些给禁锢了。redis  ---java直接用jedis + 序列化的工具(kyro,fst)就可以了
0
JFinal
JFinal

     redis 只支持 String 类型的数据,而 java 有丰富的数据类型,所以才将数据先转成 byte[] 再保存,数据转换使用了 Fst,而 Fst 转换时有它自己的格式,所以使用 redis-cli 去读取 Fst 格式的数据是不可以的。

    楼主可以自己做些实验,会逐步明白 jfinal 的做法是经过很多权衡后的结果。目前的做法,楼主只需要让读和写都使用jfinal 提供的 RedisPlugin即可,对于 redis-cli 的使用,用一下 exists 这类对 key 值的操作就好,jfinal 对于 string 型的 key 值并没有使用 fst 做转换。

callmeHEN
callmeHEN
@JFinal 我就说我存的为何是乱码,请问老大 转换为byte[]存的原因是什么呢,理解不到。
JFinal
JFinal
自增也用 jfinal 提供的 RedisPlugin 即可,本质上与我上面说的是一回事
错觉
错觉
大大,我说的第三点,自增后,取值就出异常这个是我哪里写的不对吗
0
kingwrcy
kingwrcy

@jfinal 

存进去一个

Map<String, Object>

为啥读不出来了?在redis-cli下get是有值的,java中报错为


java.lang.RuntimeException: java.io.IOException: java.lang.NullPointerException

at com.jfinal.plugin.redis.serializer.FstSerializer.valueFromBytes(FstSerializer.java:69)

还有非要jdk1.7吗?我用1.6一直报 

org/nustaq/serialization/FSTObjectOutput : Unsupported major.minor version 51.0


Jimmy哥
Jimmy哥
回复 @Jimmy哥 : 因为我保存的就是一个Boolean,所以拿出来的理所当然就是布尔类型了,并非RedisPlugin的问题
Jimmy哥
Jimmy哥
我也遇到了您这种情况: 使用JFinal的RedisPlugin往redis的哈希结构保存一个java.util.Set对象,再次取值,返回的是Boolean对象。 不知道您是如何正确获取Map<String, Object>
kingwrcy
kingwrcy
回复 @JFinal : 我都是用jfinal提供的set和get来操作的,value是map<String,Object>,key是string,get出来时就报错了,value也换成string,就ok了
JFinal
JFinal
存与写都要使用 RedisPlugin,不能与 redis-cli 混用
0
kingwrcy
kingwrcy

没有混用,我写的时候是

Cache cache = Redis.use();
		String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
		File file = new File(path);
		try {
			for (File f : file.listFiles()) {
			    if (f.isFile() && f.getPath().endsWith(".json")) {
			    	cache.set(FilenameUtils.getBaseName(f.getPath()), FileUtils.readFileToString(f, "utf-8"));
			    }
			}
		} catch (Exception e) {
			e.printStackTrace();
		}



读是
String tbInfo = cache.get(tableName);

用的都是jfinal自带的api,没有混用,我最后没办法key和value都换成了String就正常了.



0
错觉
错觉

这个序列化的问题多的很,不觉得恶心的话就把jedis给get出来,然后手动close,受不了的话自己加个禁用bytes的扩展

kingwrcy
kingwrcy
没禁用,但是key和value都是string,就是对的
返回顶部
顶部