fastjson2 icon indicating copy to clipboard operation
fastjson2 copied to clipboard

Redis序列化使用GenericFastJsonRedisSerializer,存入的是List<xx>,获取的时候List<xx>接收

Open prog-ape opened this issue 3 years ago • 10 comments

使用版本:2.0.4 Redis序列化使用GenericFastJsonRedisSerializer,存入的是List,获取的时候List接收,提示fastjson2.JSONArray无法转成List

prog-ape avatar May 25 '22 04:05 prog-ape

能提供进一步的错误信息么?比如堆栈信息

wenshao avatar May 25 '22 04:05 wenshao

@alon-sys 可以使用FastJsonRedisSerializer临时解决您的问题


FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(List.class);
FastJsonConfig config = new FastJsonConfig();
config.setReaderFeatures(JSONReader.Feature.SupportAutoType);
config.setWriterFeatures(JSONWriter.Feature.WriteClassName);
serializer.setFastJsonConfig(config);

VictorZeng avatar May 25 '22 05:05 VictorZeng

好的,谢谢

prog-ape avatar May 25 '22 07:05 prog-ape

@alon-sys 可以使用FastJsonRedisSerializer临时解决您的问题

FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(List.class);
FastJsonConfig config = new FastJsonConfig();
config.setReaderFeatures(JSONReader.Feature.SupportAutoType);
config.setWriterFeatures(JSONWriter.Feature.WriteClassName);
serializer.setFastJsonConfig(config);

问题还是一样,用1.2.83没有这种问题

prog-ape avatar May 25 '22 08:05 prog-ape

@alon-sys 能否提供一下testcase

VictorZeng avatar May 25 '22 08:05 VictorZeng

private static final RedisTemplate redisTemplate = SpringUtils.getBean("redisTemplate", RedisTemplate.class);

public static <T> T get(final String key) {
    ValueOperations<String, T> operation = redisTemplate.opsForValue();
    return operation.get(key);
}

public static <T> void set(final String key, final T value) {
    redisTemplate.opsForValue().set(key, value);
}

RedisUtils.set(cacheKey,List<SpecValueVO>) JSONObject jsonObject = JSON.parseObject(getSpecsCache());

就是一个简单的操作

prog-ape avatar May 25 '22 08:05 prog-ape

@alon-sys 能否再提供一下测试的数据

VictorZeng avatar May 25 '22 08:05 VictorZeng

也遇见了相同问题,在 Redis Hash 结构中,对存储 Java List 类型数据进行解析的时候出现该异常。 测试案例如下,将 RedisTemplate value 的序列化方式修改为 Fastjson2


     public void setSerializer(RedisTemplate<?, ?> redisTemplate) {
        GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer();

        // 设置键(key)的序列化方式
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        // 设置值(value)的序列化方式
        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
        redisTemplate.setValueSerializer(fastJsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
    }

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Test
    public void setHashObjToListByFastjson2() {
        String key   = "test-setHashObjToList";
        String field = "setHashObjToList";

        List<TestPOJO> list = new ArrayList<>();
        list.add(new TestPOJO("张三", "18"));
        list.add(new TestPOJO("王五", "19"));

        redisTemplate.opsForHash().put(key, field, list);
    }

    @Test
    public void getHashObjToListByFastJson2() {
        String key   = "test-getHashObjToList";
        String field = "getHashObjToList";

        List<TestPOJO> list = new ArrayList<>();
        list.add(new TestPOJO("张三", "18"));
        list.add(new TestPOJO("王五", "19"));

        // set
        kvCacheService.setHashObj(key, field, list);

        List<TestPOJO> getVal = (List<TestPOJO>) redisTemplate.opsForHash().get(key, field);
        log.info("Val:[{}]", getVal.toString());
        log.info("Val 0:[{}]", getVal.get(0).toString());
    }

    public class TestPOJO {

        private String name;
        private String age;

        public TestPOJO(String name, String age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getAge() {
            return age;
        }

        public void setAge(String age) {
            this.age = age;
        }
    }

mosys avatar May 25 '22 10:05 mosys

@Mosys 您好 可以试试使用FastJsonRedisSerializer能否解决您的问题

FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(List.class);
FastJsonConfig config = new FastJsonConfig();
config.setReaderFeatures(JSONReader.Feature.SupportAutoType);
config.setWriterFeatures(JSONWriter.Feature.WriteClassName);
serializer.setFastJsonConfig(config);

VictorZeng avatar May 25 '22 10:05 VictorZeng

@Mosys您可以很好地使用FastJsonRedisSerializer 来解决您的问题

FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(List.class);
FastJsonConfig config = new FastJsonConfig();
config.setReaderFeatures(JSONReader.Feature.SupportAutoType);
config.setWriterFeatures(JSONWriter.Feature.WriteClassName);
serializer.setFastJsonConfig(config);

使用该方式可以临时解决该类型无法转换的问题。

mosys avatar May 25 '22 10:05 mosys