Spring Session 共享

HttpSession是通过servlet容器创建的,保存在tomcat等容器内存中。但是分布式集群的应用中,利用nginx做负载,同一个请求可能会被分配到不同的容器中,那么如何保证不同容器之间session的共享呢?spring为我们提供了解决方法。就是通过filter封装HttpServletRequestWrapper,重写getSession(),将session放到redis或者Memcached,取的时候从redis/memcached中取。其实就是把session放到一个公共地方,这样不同的容器就都可以使用同一个session了。

实现例子:

1. 架包:

   <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    
    <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.5.2</version>
	</dependency>  
	<dependency>  
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.1.7.RELEASE</version>
	</dependency>  
	<dependency>  
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.1.7.RELEASE</version>
	</dependency>
	<dependency>  
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.1.7.RELEASE</version>
	</dependency>
	<dependency>  
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.1.7.RELEASE</version>
	</dependency>
	<dependency>  
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.1.7.RELEASE</version>
	</dependency>
	<dependency>  
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.1.7.RELEASE</version>
	</dependency>
	<dependency>  
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.1.7.RELEASE</version>
	</dependency>
	<dependency>  
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
	</dependency>


我是把spring-mvc的架包全部拿过来了。其中spring-session-data-redis就是spring将session放入redis的架包,还需要java.servlet-api 因为会用到HttpServlet等类,scope还要设置成provided,因为等等部署到tomcat中会和tomcat的javax架包冲突,不知道的请移步SCOPE

2. web.xml

  <!-- 封装session的filter -->
  <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>
  
  <!-- spring配置 -->
  <context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath*:applicationContext.xml</param-value>
  </context-param>
  
  <listener>  
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  </listener>  
  
  
  <!-- servlet -->
  <servlet>
      <servlet-name>loginServlet</servlet-name>
      <servlet-class>com.tang.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>loginServlet</servlet-name>
      <url-pattern>/action/login</url-pattern>
  </servlet-mapping>
  
  <servlet>
      <servlet-name>indexServlet</servlet-name>
      <servlet-class>com.tang.servlet.IndexServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>indexServlet</servlet-name>
      <url-pattern>/action/index</url-pattern>
  </servlet-mapping>
第一个filter放最前面,因为这个filter是是实现session存入redis的

3. appicationContext.xml

    <context:component-scan base-package="com.tang" />

    
	<bean id="redisHttpSessionConfiguration"
	      class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
	    <property name="maxInactiveIntervalInSeconds" value="1800"/>
	</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="127.0.0.1"/>
	    <property name="port" value="6379"/>
	    <property name="timeout" value="3000"/>
	    <property name="usePool" value="true"/>
	    <property name="poolConfig" ref="jedisPoolConfig"/>
	</bean>
第一个bean就是实现session放入redis,maxInactiveIntervalInSeconds超时时间,默认1800,下面几个bean是redis的一些基本配置。


4. Servlet

LoginServlet:

public class LoginServlet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 设置session
		// 将session放入redis中
		req.getSession().setAttribute("mysession", "tangxw");
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doGet(req, resp);
	}
	
}

IndexServlet:


public class IndexServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 从redis中取出session
		String mysession = (String) req.getSession().getAttribute("mysession");
		System.out.println("mysession = " + mysession);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doGet(req, resp);
	}
}
5. 测试

mvn package打包项目,把war放到tomcat下,启动redis,启动tomcat,访问:http://localhost:8082/action/login,建立session,放入redis中。我们看一下redis中的有没有放session。


可以看到redis中已经保存了我们的session了。

然后我们将maven打包的war放到另一台tomcat中,启动tomcat,访问:http://localhost:8081/action/index,可以发现能打印session(mysession) 的值,说明session确实共享了。


以上就是通过spring-session-data-redis来实现session共享。

参考文章:http://blog.csdn.net/patrickyoung6625/article/details/45694157

                 https://www.cnblogs.com/youzhibing/p/7348337.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值