Java开发工具

注入RedisTemplate

2019-11-29  本文已影响0人  墨色尘埃

第一步:

image.png

第二步:

image.png

第三步:RedisHttpSessionConfiguration类中注入了 RedisTemplate

image.png

第三步里,只设置了key的序列化方式,没有设置value的序列化方式,所以如果value是一个对象,且没有实现Serializable接口的话,存到redis里会报错。所以使用默认的序列化方式的话,对象必须实现Serializable接口

org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to 

serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type 

[com.cicdi.servertemplate.modules.vote.model.VoteSubjectHoptTotalVoteNum]
        at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:93)
        at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:171)
        at org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:129)
        at com.cicdi.servertemplate.common.util.RedisUtil.hmset(RedisUtil.java:293)

    ....................省略....................

        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Unknown Source)

Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is 
java.lang.IllegalArgumentException: Default Serializer requires a Serializable payload but received an object of type [com.cicdi.servertemplate.modules.vote.model.VoteSubjectHoptTotalVoteNum]
        at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:68)
        at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35)
        at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:91)
        ... 135 more
Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type 

[com.cicdi.servertemplate.modules.vote.model.VoteSubjectHoptTotalVoteNum]
        at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:43)
        at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:63)
        ... 137 more

第四步:自定义配置类RedisConfig中再次注入RedisTemplate,这里的 RedisTemplate 经过了个性化设置,设置其key是string类型、value是json串,这样存到redis里的时候就不会报错了。

image.png

如果不重新注入 RedisTemplate 自定义配置,存到redis里的key是乱码的,但是RedisHttpSessionConfiguration类中注入的 RedisTemplate 其实已经设置了key为string类型的,为什么用默认的就会乱码呢??

image.png

配置类:

@Configuration + @Bean 相当于重新注入类,所以断点会进到这里来

完整配置类:

@Configuration
public class RedisConfig {

    @Value("${spring.redis.password}")
    public String password;
    @Value("${spring.redis.host}")
    public String host;


    // *****************************上**********************************

    @Bean
    public CachingConfigurerSupport keyGenerator() {
        return new MyCachingConfigurerSupport();
    }

    public class MyCachingConfigurerSupport extends CachingConfigurerSupport {
        @Override
        public KeyGenerator keyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(target.getClass().getName());
                    sb.append(method.getName());
                    for (Object obj : params) {
                        sb.append(obj.toString());
                    }
                    return sb.toString();
                }
            };
        }
    }

    // TODO: 2019/9/6 SpringCacheRoleHierarchy和SpringCacheModuleSecurity存储的缓存还是乱码
//    //缓存管理器
//    @SuppressWarnings("rawtypes")
//    @Bean
//    public CacheManager cacheManager(StringRedisTemplate redisTemplate) {
//        RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
//        //设置缓存过期时间
//        rcm.setDefaultExpiration(1800);//秒
//        return rcm;
//    }

   // *******************************下********************************


    /**
     * 存入对象tostring后的信息
     * 修改默认序列化方式
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
//        template.setConnectionFactory(jedisConnectionFactory());
        template.setConnectionFactory(connectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);

        // hash的key也采用String的序列化方式,需要配置一下StringSerializer,不然key会乱码 /XX/XX
        template.setHashKeySerializer(stringRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }

//    /**
//     * 使用SpringSession里的 @EnableRedisHttpSession(redisNamespace = "jscmp") 注解
//     * 该注解开启了redis连接
//     */
//    @Bean
//    JedisConnectionFactory jedisConnectionFactory() {
//        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
//        jedisConnectionFactory.setHostName(host);
//        jedisConnectionFactory.setPassword(password);
//        return jedisConnectionFactory;
//    }


    /**
     *  解决redis集群环境没有开启Keyspace notifications导致的
     *
     *  Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource
     *
     * */
    @Bean
    public static ConfigureRedisAction configureRedisAction() {
        return ConfigureRedisAction.NO_OP;
    }
}
上一篇下一篇

猜你喜欢

热点阅读