最近项目中考虑到跨系统(多个系统共享),跨平台(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" %>
<!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>
访问
http://localhost:8080/TestHttpSession,可看到首页。
设置attributeName和attributeValue并提交后,可以在下方看到设置的值。
如在页面中加入<%=session.getClass() %>以输出session的类型,可以看到session为:class org.apache.catalina.session.StandardSessionFacade类。
2.加入依赖库
修改pom.xml, <dependencies> </dependencies>标签内最后加入以下代码段
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.0.1.RELEASE</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
保存后项目会自动下载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。
分享到:
相关推荐
1. 使用 Cookie:第一次创建 Session 时,服务端会在 HTTP 协议中向客户端 Cookie 中记录一个 Session ID,以后每次请求把这个会话 ID 发送到服务器,这样服务端就知道客户端是谁了。 2. 使用 URL 重写:如果客户端...
- **singleton**:默认情况下,每个Bean定义在Spring IoC容器中只会被创建一次,这是最常用的作用域。 - **prototype**:每次从容器中请求该Bean时都会创建一个新的实例。 - **request**:对于每个HTTP请求,都会...
【标题】"Spring MVC + Spring + Hibernate 全注解整合开发视频教程 09" 提供了一次深入了解Java企业级应用开发的机会,特别是在使用Spring MVC、Spring和Hibernate这三大核心框架进行全注解配置的场景下。...
Spring Security是Java领域中广泛应用的...总的来说,`spring-security-web 3.1.2`和`spring-security-oauth2`的源码分析将是一次深入学习Web安全和OAuth2授权的好机会,有助于提升对现代Web安全架构的理解和实践能力。
5. **懒加载和级联操作**:优化性能,仅在需要时加载关联数据,以及一次操作多个关联对象。 通过本课程的源代码,你可以逐步了解如何配置Spring Boot项目,集成Spring 6框架,以及如何使用Hibernate进行数据访问。...
8. **缓存机制**: Hibernate提供了第一级缓存(Session级别的)和第二级缓存(SessionFactory级别的)。Spring可以通过`CacheProvider`和`Cache`接口配置和管理缓存。 9. **Query和Criteria API**: Hibernate提供了...
在提供的文件列表中,"Java高级应用第22次上机.doc"可能包含了关于整合这三个框架的具体步骤或案例分析。"poi-2[1].5.1.jar"是Apache POI库,用于处理Microsoft Office格式文件,可能在生成报表或导出数据时用到。...
而Redis作为缓存数据库,用于存储临时数据,如验证码、session等,提高了系统的响应速度。 总的来说,这个项目展示了开发者扎实的Java基础,对Spring生态的深入理解,以及在分布式系统中运用各种中间件的能力。...
【标题】"WebWork Spring Hibernate整合开发网络书城(4)" 涉及到的是一个实战项目,将三个流行的Java框架——WebWork、Spring和Hibernate——集成在...对于学习者来说,这是一次深入了解和实践Java企业级开发的好机会。
最大努力一次提交 6-8 分布式事务实现模式与技术 6-9 全局一致性ID和分布式对象_ 第7章 分布式事务实现:消息驱动模式 详细介绍3种分布式事务实现的模式中的消息驱动模式并通过完整实例演示了消息驱动模式下,实现...
1. **Java 基础**:Java 是一种跨平台的面向对象编程语言,以其“一次编写,到处运行”的特性而闻名。学习 Java 需要掌握基础语法,包括类、对象、封装、继承和多态等面向对象概念。此外,异常处理、集合框架(如 ...
购物车是电商系统中的关键组件,它允许用户将想要购买的商品暂存,以便于一次性结算或进行商品比较。这涉及到数据库操作、商品管理、用户交互等多个技术环节,包括商品的添加、删除、数量调整以及最终的结算流程。 ...
在这个“Javaweb(7)学习资料”中,我们可以推测它可能包含了关于JavaWeb开发的第七个阶段或者模块的学习材料。尽管没有具体的文件内容,但从一般的JavaWeb学习路径出发,我们可以深入探讨一些关键知识点。 1. **...
JSP页面在第一次访问时会被转换为Servlet,然后编译并执行。 3. **MVC架构**: Model-View-Controller模式是一种常见的软件设计模式,广泛应用于Web应用开发。Model负责数据处理,View负责显示用户界面,Controller...
当服务器启动或第一次请求到达时,Servlet会被加载和初始化。然后,每次有请求到达,Servlet都会调用`service()`方法来处理请求。最后,当服务器关闭或者不再需要Servlet时,会执行销毁方法。 3. **Servlet接口和...
- **SessionFactory**:负责创建Session对象,它是线程安全的,整个应用中只需创建一次。 - **Session**:代表与数据库的会话,是执行数据库操作的主要接口,非线程安全,每次数据库交互都需要新建一个Session。 - *...
3. **打开Session**: Session是短生命周期的,用于一次或一组数据库操作。 4. **操作实体**: 使用Session进行CRUD(Create、Read、Update、Delete)操作。 5. **提交事务**: 对于多步操作,需包裹在Transaction中,...
理解这些基础,是构建JavaWeb框架的第一步。 在框架设计方面,书籍会深入探讨MVC(Model-View-Controller)模式,这是JavaWeb开发中常见的架构模式。模型负责处理业务逻辑,视图负责展示数据,控制器则协调模型和...