当前位置: 代码网 > it编程>数据库>Redis > Redis @type坑的解决

Redis @type坑的解决

2024年06月17日 Redis 我要评论
redis中@type导致取数据解析报错java.lang.classcastexception: com.alibaba.fastjson.jsonobject cannot be cast to新

redis中@type导致取数据解析报错

java.lang.classcastexception: com.alibaba.fastjson.jsonobject cannot be cast to
新建一个对象存入redis中,对象中会出现一个字段@type

loginuser user = new loginuser ()
......
redistemplate.opsforvalue().set(key, user)

存入redis中数据如下

127.0.0.1:6379> get login_tokens:5be4de32-6eb5-44a5-b212-56d93e3fc067
"{\"@type\":\"com.common.core.domain.model.loginuser\",\"deptid\":103l,\"expiretime\":1710463649132,\"token\":\"xxxx\",\"user\":{\"admin\":true,\"createby\":\"admin\",\"dept\":{\"deptid\":103l,\"deptname\":\"xxx",\"ordernum\":1,\"params\":{\"@type\":\"java.util.hashmap\"},\"parentid\":101l,\"status\":\"0\"},\"deptid\":103l,\"logindate\":\"2024-03-14 14:35:56\",\"loginip\":\"127.0.0.1\",\"nickname\":\"xxx\",\"params\":{\"@type\":\"java.util.hashmap\"},\"phonenumber\":\"15888888888\",\"sex\":\"1\",\"status\":\"0\",\"userid\":1l,\"username\":\"admin\"},\"userid\":1l,\"username\":\"admin\"}"
127.0.0.1:6379>

取数据时,redistemplate.opsforvalue().get(key);
如果loginuser对象的包与存入时的包路径不一致,会报错java.lang.classcastexception: com.alibaba.fastjson.jsonobject cannot be cast to

redis缓存序列化导致存储数据没有@type

在使用redis注解将数据缓存的时候发现存储进去的数据是这样的,没有@type

127.0.0.1:6379> get login_tokens:5be4de32-6eb5-44a5-b212-56d93e3fc067
"{\"deptid\":103l,\"expiretime\":1710463649132,\"token\":\"xxxx\",\"user\":{\"admin\":true,\"createby\":\"admin\",\"dept\":{\"deptid\":103l,\"deptname\":\"xxx",\"ordernum\":1,\"parentid\":101l,\"status\":\"0\"},\"deptid\":103l,\"logindate\":\"2024-03-14 14:35:56\",\"loginip\":\"127.0.0.1\",\"nickname\":\"xxx\",\"phonenumber\":\"15888888888\",\"sex\":\"1\",\"status\":\"0\",\"userid\":1l,\"username\":\"admin\"},\"userid\":1l,\"username\":\"admin\"}"
127.0.0.1:6379>

之前通过set方法放进去的数据是这样的

127.0.0.1:6379> get login_tokens:5be4de32-6eb5-44a5-b212-56d93e3fc067
"{\"@type\":\"com.common.core.domain.model.loginuser\",\"deptid\":103l,\"expiretime\":1710463649132,\"token\":\"xxxx\",\"user\":{\"admin\":true,\"createby\":\"admin\",\"dept\":{\"deptid\":103l,\"deptname\":\"xxx",\"ordernum\":1,\"params\":{\"@type\":\"java.util.hashmap\"},\"parentid\":101l,\"status\":\"0\"},\"deptid\":103l,\"logindate\":\"2024-03-14 14:35:56\",\"loginip\":\"127.0.0.1\",\"nickname\":\"xxx\",\"params\":{\"@type\":\"java.util.hashmap\"},\"phonenumber\":\"15888888888\",\"sex\":\"1\",\"status\":\"0\",\"userid\":1l,\"username\":\"admin\"},\"userid\":1l,\"username\":\"admin\"}"
127.0.0.1:6379>

原因:
是因为set方法的序列化方法和注解的序列化方法不同

在这里插入图片描述

解决办法:
将序列化方法更换成set方法所使用的序列化方法

下面是序列化方法

public class fastjson2jsonredisserializer<t> implements redisserializer<t> {
    @suppresswarnings("unused")
    private objectmapper objectmapper = new objectmapper();

    public static final charset default_charset = standardcharsets.utf_8;

    private class<t> clazz;

    static {
        parserconfig.getglobalinstance().setautotypesupport(true);
    }

    public fastjson2jsonredisserializer(class<t> clazz) {
        super();
        this.clazz = clazz;
    }

    @override
    public byte[] serialize(t t) throws serializationexception {
        if (t == null) {
            return new byte[0];
        }
        return json.tojsonstring(t, serializerfeature.writeclassname).getbytes(default_charset);
    }

    @override
    public t deserialize(byte[] bytes) throws serializationexception {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        string str = new string(bytes, default_charset);
        return json.parseobject(str, clazz);
    }

    public void setobjectmapper(objectmapper objectmapper) {
        assert.notnull(objectmapper, "'objectmapper' must not be null");
        this.objectmapper = objectmapper;
    }

    protected javatype getjavatype(class<?> clazz) {
        return typefactory.defaultinstance().constructtype(clazz);
    }
}

serializerfeature.writeclassname这个序列化

public static string getstring(object object) {
   return json.tojsonstring(object, serializerfeature.writeclassname);
}

如果加了serializerfeature.writeclassname存进redis当中的实体类就会带@type路径地址
“@type”:“com.xxx.xxx.entity.opennotice”

问题解决方案:去掉@type 或者 两边@type路径存放路径一致 (包名和实体类修改为一致)

去掉@type使用 jsonobject.tojsonstring(obj)来存value实体类

    /**
     * hashmap存值方式
     *
     * @param parentkey
     * @param fieldkey
     * @param obj
     */
    public static void hashset(string parentkey, string fieldkey, object obj) {
        try {
            jedis.hset(parentkey, fieldkey, jsonobject.tojsonstring(obj));
            //jedis.hset(parentkey, fieldkey, jsonparser.getstring(obj)); //"@type":"com.xyz.minilegion.entity.opennotice"
        } finally {
            jedis.close();
        }
    }

获取hashall数据

   /**
     * 获取hashgetall
     * @param parentkey
     * @return
     */
    public map<string, string> hashgetall(string parentkey) {
        try (jedis jedis = pools.getresource()) { //这种写法不需要手动close();
            return jedis.hgetall(parentkey);
        }catch (exception e) {      
            return null;
        }
    }

测试redis转实体类`

   @test
    void getsoldierattribute() {
        map<string, string> opennoticemap = redispoolmgr.hashgetall(staticdata.opennotice);
        //第一种根据key循环
        for (string key : opennoticemap.keyset()) {
            opennotice opennotice = jsonobject.parseobject(opennoticemap.get(key), opennotice.class);
            system.out.println("根据key循环:" +opennotice.getcontent());
            system.out.println("根据key循环:" + jsonobject.tojsonstring(opennotice));
        }
 
        //第二种根据value循环
        for (string values : opennoticemap.values()) {
            opennotice opennotice = jsonobject.parseobject(values, opennotice.class);
            system.out.println("根据value循环:"+opennotice.getcontent());
            system.out.println("根据value循环:" + jsonobject.tojsonstring(opennotice));
        }
    }

在这里插入图片描述

 到此这篇关于redis @type坑的解决的文章就介绍到这了,更多相关redis @type坑内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com