springboot 集成redis 和http请求

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;
    }
}


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容