为Redis配置自定义fastJson序列化工具类

    alibaba.fastjson内部已经提供了对Redis存储对象序列化的工具类GenericFastJsonRedisSerializer,但是该工具在反序列化时返回为Object,我们仿照GenericFastJsonRedisSerializer来自定义一个扩展的工具类,反序列化后自动转化为指定的java对象。

  • GenericFastJsonRedisSerializer 源码
package com.alibaba.fastjson.support.spring;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.IOUtils;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

/**
 * {@link RedisSerializer} FastJson Generic Impl
 * @author lihengming
 * @since 1.2.36
 */
public class GenericFastJsonRedisSerializer implements RedisSerializer<Object> {
    private final static ParserConfig defaultRedisConfig = new ParserConfig();
    static { defaultRedisConfig.setAutoTypeSupport(true);}

    public byte[] serialize(Object object) throws SerializationException {
        if (object == null) {
            return new byte[0];
        }
        try {
            return JSON.toJSONBytes(object, SerializerFeature.WriteClassName);
        } catch (Exception ex) {
            throw new SerializationException("Could not serialize: " + ex.getMessage(), ex);
        }
    }

    public Object deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        try {
            return JSON.parseObject(new String(bytes, IOUtils.UTF8), Object.class, defaultRedisConfig);
        } catch (Exception ex) {
            throw new SerializationException("Could not deserialize: " + ex.getMessage(), ex);
        }
    }
}

  • 自定义FastJsonRedisSerializer
import java.nio.charset.Charset;

import com.alibaba.fastjson.parser.ParserConfig;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * <Description> fastjson序列化<br>
 * 
 * @author xubin<br>
 * @version 1.0<br>
 * @taskId <br>
 * @param <T> 泛化
 * @CreateDate Nov 8, 2018 <br>
 */

public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {

    private final static ParserConfig defaultRedisConfig = new ParserConfig();
    static { defaultRedisConfig.setAutoTypeSupport(true);}

    /**
     * DEFAULT_CHARSET <br>
     */
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    /**
     * clazz 反序列化类<br>
     */
    private Class<T> clazz;

    /**
     * <Description> 构造器<br>
     * 
     * @param clazz 反序列化目标类
     */
    public FastJsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }

    /**
     * Description: 序列化<br>
     * 
     * @author xubin<br>
     * @taskId <br>
     * @param t
     * @return
     * @throws SerializationException <br>
     */
    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }


    /**
     * Description: 反序列化<br>
     * 
     * @author xubin<br>
     * @taskId <br>
     * @param bytes
     * @return
     * @throws SerializationException <br>
     */
    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);
        return (T) JSON.parseObject(str, clazz, defaultRedisConfig);
    }

}

  • json报文示例
{
    "@type": "com.lucas.device.mqtt.protocol.MqttPacketCache",
    "id": 647682641483370500,
    "packet": {
        "@type": "com.lucas.device.mqtt.protocol.Packet",
        "body": {
            "@type": "com.lucas.device.mqtt.protocol.payload.BindFacesetBody",
            "facesetTokenList": [
                "630281772974575616"
            ]
        },
        "head": {
            "code": 114,
            "id": 647682641483370500,
            "type": 2,
            "version": 1
        }
    }
}

此处要注意的是defaultRedisConfig.setAutoTypeSupport(true)这段,在调用JSON.toJSONString(object, SerializerFeature.WriteClassName)时会在json报文中包含@type信息,反序列化时会根据 @type 对要映射的对象进行检查,所以请确保要反序列化的类型有默认构造器同时序列化工具打开了autoType的支持,否则反序列化会出现异常com.alibaba.fastjson.JSONException: autoType is not support。

  • RedisConfig 配置自定义的序列化工具类
   /**
     * Description: <br>
     * 
     * @author xubin<br>
     * @taskId <br>
     * @param factory 工厂对象
     * @return <br>
     */
    @Bean
    public RedisTemplate<String, MqttPacketCache> packetRedisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, MqttPacketCache> redisTemplate = new RedisTemplate<>();
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(new FastJsonRedisSerializer<>(MqttPacketCache.class));
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(new FastJsonRedisSerializer<>(MqttPacketCache.class));
        return redisTemplate;
    }

转载于:https://my.oschina.net/u/872813/blog/3052565

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 Fastjson 序列化 Redis 的数据,需要在 Redis配置文件中设置序列化器的类型为 FastjsonSerializer。具体步骤如下: 1. 在 Redis配置文件 redis.conf 中,找到 `# requirepass foobared` 这一行,并将其前面的注释符号 # 去掉,设置 Redis 的密码为 foobared。这样可以提高 Redis 的安全性,避免被未经授权的用户访问。 2. 在 Redis配置文件 redis.conf 中,找到 `# bind 127.0.0.1` 这一行,并将其前面的注释符号 # 去掉,设置 Redis 只能被本地访问。这样可以避免 Redis 被未经授权的用户远程访问。 3. 在 Redis配置文件 redis.conf 中,找到 `# maxmemory <bytes>` 这一行,并将其前面的注释符号 # 去掉,设置 Redis 最大使用内存的限制。例如,设置为 1GB 的命令如下: ``` maxmemory 1gb ``` 4. 在 Redis配置文件 redis.conf 中,找到 `# appendonly no` 这一行,并将其前面的注释符号 # 去掉,启用 Redis 的 AOF (Append Only File) 持久化功能。这样可以确保 Redis 在宕机或异常退出时,数据不会丢失。 5. 在 Redis配置文件 redis.conf 中,找到 `# requirepass foobared` 这一行下面,添加以下配置: ``` # 开启 Fastjson 序列化器 # Redis 默认使用的是 JdkSerializationRedisSerializer 序列化器,但它的效率较低,不适用于大规模数据存储 # Fastjson 是一个高性能的 Java 序列化库,它能够快速地将 Java 对象转换为 JSON 字符串,并且反序列化也很快 # FastjsonSerializer 是 Redisson 提供的一个 Fastjson 序列化器 # 需要添加 Redisson 的依赖 # https://github.com/redisson/redisson/wiki/Redisson%E9%85%8D%E7%BD%AE#15-%E5%BA%8F%E5%88%97%E5%8C%96 # fastjson序列化比较快,但是反序列化会有一定的风险,需要根据自己的业务场景进行评估 # 详细说明可以参考 http://docs.redisson.org/en/latest/codec/FastjsonCodec/ codec: org.redisson.codec.FastjsonCodec ``` 6. 保存并关闭 Redis配置文件 redis.conf。 7. 重启 Redis 服务,让配置文件的修改生效。可以使用以下命令重启 Redis: ``` redis-cli shutdown redis-server /path/to/redis.conf ``` 其中,`/path/to/redis.conf` 表示 Redis 配置文件的路径。如果 Redis配置文件在默认路径 `/etc/redis/redis.conf` 下,可以直接使用以下命令重启 Redis: ``` redis-cli shutdown redis-server ``` 重启后,就可以使用 Fastjson 序列化 Redis 的数据了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值