SpringBoot2.x整合Redis使用FastJson序列化

与Redis相关知识可查看《Redis系列记录》

(十五)Springboot缓存

一、相关配置

1.1 pom.xml

<!-- spring-boot-starter-data-redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <!-- 连接池 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <!-- fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>

1.2 application.properties

spring.cache.type=redis
# Redis数据库索引(默认为0)
spring.redis.database=0  
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379  
# Redis服务器连接密码(默认为空)
#spring.redis.password=123456
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.max-active=200  
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.lettuce.max-wait=-1  
# 连接池中的最大空闲连接
spring.redis.lettuce.max-idle=10 
# 连接池中的最小空闲连接
spring.redis.lettuce.min-idle=0  
# 连接超时时间(毫秒)
spring.redis.timeout=1000ms

logging.level.com.example.redisdemo=debug

1.3 RedisConfig

@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    public RedisSerializer fastJson2JsonRedisSerialize(){
        return new FastJson2JsonRedisSerialize<Object>(Object.class);
    }

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory,RedisSerializer fastJson2JsonRedisSerialize){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置Key的序列化采用StringRedisSerializer
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        //设置值的序列化采用FastJsonRedisSerializer
        redisTemplate.setValueSerializer(fastJson2JsonRedisSerialize);
        redisTemplate.setHashValueSerializer(fastJson2JsonRedisSerialize);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        // 生成一个默认配置,通过config对象即可对缓存进行自定义配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        // 设置缓存的默认过期时间,也是使用Duration设置
        config = config.entryTtl(Duration.ofMinutes(5))
                // 设置 key为string序列化
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                // 设置value为fastJson序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJson2JsonRedisSerialize()))
                // 不缓存空值
                .disableCachingNullValues();
        // 使用自定义的缓存配置初始化一个cacheManager
        return RedisCacheManager
                .builder(redisConnectionFactory)
                .cacheDefaults(config)
                .transactionAware()
                .build();
    }
}

1.4  FastJson2JsonRedisSerialize

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

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class<T> clazz;

    static {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        //如果遇到反序列化autoType is not support错误,请添加并修改一下包名到bean文件路径
        //ParserConfig.getGlobalInstance().addAccept("com.example.redisdemo.domain");
    }

    public FastJson2JsonRedisSerialize(Class clazz){
        super();
        this.clazz = clazz;
    }


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

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

二、测试

2.1 User

public class User implements Serializable {

    private static final long serialVersionUID = 8391377903506428591L;
    private Integer id;

    private String username;

    private String password;

    public User(){
        super();
    }

    public User(Integer id, String username, String password){
        this.id = id;
        this.username = username;
        this.password = password;
    }
   getter... setter... toString()...
}

2.2 UserService   UserServiceImpl

public interface UserService {

    public User addUser(User user);

    public User getUser(Integer id);

    public void delUser(Integer id);
}

 这里不用Mapper了,使用Map来模拟一下数据库操作,

@CacheConfig(cacheNames = "user")
@Service("userService")
public class UserServiceImpl implements UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    private static final Map<String,Object> usersMap = new HashMap<>();

    @Override
    @CachePut(key = "#user.id")
    public User addUser(User user) {
        usersMap.put(user.getId().toString(),user);
        logger.info("存入数据库【User】= {}",user);
        return user;
    }

    @Override
    @Cacheable(key = "#id",unless = "#result == null ")
    public User getUser(Integer id){
        User user = (User) usersMap.get(id.toString());
        logger.info("从数据库获取【User】= {}",user);
        return user;
    }

    @Override
    @CacheEvict(key = "#id")
    public void delUser(Integer id) {
        usersMap.remove(id.toString());
        logger.info("从数据库删除【User】");
    }
}

2.3 Test

    @Test
    void testOne() {
         userService.addUser(new User(1,"aa","123"));
         User user = userService.getUser(1);
         logger.debug("【User】={}",user);
    }

2.4 结果

 这里可以看到只打印了添加日志和最后的查询结果,并没有打印查询日志,所以证明缓存生效。

三、相关知识点与坑

3.1 报com.alibaba.fastjson.JSONException: autoType is not support

解决方法:在FastJson2JsonRedisSerialize 类中添加   这两句代码都可以解决反序列化问题

  static {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        //如果遇到反序列化autoType is not support错误,请添加并修改一下包名到bean文件路径
        //ParserConfig.getGlobalInstance().addAccept("com.example.redisdemo.domain");
    }

3.2 Cache 'redisCache' does not allow 'null' values

解决方法:添加unless = "#result == null"

 @Cacheable(key = "#id",unless = "#result == null ")

缓存相关注解可查看第(十五)篇:Springboot缓存


四、RedisTemplate

上文中使用注解来完成缓存操作,下文中使用redisTemplate来操作缓存

在测试类中添加: 

@Resource(name = "redisTemplate")
    private ValueOperations<String,Object> vo;

  @Test
    void testFour(){
        vo.set("java",new User(1,"bb","111"));
        User user = (User) vo.get("java");
        System.out.println(user);
    }

 执行: 也是好用的

 那么为什么redisTemplate可以直接注入给五种数据类型的XXOperations使用呢?原来有属性编辑器

 

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
要在Redis使用fastjson进行序列化配置,您需要按照以下步骤执行: 1. 添加fastjson依赖:将fastjson库添加到您的项目中,可以通过在Maven项目的pom.xml文件中添加以下依赖来完成: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency> ``` 2. 创建FastJsonRedisSerializer类:创建一个实现了RedisSerializer接口的FastJsonRedisSerializer类。这个类将负责将Java对象序列化为JSON字符串,并将JSON字符串反序列化回Java对象。 ```java import com.alibaba.fastjson.JSON; import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.SerializationException; public class FastJsonRedisSerializer<T> implements RedisSerializer<T> { private Class<T> clazz; public FastJsonRedisSerializer(Class<T> clazz) { this.clazz = clazz; } @Override public byte[] serialize(T t) throws SerializationException { if (t == null) { return new byte[0]; } return JSON.toJSONBytes(t); } @Override public T deserialize(byte[] bytes) throws SerializationException { if (bytes == null || bytes.length <= 0) { return null; } return JSON.parseObject(bytes, clazz); } } ``` 3. 配置RedisTemplate:在您的配置文件中配置RedisTemplate,并将FastJsonRedisSerializer设置为Redis的默认序列化器。 ```java import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); // 设置key的序列化器 template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); // 设置value序列化器 template.setValueSerializer(new FastJsonRedisSerializer<>(Object.class)); template.setHashValueSerializer(new FastJsonRedisSerializer<>(Object.class)); return template; } } ``` 通过以上步骤配置好RedisTemplate后,您就可以在Spring Boot项目中使用fastjson进行Redis序列化了。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoneWalker、

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值