GSON的序列化问题-(子类于父类具有相同属性)

1 篇文章 0 订阅

背景

因为fastjson的安全漏洞问题,项目中不得不将fastjson更换。研究之后决定采用gson做序列化。

场景

因原序列化代码,用在reids中,重写了序列化方法,报序列化bug之后这也误导了我们一段时间。

GSON序列化报错如下:
“class XXX declares multiple JSON fields named XXX”,
可以看出这是序列化字段时出现了错误,添加 transient 关键字 修饰 不需要序列化的字段,便可以解决该序列化问题。

在项目中存在 子类继承父类,且子类transient与父类具有相同的属性,导致gson在序列化时出错。此时只需要添加transient即可(需要分析代码添加到子类还是父类)

@Getter
@Setter
public class BaseDTO<T> {
    private transient  Long id;
}
@Getter
@Setter
public class ZmsDTO<T> extends BaseDTO<T> {
    private Long id;
    private String name;
    private List<T> childrens = new ArrayList<>();
}

序列化

  public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }

        //JSONObject.toJSONString(t, SerializerFeature.WriteClassName).getBytes(IOUtils.UTF8)
        Gson gson = new Gson();
        String str =gson.toJson(t);
        byte[] bytes = new byte[0];
        try {
            bytes = str.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return  bytes;
    }

反序列化

public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = null;
        try {
            str = new String(bytes,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //JSONObject.parseObject(str, type, defaultRedisConfig)
        Gson gson = new Gson();
        return  gson.fromJson(str, type);
    }

因部分朋友需要demo,现补充一下demo
首先实现自己的序列化方法

/**
 * Redis序列化
 *
 *

 */
public class GsonRedisSerializer<T> implements RedisSerializer<T> {


    private Class<T> type;

    public GsonRedisSerializer(Class<T> type) {
        this.type = type;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }

        //JSONObject.toJSONString(t, SerializerFeature.WriteClassName).getBytes(IOUtils.UTF8)
        Gson gson = new Gson();
        String str =gson.toJson(t);
        byte[] bytes = new byte[0];
        try {
            bytes = str.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return  bytes;
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = null;
        try {
            str = new String(bytes,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //JSONObject.parseObject(str, type, defaultRedisConfig)
        Gson gson = new Gson();
        return  gson.fromJson(str, type);
    }
}

然后替换Redis的序列化

/**
 * Redis配置
 *
 *
 */
@Configuration
public class RedisConfig {
    @Resource
    private RedisConnectionFactory factory;

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        
        redisTemplate.setValueSerializer(new GsonRedisSerializer<>(Object.class));
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        
        redisTemplate.setHashValueSerializer(new GsonRedisSerializer<>(Object.class));
        redisTemplate.setConnectionFactory(factory);

        return redisTemplate;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值