Spring Session边学边写(一)第一次实践

阅读更多
最近项目中考虑到跨系统(多个系统共享),跨平台(App和浏览器)的会话管理,还要考虑从现在的jboss替换为tomcat等其他应用服务器。正好spring出了Spring Session,而且更新到了1.0.1 RELEASE版本,借此机会学习一番,将实践经过一起分享。
首先是Spring Session的官方文档地址 : http://docs.spring.io/spring-session/docs/1.0.1.RELEASE/reference/html5/

里面可以看到介绍:
  • HttpSession: 集群会话、浏览器多会话支持、rest样式api
  • WebSocket
以及多种应用类型的示例和指导。 本次实践按照官方示例一:HttpSession进行。

1.搭建Maven工程
官方示例使用Maven工程实现,需要先搭建Maven工程并转为web项目。具体步骤见另外一篇博客(我也是按照他的来实现的,就不粘过来了,尊重原创) http://b-l-east.iteye.com/blog/1246482

按照步骤创建工程TestHttpSession,最后部署至tomcat并启动,访问 http://localhost:8080/TestHttpSession,说明项目搭建成功。

修改/创建src/main/webapp/index.jsp,代码如下
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>



	Session Attributes
	
	


	

Description

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.

Try it


Attribute Name Attribute Value

访问 http://localhost:8080/TestHttpSession,可看到首页。
设置attributeName和attributeValue并提交后,可以在下方看到设置的值。

如在页面中加入<%=session.getClass() %>以输出session的类型,可以看到session为:class org.apache.catalina.session.StandardSessionFacade类。

2.加入依赖库
修改pom.xml, 标签内最后加入以下代码段
	
	    org.springframework.session
	    spring-session-data-redis
	    1.0.1.RELEASE
	    pom
	
	
	    org.springframework
	    spring-web
	    4.1.6.RELEASE
	

保存后项目会自动下载spring及spring session,jedis等依赖库。

3.加入配置代码
按照官方文档,在src/main/java源文件夹下创建sample包,并创建Config类
,代码如下
package sample;

import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.redis.embedded.EnableEmbeddedRedis;
import org.springframework.session.redis.embedded.RedisServerPort;

// tag::class[]
@EnableEmbeddedRedis // <1>
@EnableRedisHttpSession // <2>
public class Config {

	@Bean
	public JedisConnectionFactory connectionFactory(@RedisServerPort int port) {
		JedisConnectionFactory connection = new JedisConnectionFactory(); // <3>
		connection.setPort(port);
		return connection;
	}
}

这本是从GitHub上下载的源码,但是类中会报错,暂时忽略该问题,继续按官方文档执行。

在sample包下新建Initializer类,代码如下
package sample;

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

// tag::class[]
public class Initializer
		extends AbstractHttpSessionApplicationInitializer { // <1>

	public Initializer() {
		super(Config.class); // <2>
	}
}
// end::class[]

该类的作用是在应用启动时加载Config类,执行Config中的启动redis并创建连接等操作。

在sample包下新建SessionServlet类,代码如下
package sample;

import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
import java.io.IOException;

// tag::class[]
@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;
}
// tag::end[]

该类的作用是实现路径为/session的servlet,可以将属性post至session中保存。

4.部署测试
重新发布至tomcat。
访问 http://localhost:8080/TestHttpSession,发现无法访问。
查看tomcat控制台,发现意料之中的错误。因Config类中的类引用找不到,系统启动失败。

因Config类中对EnableEmbeddedRedis、RedisServerPort、RedisServerPort 这三个类的引用根本找不到导致类编译失败。
Config类的作用是EnableEmbeddedRedis自动创建内建的redis缓存,并使用jedis连接缓存、创建连接工厂,以供会话存储查询使用。但是不知道是不是因为源码版本的问题,根本找不到这几个类,所以无法启动缓存,jedis也无法连接。
所以只要使用外部redis缓存服务器,并将spring-jedis配置连接至外部缓存,就可以解决该问题。

5.使用外部缓存
redis官网地址: http://redis.io/
本想安装windows版,结果发现redis官方不支持windows。虽然github上有其他版本支持windows的redis,但是安装后启动不成功,遂放弃转向Linux服务器版本。
参考文章如下:
Redis介绍以及安装(Linux): http://www.cnblogs.com/silent2012/p/3499654.html
Redis常用命令: http://www.linuxidc.com/Linux/2012-03/57573.htm

按照文档将redis安装在linux服务器192.168.24.31上并启动redis-server,端口默认6379。
修改sample包下Config类,代码如下:
package sample;

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

// tag::class[]
@Configuration
@EnableRedisHttpSession // <2>
public class Config {

	@Bean
	public JedisConnectionFactory connectionFactory() {
		JedisConnectionFactory connection = new JedisConnectionFactory(); // <3>
		connection.setPort(6379);
		connection.setHostName("192.168.24.31");
		return connection;
	}
}
// end::class[]

修改将内建redis的引用、启动去掉,并连接至刚配好的外部redis:192.168.24.31:6379。

5.部署测试
重新发布至tomcat。
访问 http://localhost:8080/TestHttpSession,可看到首页。
设置attributeName和attributeValue并提交后,可以在下方看到设置的值。
同时可以看到session的类型变成了class org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper类。
在linux服务器上使用redis-cli客户端的keys * 命令可看到会话已被缓存。

6.停机测试
将tomcat服务器关闭(但不关闭浏览器,以保留客户端cookie)。
重新启动tomcat后刷新页面,发现还可以取到之前session的值,说明集群会话缓存成功。
使用chrome开发者工具可看到cookie中原有的JSESSIONID被替换成了SESSION。

你可能感兴趣的:(spring,spring,session)