[alibaba/fastjson]spring-data-redis使用FastJsonRedisSerializer反序列化转换异常

2025-11-03 626 views
7

fastjson版本1.2.51 spring-data-redis版本2.1.0RELEASE 我是这样初始化: 然后注入 存进redis 然后反序列化读取的时候就转换异常了 从redis看存储的json数据好像是没问题的:

网上看到以前的版本别人会手动写一个FastJsonRedisSerializer的serialize和deserialize,但是我看现在已经存在这两个方法了,想着是不是就能直接用了。序列化的差别好像就是 https://github.com/alibaba/fastjson/issues/2060 提到的。在别人的回复 https://github.com/alibaba/fastjson/issues/2083#issuecomment-427728000 里面提到"FastJsonRedisSerializer反序列化过来对象为JSONObject,建议你自己再转换一次", 但是反序列化的方法不是已经有泛型了?为什么还要再重复的转换一次呢?官方都没有好的解决方案吗?

回答

8

获取列表数据带泛型是ok的 可以直接转成对象

7

上面序列化后出现@type是因为我用网上的方法手动实现了serialize和deserialize方法 如果用fastjson默认的方法的话 序列化后是没有这个@type的。

测试了几次 好像用GenericFastJsonRedisSerializer可以正常序列化跟反序列化 会把@type写入。但是格式上不如GenericJackson2JsonRedisSerializer,有class类型 字段也是有序的。GenericFastJsonRedisSerializer如果有Double类型的字段的话 序列化后不能按照json格式化,因为数字后有D。但是不影响反序列化。

0

@lihengming 帮忙看一下

1

@DreamXiao see https://github.com/alibaba/fastjson/wiki/%E5%9C%A8-Spring-%E4%B8%AD%E9%9B%86%E6%88%90-Fastjson#%E5%9C%A8-spring-data-redis-%E4%B8%AD%E9%9B%86%E6%88%90-fastjson

8

@VictorZeng 是这样配置没错的 你也可以看到我的代码截图 具体几种不同的序列化后的字符串在上面评论我也提供了

1

@DreamXiao “通常使用 GenericFastJsonRedisSerializer 即可满足大部分场景,如果你想定义特定类型专用的 RedisTemplate 可以使用 FastJsonRedisSerializer 来代替 GenericFastJsonRedisSerializer” 也就是说GenericFastJsonRedisSerializer 可以自动转换对象类型,FastJsonRedisSerializer 需要自定义转换需要的类型。

5

@VictorZeng 嗯嗯谢谢 看起来格式化后还是GenericJackson2JsonRedisSerializer舒服 不过可能fastjson性能会更优于GenericJackson2JsonRedisSerializer吧。

2

fixed by #2153

1

@DreamXiao “通常使用 GenericFastJsonRedisSerializer 即可满足大部分场景,如果你想定义特定类型专用的 RedisTemplate 可以使用 FastJsonRedisSerializer 来代替 GenericFastJsonRedisSerializer” 也就是说GenericFastJsonRedisSerializer 可以自动转换对象类型,FastJsonRedisSerializer 需要自定义转换需要的类型。

完美解决。谢谢了

5

fastjson版本1.2.51 spring-data-redis版本2.1.0RELEASE 我是这样初始化: 然后注入 存进redis 然后反序列化读取的时候就转换异常了 从redis看存储的json数据好像是没问题的: 网上看到以前的版本别人会手动写一个FastJsonRedisSerializer的serialize和deserialize,但是我看现在已经存在这两个方法了,想着是不是就能直接用了。序列化的差别好像就是 #2060 提到的。在别人的回复 #2083 (comment) 里面提到"FastJsonRedisSerializer反序列化过来对象为JSONObject,建议你自己再转换一次", 但是反序列化的方法不是已经有泛型了?为什么还要再重复的转换一次呢?官方都没有好的解决方案吗?

我的配置跟这个一样,不过我是用的是:GenericFastJsonRedisSerializer,配置使用的是默认的配置。我的序列化很好,但是反序列化的时候出现异常:

org.springframework.data.redis.serializer.SerializationException: Could not deserialize: not close json text, token : error; nested exception is com.alibaba.fastjson.JSONException: not close json text, token : error
  at com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer.deserialize(GenericFastJsonRedisSerializer.java:37)
  at org.springframework.data.redis.core.AbstractOperations.deserializeValue(AbstractOperations.java:335)
  at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:61)
  at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:228)
  at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:188)
  at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:96)
  at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:53)
  at com.xxxxxxx.xxxxxxxxx.service.service.impl.CacheServiceImpl.get(CacheServiceImpl.java:92)
  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:498)
  at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:205)
  at com.sun.proxy.$Proxy90.get(Unknown Source)
  at com.xxxxxxxx.xxxxxxx.service.service.impl.WeiXinAuthFactory.accessToken(WeiXinAuthFactory.java:41)
  at com.xxxxxxxx.xxxxxxxxx.reactor.listener.TemplateMsgListener.onApplicationEvent(TemplateMsgListener.java:39)
  at com.xxxxxxx.xxxxxxxxxx.reactor.listener.TemplateMsgListener.onApplicationEvent(TemplateMsgListener.java:20)
  at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
  at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:158)
  at org.springframework.context.event.SimpleApplicationEventMulticaster.lambda$multicastEvent$0(SimpleApplicationEventMulticaster.java:136)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  at java.lang.Thread.run(Thread.java:748)
Caused by: com.alibaba.fastjson.JSONException: not close json text, token : error
  at com.alibaba.fastjson.parser.DefaultJSONParser.close(DefaultJSONParser.java:1527)
  at com.alibaba.fastjson.JSON.parseObject(JSON.java:400)
  at com.alibaba.fastjson.JSON.parseObject(JSON.java:359)
  at com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer.deserialize(GenericFastJsonRedisSerializer.java:35)
  ... 23 common frames omitted

而且这个Value序列化的时候,就是使用的GenericFastJsonRedisSerializer,但是它自己反序列话的时候,确不行了。有一点是,我序列化的内容里面可能会有下划线,真糟心