redis实现session共享

一、spring+redis+session

1、添加依赖

<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
  <version>1.2.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.1</version>
</dependency>

2、配置

spring-mvc.xml:

<bean id="redisHttpSessionConfiguration"
      class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
    <property name="maxInactiveIntervalInSeconds" value="600"/>
</bean>

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxTotal" value="100" />
    <property name="maxIdle" value="10" />
</bean>

<bean id="jedisConnectionFactory"
      class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
    <property name="hostName" value="${redis_hostname}"/>
    <property name="port" value="${redis_port}"/>
    <property name="password" value="${redis_pwd}" />
    <property name="timeout" value="3000"/>
    <property name="usePool" value="true"/>
    <property name="poolConfig" ref="jedisPoolConfig"/>
</bean>

web.xml添加拦截器:

<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3、使用spring-session

只要使用标准的servlet api调用session,在底层就会通过Spring Session得到的,并且会存储到Redis或其他你所选择的数据源中。

这里是我写的一个demo:

/**

 */
@Controller
@RequestMapping(value = "index")
public class IndexController {

    private final Gson gson = new GsonBuilder().setDateFormat("yyyyMMddHHmmss").create();

    @RequestMapping(value = "login")
    public String login(HttpServletRequest request, String username){

        request.getSession().setAttribute("user", gson.toJson(new User(username,"123456")));

        return "login";
    }

    @RequestMapping(value = "index")
    public String index(HttpServletRequest request, Model model){

        User user = gson.fromJson(request.getSession().getAttribute("user").toString(), User.class);

        model.addAttribute("user", user);

        return "index";
    }
}

index.jsp:

第一个tomcat

<html>
<body>
<h2>Hello World!</h2>
<p>${user.username}</p>
</body>
</html>

第二个tomcat

<html>
<body>
<h2>Hello World! i am the second!</h2>
<p>${user.username}</p>
</body>
</html>

测试

这里利用上一篇nginx负载配置的两个tomcat来测试。
首先访问 http://192.168.99.100/feng/index/login.htm?username=nginx 来触发生成session。

查看redis,发现session已经保存到redis。

访问 http://192.168.99.100/feng/index/index.htm 来读取session, 并刷新多次。

发现在负载的情况下读取session没问题,并且是同一个session,成功实现负载+session共享!

二、springboot+redis+session

1:导包:

  1. <parent>

  2. <groupId>org.springframework.boot</groupId>

  3. <artifactId>spring-boot-starter-parent</artifactId>

  4. <version>2.0.2.RELEASE</version>

  5.     </parent>

  6.     <dependencies>

  7.         <dependency>

  8.             <groupId>org.springframework.boot</groupId>

  9.             <artifactId>spring-boot-starter-web</artifactId>

  10.         </dependency>

  11.         <dependency>

  12.             <groupId>org.springframework.session</groupId>

  13.             <artifactId>spring-session-data-redis</artifactId>

  14.         </dependency>

  15.         <dependency>

  16.             <groupId>org.springframework.boot</groupId>

  17.             <artifactId>spring-boot-starter-data-redis</artifactId>

  18.         </dependency>

  19.     </dependencies>

2:配置redis信息, 并开启redis(在这里我是根据我自己的电脑配置的):

 
  1. spring.redis.host=127.0.0.1

  2. spring.redis.port=6379

3:配置启动类:

 
  1. @SpringBootApplication

  2. @EnableRedisHttpSession(maxInactiveIntervalInSeconds= 3600) //spring在多长时间后强制使redis中的session失效,默认是1800.(单位/秒)

  3. public class DemoApplication {

  4.  
  5. public static void main(String[] args) {

  6. SpringApplication.run(DemoApplication.class, args);

  7. }

  8. }

4:写登录Controller测试: 成功!

 
  1. package com.example.demo.controller;

  2.  
  3. import com.example.demo.pojo.User;

  4. import com.example.demo.util.FoilResult;

  5. import org.springframework.stereotype.Controller;

  6. import org.springframework.web.bind.annotation.PostMapping;

  7. import org.springframework.web.bind.annotation.ResponseBody;

  8. import javax.servlet.http.HttpSession;

  9.  
  10. @Controller

  11. public class AgentController {

  12.  
  13. @PostMapping(value = "login")

  14. @ResponseBody

  15. public FoilResult login(HttpSession session) {

  16. System.out.println("===============登录成功===============");

  17. User user = new User();

  18. user.setName("luan");

  19. session.setAttribute("admin",user);

  20. return FoilResult.ok();

  21. }

  22.  
  23. @PostMapping(value = "logout")

  24. @ResponseBody

  25. public FoilResult logout(HttpSession session) {

  26. System.out.println("============退出系统=============");

  27. System.out.println(session.getId());

  28. session.removeAttribute("admin");

  29. session.invalidate();

  30. return FoilResult.ok();

  31. }

  32.  
  33. @PostMapping(value = "get")

  34. @ResponseBody

  35. public String get(HttpSession session) {

  36. User user = (User)session.getAttribute("admin");

  37. return user.getName();

  38. }

  39.  
  40. }

登录成功后,session就保存到到了redis中,可查看key值为spring:session:sessions进行查看.

退出后,redis中的session失效.

如果不自动退出,到了"过程3"中配置的@EnableRedisHttpSession(maxInactiveIntervalInSeconds= 3600) 时间后,redis中的session也会自动失效.

至此,就完成了reids共享session的效果!!!

 

注 : 在此过程中也可能会有一些版本坑的:

问题 : 启动报错:

 
  1. Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.

  2. 2018-05-23 16:01:50.573 ERROR 12308 --- [ main] o.s.boot.SpringApplication : Application run failed

  3.  
  4. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.getConfig(Ljava/lang/String;)Ljava/util/List;

  5. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  6. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:579) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  7. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  8. at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  9. at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  10. at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  11. at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  12. at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  13. at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  14. at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  15. at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]

  16. at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]

  17. at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]

  18. at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]

  19. at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]

  20. at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]

  21. at com.example.demo.DemoApplication.main(DemoApplication.java:14) [classes/:na]

  22. Caused by: java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.getConfig(Ljava/lang/String;)Ljava/util/List;

  23. at org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction.getNotifyOptions(ConfigureNotifyKeyspaceEventsAction.java:74) ~[spring-session-1.3.2.RELEASE.jar:na]

  24. at org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction.configure(ConfigureNotifyKeyspaceEventsAction.java:55) ~[spring-session-1.3.2.RELEASE.jar:na]

  25. at org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration$EnableRedisKeyspaceNotificationsInitializer.afterPropertiesSet(RedisHttpSessionConfiguration.java:251) ~[spring-session-1.3.2.RELEASE.jar:na]

  26. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1765) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  27. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1702) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

  28. ... 16 common frames omitted

可能原因 : spring-session-data-redis版本问题:(我的是这个原因!)

 
  1. <dependency>

  2. <groupId>org.springframework.session</groupId>

  3. <artifactId>spring-session-data-redis</artifactId>

  4. <version>1.3.2.RELEASE</version>

  5.  
  6. </dependency>

解决 : 版本改为2.0.3

 
  1. <dependency>

  2. <groupId>org.springframework.session</groupId>

  3. <artifactId>spring-session-data-redis</artifactId>

  4. <version>1.3.2.RELEASE</version>

  5.  
  6. </dependency>

注 : 这里可能会出现一个ajax跨域访问无法携带cookie的问题(我在这里出现了), 我的已经解决, 请参考:https://blog.csdn.net/luan666/article/details/80429869

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值