springboot整合redis,实现共享session

最近在springboot里整合redis来做缓存的时候,踩了很多坑啊,哎,前前后后折腾了两个晚上的时间。在这记录一下,以免下次又踩坑。
pom.xml:


		
			redis.clients
			jedis
		
		
		
			org.apache.commons
			commons-pool2
			2.5.0
		

properties文件配置;

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

config类:

package com.xiangzhang.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * redis配置类
 *
 * @author jie ON 2019/3/14
 **/
@Configuration
@EnableCaching
public class RedisConfig {
    @Bean
    /**
     * 如使用注解的话需要配置cacheManager
     */
    CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
        //设置默认超过期时间是1天
        defaultCacheConfig.entryTtl(Duration.ofDays(1));
        //初始化RedisCacheManager
        RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
        return cacheManager;
    }

    /**
     * 以下两种redisTemplate自由根据场景选择
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
        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);

        template.setValueSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }
}

bean类:

package com.xiangzhang.entity;

import com.gitee.sunchenbin.mybatis.actable.annotation.Column;
import com.gitee.sunchenbin.mybatis.actable.annotation.Table;
import com.gitee.sunchenbin.mybatis.actable.command.BaseModel;
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author 熊义杰
 * @date 2019-3-2
 */

@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "hero")
public class User extends BaseModel {
    /**
     * 属性上的注解定义了创建表时的各个字段的属性
     */
    @Column(name = "id",type = MySqlTypeConstant.INT,length = 11,isKey = true,isAutoIncrement = true)

    private int id;

    @Column(name = "name",type = MySqlTypeConstant.VARCHAR,length = 111)

    private String name;

    @Column(name = "hp",type = MySqlTypeConstant.DOUBLE,length = 16,decimalLength = 2)

    private double hp;

    @Column(name = "damage",type = MySqlTypeConstant.DOUBLE,length = 16,decimalLength = 2)

    private double damage;
}

测试类:

package com.xiangzhang;

import com.xiangzhang.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;


@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
	private static final Logger log = LoggerFactory.getLogger(DemoApplicationTests.class);
	@Autowired
	RedisTemplate redisTemplate;

	@Test
	public void get(){

		String key = "balabala";
		redisTemplate.opsForValue().set(key,"lalala");
		final String k2 = (String)redisTemplate.opsForValue().get(key);
		log.info("[自定义的字符缓存结果] - [{}]",k2);

		redisTemplate.opsForValue().set(key,new User(11,"李白",123,485));
		final User user = (User)redisTemplate.opsForValue().get(key);
		log.info("[自定义的对象缓存结果] - [{}]",user);
	}
}

在这里有几个要注意的问题是,运行前必须在本地或者你的服务器上打开redis的服务端,不然会一直报错连接不上,我之前还一直以为是密码配置的问题。。

下面给上共享session的配置:
pom.xml:


		
			org.springframework.session
			spring-session-data-redis
		
		
			nl.bitwalker
			UserAgentUtils
			1.2.4
		
		
			commons-codec
			commons-codec
			1.6
		

config类:

package com.xiangzhang.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * @author 熊义杰
 * @date 2019/3/14
 */

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
public class SessionConfig {
}

测试controller类:

package com.xiangzhang.controller;

import com.xiangzhang.entity.User;
import com.xiangzhang.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * @author 熊义杰
 * @date 2019/3/14
 */

@Controller
@RequestMapping
public class UserRedisController {

    @Autowired
    UserMapper userMapper;

    @GetMapping(value = "/user")
    public List getAllUser() {
        return this.userMapper.returnResult();
    }

    @GetMapping(value = "/user/{id}")
    @Cacheable(value = "user-key")
    public User getUserById(@PathVariable("id") int id) {
        return userMapper.returnById(id);
    }

    @RequestMapping(value = "/test/cookie")
    public String getCookie(@RequestParam("token") String token, HttpServletRequest request, HttpSession session){
        Object sesssionToken = session.getAttribute("token");
        if(sesssionToken == null){
            System.out.println("不存在session,设置session = " + token);
            session.setAttribute("token",token);
        }else {
            System.out.println("存在session = " + sesssionToken.toString());
        }
        Cookie[] cookies = request.getCookies();
        if(cookies != null && cookies.length > 0){
            for(Cookie cookie : cookies){
                System.out.println(cookie.getName() + ":" + cookie.getValue());
            }
        }
        return "footer";
    }
}

你可能感兴趣的:(redis,springboot)