paulwong

SPRING-SESSION

HTTP SESSION的管理通常是由容器来做,但如果是在PAAS环境下,服务器不能做变更,则需要由WEB应用来做处理HTTP SESSION。

同样,如果是分布式的环境下,SESSION的管理也会带来性能问题。

SPRING推出了处理SESSION的框架:SPRING-SESSION。


SPRING会重写HTTP SESSION的那一套,使用SESSION也同样还是用
req.getSession().setAttribute(attributeName, attributeValue);


此框架使用REDIS作为HTTP SESSION的持久化容器。此框架只对使用的当前WEB应用下的HTTP SESSION进行集中管理,同一WEB容器下的其他WEB应用还是会使用容器的SESSION管理那一套。

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>com.paul</groupId>
    <artifactId>spring-session</artifactId>
    <packaging>war</packaging>
        <version>1.0</version>
    <repositories>
        <repository>
            <id>spring-snapshot</id>
            <url>https://repo.spring.io/libs-milestone</url>
        </repository>
        <repository>
            <id>clojars.org</id>
            <url>http://clojars.org/repo</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session</artifactId>
            <version>1.0.0.RC1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.3.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>redis.embedded</groupId>
            <artifactId>embedded-redis</artifactId>
            <version>0.3</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.0</version>
                <configuration>
                    <path>/</path>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <spring.version>4.1.0.RELEASE</spring.version>
    </properties>
</project>


在ECLIPSE中运行TOMCAT的文件:spring-session-tomcat-run.launch
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
<stringAttribute key="M2_GOALS" value="tomcat7:run"/>
<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
<booleanAttribute key="M2_OFFLINE" value="false"/>
<stringAttribute key="M2_PROFILES" value=""/>
<listAttribute key="M2_PROPERTIES"/>
<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
<booleanAttribute key="M2_SKIP_TESTS" value="false"/>
<intAttribute key="M2_THREADS" value="1"/>
<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dspring.profiles.active=dev"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/spring-session}"/>
</launchConfiguration>



启动内置REDIS服务器的文件:EmbeddedRedisConfiguration.java
package com.paul.springsesseion;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.Protocol;
import redis.embedded.RedisServer;

/**
 * Runs an embedded Redis instance. This is only necessary since we do not want
 * users to have to setup a Redis instance. In a production environment, this
 * would not be used since a Redis Server would be setup.
 *
 * 
@author Rob Winch
 
*/
@Configuration
public class EmbeddedRedisConfiguration {

    @Bean
    public RedisServerBean redisServer() {
        return new RedisServerBean();
    }

    class RedisServerBean implements InitializingBean, DisposableBean {
        private RedisServer redisServer;


        @Override
        public void afterPropertiesSet() throws Exception {
            redisServer = new RedisServer(Protocol.DEFAULT_PORT);
            redisServer.start();
        }

        @Override
        public void destroy() throws Exception {
            if(redisServer != null) {
                redisServer.stop();
            }
        }
    }
}


配置文件:Config.java
package com.paul.springsesseion;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * 
@author Rob Winch
 
*/
@Import(EmbeddedRedisConfiguration.class)
@Configuration
@EnableRedisHttpSession
public class Config {

    @Bean
    public JedisConnectionFactory connectionFactory() {
        return new JedisConnectionFactory();
    }
}


初始化配置文件:Initializer.java
package com.paul.springsesseion;

import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;

/**
 * 
@author Rob Winch
 
*/
public class Initializer extends AbstractHttpSessionApplicationInitializer {

    public Initializer() {
        super(Config.class);
    }
}



存取HTTP SESSION:SessionServlet.java
package com.paul.springsesseion;

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

/**
 * 
@author Rob Winch
 
*/
@WebServlet("/session")
public class SessionServlet extends HttpServlet {

    @Override
    protected void doPost(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() + "/");
    }

    private static final long serialVersionUID = 2878267318695777395L;
}


页面:index.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Session Attributes</title>
    <link rel="stylesheet" href="assets/bootstrap.min.css">
    <style type="text/css">
        body 
{
            padding
: 1em;
        
}
    
</style>
</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="attributeValue">Attribute Name</label>
            <input id="attributeValue" 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>


参考:
https://github.com/spring-projects/spring-session

posted on 2014-11-19 18:23 paulwong 阅读(6360) 评论(1)  编辑  收藏 所属分类: SPRING分布式REDIS

Feedback

# spring-session框架能否做url重写? 2016-06-08 11:14 liuxinsudi

在TOMCAT 自生的session管理中通过下面主要的方式
${basePath}/servlet/Upload;jsessionid=${sessionId}?
做url重写,如果改为spring session管理,能否做url重写?
如果可以的话,参数该怎么表达?   回复  更多评论   



只有注册用户登录后才能发表评论。


网站导航: