SpringBoot配置RedisTemplate使⽤FastJson进⾏序列化
⽂章⽬录
前⾔
在我们项⽬进⾏开发时,不可避免的会使⽤到Redis,Spring官⽅给我们提供了RedisTemplate这个类,它替我们封装提供了Redis基本上全部的常⽤操作。⽽官⽅默认使⽤的序列化⽅式为Sdk提供的序列化类。下⾯讲如何替换SpringBoot默认序列化⽅式,并解决⼀些问题
依赖版本
SpringBoot版本:2.2.6
SpringBoot-redis-starter版本:2.2.6
FastJson版本:1.2.68
JDK:1.8
⾃定义序列化⽅式
1. 我们在使⽤官⽅提供的``FastJsonRedisSerializer`时,从Redis取回的数据,为JSONObject或JSONArray类型,需要⼿动转换成
⾃⼰需要的实体。
2. 官⽅还提供了另外⼀个GenericFastJsonRedisSerializer序列化⼯具,这个类会根据我们的实体类型,从Redis取回的数据,⾃动反序列
化为相应的实体对象。但是不知道是不是FastJson版本问题,就算GenericFastJsonRedisSerializer源码⾥已经设置过AutoType为True 但是在实际使⽤过程中,反序列化⼀些集合类型的数据时还是会出现autoType is not support.的异常导致序列化失败
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.dis.serializer.RedisSerializer;
import org.dis.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);}// 这⾥设置AutoType为True解决序列化失败autoType is not support的问题
public byte[]serialize(Object object)throws SerializationException {
if(object == null){
return new byte[0];
}
try{
JSONBytes(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;
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);
}
}
}
3. ⾃定义序列化类:FastJsonRedisSerializer
在Debug过程中,发现在反序列化时报了异常并且反序列化失败,但是如果在其失败后再次进⾏反序列化就可以正常进⾏反序列化操作了,所以采⽤了⼀个笨⽅法来解决这个问题,就是在反序列化时加⼊⼀次重试操作。
源码:
f;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.dis.serializer.RedisSerializer;
import org.dis.serializer.SerializationException;
import java.nio.charset.Charset;
import java.util.HashMap;
/**
* <p>
* FastJson序列化
* </p>
*
* @author yangxiaohui
* @since 2020/5/18
*/
public class FastJsonRedisSerializer<T>implements RedisSerializer<T>{
/**
* 解决反序列化时Could not deserialize: autoType is not support. 的问题
*/
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;
public FastJsonRedisSerializer(Class<T> clazz){
super();
this.clazz = clazz;
}
/**
* 序列化
*
* @param t 对象
* @return 字节码
* @throws SerializationException 序列化异常
*/
@Override
@Override
public byte[]serialize(T t)throws SerializationException {
if(t == null){
return new byte[0];
}
JSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
/
**
* 反序列化
*
* @param bytes 字节码
* @return 对象
*/
@Override
public T deserialize(byte[] bytes)throws SerializationException {
if(bytes == null || bytes.length <=0){
return null;
}
String str =new String(bytes, DEFAULT_CHARSET);
try{
return(T) JSON.parseObject(str, clazz, defaultRedisConfig);
}catch(Exception e){
// 如果报错,再次反序列化并返回
return(T) JSON.parseObject(str, clazz, defaultRedisConfig);
}
}
}
4. 新建RedisConf配置类 :
f;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.dition.ConditionalOnMissingBean;
import org.springframework.boot.dis.RedisAutoConfiguration;
import org.springframework.boot.dis.RedisProperties;
import org.t.properties.EnableConfigurationProperties;
import t.annotation.Bean;
import t.annotation.Configuration;
import org.springframework.dao.DataAccessException;
import org.tion.*;
import org.tion.jedis.JedisConnectionFactory;
import org.RedisTemplate;
import org.StringRedisTemplate;
import org.dis.serializer.StringRedisSerializer;
import java.UnknownHostException;
/**
* <p>
*  Redis配置
* </p>
*
* @author yangxiaohui
* @since 2020/5/7
*/
@SuppressWarnings("all")
@Configuration
public class RedisConf {
@Bean
public RedisTemplate<String, Object>redisTemplate(RedisConnectionFactory redisConnectionFactory){        RedisTemplate<String, Object> template =new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
FastJsonRedisSerializer serializer =new FastJsonRedisSerializer(Object.class);fastjson怎么用
// value值的序列化采⽤fastJsonRedisSerializer
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
// key的序列化采⽤StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
template.afterPropertiesSet();
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
StringRedisTemplate template =new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
注:
因为在反序列化时,做了⼀层重试的操作,所以对性能会有⼀些影响,肯定不是最优解。如果有⼤佬知道能怎么更有效率的解决该问题,还希望能够留⾔⽀持。谢谢

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。