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 >
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 >
< 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();
}
}
}
}
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();
}
}
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);
}
}
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;
}
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 >
<! 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