淘先锋技术网

首页 1 2 3 4 5 6 7

**

spring-session+Redis完成session共享

**

最近学习了spring-session完成session共享的配置,记录一下。

项目结构

在这里插入图片描述
1.pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>springsession</groupId>
  <artifactId>springsession</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    
    <dependency>
	    <groupId>taglibs</groupId>
	    <artifactId>standard</artifactId>
	    <version>1.1.2</version>
	</dependency>
    
    <dependency>
	    <groupId>javax.servlet.jsp.jstl</groupId>
	    <artifactId>jstl</artifactId>
	    <version>1.2</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
	<dependency>
	    <groupId>javax.servlet.jsp.jstl</groupId>
	    <artifactId>jstl-api</artifactId>
	    <version>1.2</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/org.glassfish.web/jstl-impl -->
	<dependency>
	    <groupId>org.glassfish.web</groupId>
	    <artifactId>jstl-impl</artifactId>
	    <version>1.2</version>
	</dependency>
    
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
        <version>1.3.1.RELEASE</version>
        <type>pom</type>
    </dependency>
    
    <dependency>
        <groupId>biz.paluch.redis</groupId>
        <artifactId>lettuce</artifactId>
        <version>3.5.0.Final</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.2.9.RELEASE</version>
    </dependency>
  </dependencies>
  
 
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

2.web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>springsession</display-name>
  
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath*:application-context.xml
        
    </param-value>
  </context-param>
  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!--DelegatingFilterProxy将查找一个Bean的名字springSessionRepositoryFilter丢给一个过滤器。为每个请求
  调用DelegatingFilterProxy, springSessionRepositoryFilter将被调用-->
  <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>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>
  
  
   <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

3.application-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <import resource="classpath:application-session.xml"/>
    
</beans>

4.application-session.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 加载properties文件 -->
    <bean id="configProperties"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:session-redis.properties</value>
            </list>
        </property>
    </bean>
    
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大空闲数 -->
        <property name="maxIdle" value="${redis.pool.maxIdle}" />
        <!-- 最小空闲数 -->
        <property name="minIdle" value="${redis.pool.minIdle}" />
        <!-- 控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive -->
        <property name="maxTotal" value="${redis.pool.maxTotal}" />
        <!-- 最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制 -->
        <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
        <!-- 连接的最小空闲时间 -->
        <property name="minEvictableIdleTimeMillis" value="${redis.pool.minEvictableIdleTimeMillis}"></property>
        <!-- 每次释放连接的最大数目,默认3 -->
        <property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}"></property>
        <!-- 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1 -->
        <property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}"></property>
        <!-- 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个 -->
        <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
        <property name="testOnReturn" value="${redis.pool.testOnReturn}" />
        <!-- 在空闲时检查有效性, 默认false -->
        <property name="testWhileIdle" value="${redis.pool.testWhileIdle}"></property>
    </bean>

    <!--创建一个Spring Bean的名称springSessionRepositoryFilter实现过滤器。
        筛选器负责将HttpSession实现替换为Spring会话支持。在这个实例中,Spring会话得到了Redis的支持。-->
    <!-- springsession支持 -->
    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
         <property name="maxInactiveIntervalInSeconds" value="${redis.session.timeout}" />    <!-- session过期时间,单位是秒 -->
    </bean>
   
    
    
    <!-- 采用JedisConnectionFactory -->
    <bean id="jedisConnectionFactory"
      class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
	    <property name="hostName" value="${redis.host}"/>
	    <property name="port" value="${redis.port}"/>
	    <property name="password" value="${redis.pass}" />
	    <!--  连接超时时间 -->
	    <property name="timeout" value="3000"/>
	    <property name="usePool" value="true"/>
	    <property name="poolConfig" ref="jedisPoolConfig"/>
	</bean>

</beans>



5.SessionServlet.java

package com.testspringsession.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/session")
public class SessionServlet extends HttpServlet{

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String attributeName = req.getParameter("attributeName");
        String attributeValue = req.getParameter("attributeValue");
        req.getSession().setAttribute(attributeName, attributeValue);
        
        resp.sendRedirect(req.getContextPath() + "/");
    }
    
}

6.index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page isELIgnored="false" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Session Attributes</title>
<base href="<%=basePath%>" target="_blank" rel="external nofollow" >
</head>
<body>
     <div class="container">
        <h1>Description</h1>
        <p>This application demonstrates how to use a Redis instance to back your session. Notice that there is no JSESSIONID cookie. We are also able to customize the way of identifying what the requested session id is.</p>

        <h1>Try it</h1>

        <form class="form-inline" role="form" action="./session" method="post">
            <label for="attributeName">Attribute Name</label>
            <input id="attributeName" type="text" name="attributeName"/>
            <label for="attributeValue">Attribute Value</label>
            <input id="attributeValue" type="text" name="attributeValue"/>
            <input type="submit" value="Set Attribute"/>
        </form>

        <hr/>

        <table class="table table-striped">
            <thead>
            <tr>
                <th>Attribute Name</th>
                <th>Attribute Value</th>
            </tr>
            </thead>
            <tbody>
            <c:forEach items="${sessionScope}" var="attr">
                <tr>
                    <td><c:out value="${attr.key}"/></td>
                    <td><c:out value="${attr.value}"/></td>
                </tr>
            </c:forEach>
            </tbody>
        </table>
    </div>
</body>
</html>

6.session-redis.properties

#redisIp
redis.host=127.0.0.1
#redisPassword
redis.pass=123456
redis.port=6379
redis.session.timeout=1800

redis.database=0
redis.timeout=1000
redis.userPool=true
redis.pool.maxIdle=100
redis.pool.minIdle=10
redis.pool.maxTotal=200
redis.pool.maxWaitMillis=10000
redis.pool.minEvictableIdleTimeMillis=300000
redis.pool.numTestsPerEvictionRun=10
redis.pool.timeBetweenEvictionRunsMillis=30000
redis.pool.testOnBorrow=true
redis.pool.testOnReturn=true
redis.pool.testWhileIdle=true

测试项目构建完成。

测试方法:启动本机redis,将项目放入两个tomcat容器,运行,从同一浏览器发送请求至不同的节点,观察显示结果。

参考文章:https://www.cnblogs.com/youzhibing/p/7348337.html