美文网首页
springboot 集成redis 和http请求

springboot 集成redis 和http请求

作者: Helen_Cat | 来源:发表于2018-12-12 14:13 被阅读225次

    springboot 集成redis ,使用原生的jedis ,有点繁琐,本身springboot 已经集成了 redis并有 redisTemplate 可以使用,不过还是多少有点坑,需要提前说明的
    首先要引入jar包依赖

        <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
    

    然后在 application 配置文件中 配置redis 的连接项

    spring.redis.database=0
    spring.redis.host= 10.201.9.23
    
    spring.redis.port=6379
    spring.redis.password=88888
    spring.redis.auth=88888
    spring.redis.pool.max-active=8
    spring.redis.pool.max-wait=-1
    spring.redis.pool.max-idle=8
    spring.redis.pool.min-idle=0
    spring.redis.timeout=5000
    
    

    接着最简单的使用就是

       @Autowired
        protected RedisTemplate<Object ,Object>  redisTemplate;
    
    

    或者

        @Autowired
      protected StringRedisTemplate redisTemplate;
    
    

    如果你配置环境对的话,redis 就可以使用了
    springboot 在启动会自己初始化 RedisConnectionFactory redisConnectionFactory
    这个对象,然后注入 ,并初始化化一个 RedisTemplate 对象,这样感觉无缝连接到redis了,但是吧,平时没问题,一旦时间久了就会出问题,就是redis 的序列化和反序列化问题,之前没有在log 里捕捉 这个反序列化的异常,后来捕捉到这个异常,

    ERROR] 2018-03-07 14:05:03,747 XXX - Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.StreamCorruptedException: invalid stream header: 6E756C6C
    --------------------- 
    作者:竹子鸠 
    来源:CSDN 
    原文:https://blog.csdn.net/yexiaojiu1/article/details/79470439 
    版权声明:本文为博主原创文章,转载请附上博文链接!
    
    

    springboot在反序列话 redis,有点bug
    如何破解 ,就是在初始化 RedisTemplate 这个bean 的时候就配置一下序列化和反序列化的属性,
    声明一个 RedisService 公共类,并加 @Component 注解, 在这个里面初始化化 RedisTemplate,需要注意的是 就是你的key 对应的value存的是什么类型,如果是String
    ,就用new StringRedisSerializer(),如果是对象类 json ,就使用
    new Jackson2JsonRedisSerializer(Object.class);或者
    new GenericJackson2JsonRedisSerializer()),不然这个还会报错,
    然后我们在这个里面 声明 get set exist remove redis key 的操作

    最后使用 redis 的时候 ,直接注入 RedisService 就可以了

      @Autowired
      private RedisService redisService;
    

    RedisService

    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.core.*;
    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Service;
    
    import java.io.Serializable;
    import java.util.List;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    
    @Component
    public class RedisService {
    
    
    
    
        protected  final Logger logger=LoggerFactory.getLogger(RedisService.class);
    
    //    @Autowired
    //    protected   RedisConnectionFactory redisConnectionFactory;
    
        @Bean
        public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory)  {
            //RedisTemplate<String, String>
            logger.info("尝试初始化redis template");
            RedisTemplate<Object ,Object>  redisTemplate= new RedisTemplate<>();
            redisTemplate.setConnectionFactory(redisConnectionFactory);
    
    
            //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
            Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
    
            ObjectMapper mapper = new ObjectMapper();
            mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            serializer.setObjectMapper(mapper);
    
    
            //使用StringRedisSerializer来序列化和反序列化redis的key值
            redisTemplate.setKeySerializer(new StringRedisSerializer());
    //        redisTemplate.setValueSerializer(serializer);
            redisTemplate.setStringSerializer(new StringRedisSerializer());
           redisTemplate.setValueSerializer(new StringRedisSerializer());
    //        redisTemplate.setEnableDefaultSerializer(true);
           // redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    
            redisTemplate.setHashKeySerializer(new StringRedisSerializer());
            redisTemplate.setHashValueSerializer(serializer);
    
            redisTemplate.afterPropertiesSet();
    
            logger.info("redis init successful 初始化成功");
            this.redisTemplate=redisTemplate;
       
    
            return this.redisTemplate;
        }
    
        @Autowired
        protected RedisTemplate<Object ,Object>  redisTemplate;
        /**
         * 写入redis缓存(不设置expire存活时间)
         * @param key
         * @param value
         * @return
         */
        public boolean set(final String key, String value){
            boolean result = false;
            try {
                logger.info("正在insert设置  "+key+"的redis 值"+value);
                ValueOperations operations =redisTemplate.opsForValue();
                operations.set(key, value);
                result = true;
                logger.info(key+" 插入redis 成功 "+value);
            } catch (Exception e) {
                logger.error("写入redis缓存失败!错误信息为:" + e.getMessage());
            }
            return result;
        }
    
        /**
         * 写入redis缓存(设置expire存活时间)
         * @param key
         * @param value
         * @param expire
         * @return
         */
        public boolean set(final String key, String value, Long expire){
            boolean result = false;
            try {
                logger.info("正在设置  "+key+"的redis 值"+value+" expire "+expire);
    
                ValueOperations operations = redisTemplate.opsForValue();
                operations.set(key, value);
                redisTemplate.expire(key, expire, TimeUnit.SECONDS);
                result = true;
                logger.info(key+" 插入redis 成功 "+value);
            } catch (Exception e) {
                logger.error("写入redis缓存(设置expire存活时间)失败!错误信息为:" + e.getMessage());
            }
            return result;
        }
    
    
        /**
         * 读取redis缓存
         * @param key
         * @return
         */
        public Object get(final String key){
            Object result = null;
            try {
                logger.info("正在尝试获取 "+key+"的redis 值");
                ValueOperations operations = redisTemplate.opsForValue();
                result = operations.get(key);
                logger.info("get 得到  "+key+"的redis 值"+result);
            } catch (Exception e) {
    
                logger.error("读取redis缓存失败!错误信息为:" + e.getMessage());
                String connect=redisTemplate.getConnectionFactory().getConnection().toString();
                logger.error(connect);
            }
            return result;
        }
    
        /**
         * 判断redis缓存中是否有对应的key
         * @param key
         * @return
         */
        public boolean exists(final String key){
            boolean result = false;
            try {
                logger.info("正在查看  "+key+"的redis 值 是否存在");
                result = redisTemplate.hasKey(key);
                logger.info("查看  "+key+"的redis 值 存在 结果 "+result);
            } catch (Exception e) {
                logger.error("判断redis缓存中是否有对应的key失败!错误信息为:" + e.getMessage());
            }
            return result;
        }
    
        /**
         * redis根据key删除对应的value
         * @param key
         * @return
         */
        public boolean remove(final String key){
            boolean result = false;
            try {
                if(exists(key)){
                    logger.info("移除  "+key+"的redis 值");
                    redisTemplate.delete(key);
                }
                result = true;
            } catch (Exception e) {
                logger.error("redis根据key删除对应的value失败!错误信息为:" + e.getMessage());
            }
            return result;
        }
    
        /**
         * redis根据keys批量删除对应的value
         * @param keys
         * @return
         */
        public void remove(final String... keys){
            for(String key : keys){
                remove(key);
                logger.info("remove redis key "+key);
            }
        }
    }
    
    }
    
    

    另外 springboot 请求外部http的时候使用 RestTemplate 也有一个坑,就是默认的request buffer不释放,导致时间越久,请求头巨大,最后 就无法请求外部了,所以 可以这样使用

    
    
    import com.fasterxml.jackson.databind.SerializationFeature;
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    import org.springframework.http.client.SimpleClientHttpRequestFactory;
    import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
    import org.springframework.web.client.RestTemplate;
    @Component
    public class RestHttpConfig {
    
    
      @Bean
        public  RestTemplate restTemplate(){
    
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
            factory.setBufferRequestBody(false);
            RestTemplate restTemplate = new RestTemplate(factory);
            MappingJackson2HttpMessageConverter jsonHttpMessageConverter = new MappingJackson2HttpMessageConverter();        jsonHttpMessageConverter.getObjectMapper().configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            restTemplate.getMessageConverters().add(jsonHttpMessageConverter);
    
            return  restTemplate;
        }
    }
    
    
    

    相关文章

      网友评论

          本文标题:springboot 集成redis 和http请求

          本文链接:https://www.haomeiwen.com/subject/xzwuhqtx.html