Redis序列化配置

谁说我不能喝 提交于 2019-12-23 22:52:33

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

序列化说明

修改RedisTemplate的默认序列化配置,默认是使用JDK的序列化,通过自己实现RedisSerializer接口编写需要的序列化方式。

使用Fastjson进行RedisTemplate的Value序列化

package cc.xuepeng.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * 使用Alibaba的FastJson作为Json序列化的工具。
 *
 * @param <T>
 * @author xuepeng
 */
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {

    /**
     * 默认的转换编码。
     */
    private static final Charset DEFAULT_CHARSET = Charset.forName(StandardCharsets.UTF_8.name());
    /**
     * 要转换的类的Class对象。
     */
    private Class<T> clazz;

    /**
     * 构造函数。
     *
     * @param clazz 设置要序列化的对象的Class对象。
     */
    public FastJsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }

    /**
     * 序列化对象。
     *
     * @param object 要被序列化的对象。
     * @return 序列化成字节数组。
     */
    @Override
    public byte[] serialize(T object) {
        if (object == null) {
            return new byte[0];
        }
        return JSON.toJSONString(object, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    /**
     * 反序列化对象。
     *
     * @param bytes 字节数组。
     * @return 要序列化的对象。
     */
    @Override
    public T deserialize(byte[] bytes) {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);
        return JSON.parseObject(str, clazz);
    }

}

进行RedisTemplate的Key序列化

package cc.xuepeng.config;

import com.alibaba.fastjson.JSON;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * 自定义StringRedisSerializer列化器。
 * 原生的StringRedisSerializer在使用@Cacheable注解时,当key不是String类型会发生错误。
 * 因为原生的StringRedisSerializer只支持String。
 *
 * @author xuepeng
 */
public class StringRedisSerializer implements RedisSerializer<Object> {

    /**
     * 默认的转换编码。
     */
    private final Charset charset;
    /**
     * 反斜杠符号。
     */
    private static final String TARGET = "\"";
    /**
     * 空格符号。
     */
    private static final String REPLACEMENT = "";

    /**
     * 构造函数。
     */
    public StringRedisSerializer() {
        this(Charset.forName(StandardCharsets.UTF_8.name()));
    }

    /**
     * 构造函数。
     *
     * @param charset 转换编码。
     */
    public StringRedisSerializer(Charset charset) {
        Assert.notNull(charset, "Charset must not be null!");
        this.charset = charset;
    }

    @Override
    public byte[] serialize(Object object) {
        String string = JSON.toJSONString(object);
        if (StringUtils.isEmpty(string)) {
            return new byte[0];
        }
        string = string.replace(TARGET, REPLACEMENT);
        return string.getBytes(charset);
    }

    @Override
    public Object deserialize(byte[] bytes) {
        if (bytes != null) {
            return new String(bytes, charset);
        }
        return null;
    }

}

设置RedisConfig

/**
 * Redis配置类。
 *
 * @author xuepeng
 */
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {

    /**
     * 重写Redis序列化方式,使用Json方式:
     * 当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的。
     * RedisTemplate默认使用的是JdkSerializationRedisSerializer,StringRedisTemplate默认使用的是StringRedisSerializer。
     * 在此我们将自己配置RedisTemplate并定义Serializer。
     *
     * @param redisConnectionFactory redis连接工厂。
     * @return redisTemplate对象。
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
        // 全局开启AutoType,不建议使用
        // ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        // 建议使用这种方式,小范围指定白名单
        ParserConfig.getGlobalInstance().addAccept("cc.xuepeng.");
        // 设置键(key)的序列化采用StringRedisSerializer。
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // 设置值(value)的序列化采用FastJsonRedisSerializer。
        redisTemplate.setValueSerializer(fastJsonRedisSerializer);
        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
        return redisTemplate;
    }

}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!