spring-session之二:简单配置
官方示例:https://docs.spring.io/spring-session/docs/current/reference/html5/#samples
配置Spring Session
在Web项目中配置Spring Session分为四步:
- 搭建用于Spring Session的数据存储
- 将Spring Session的jar文件添加到web应用中
- 将Spring Session filter添加到web应用的配置中
- 配置Spring Session如何选择session数据存储的连接
Spring Session自带了对Redis的支持。搭建和安装redis的细节可以参考《windows下安装redis》。
有两种常见的方式能够完成上述的Spring Session配置步骤。第一种方式是使用Spring Boot来自动配置Spring Session。第二种配置Spring Session的方式是手动完成上述的每一个配置步骤。
借助像Maven或Gradle这样的依赖管理器,将Spring Session添加应用中是很容易的。如果你使用Maven和Spring Boot的话,那么可以在pom.xml中使用如下的依赖:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
其中,spring-boot-starter-redis依赖能够确保使用redis所需的所有jar都会包含在应用中,所以它们可以借助Spring Boot进行自动装配。spring-session依赖将会引入 Spring Session的jar。
至于Spring Session Servlet filter的配置,可以通过Spring Boot的自动配置来实现,这只需要在Spring Boot的配置类上使用 @EnableRedisHttpSession注解就可以了,如下面的代码片段所示。
package com.dxz.springsession.demo3.httpsession; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver; @ServletComponentScan
@SpringBootApplication
public class SpringsecurityDemo3Application { public static void main(String[] args) {
SpringApplication.run(SpringsecurityDemo3Application.class, args);
}
}
至于Spring Session到Redis连接的配置,可以添加如下配置到Spring Boot的application.properties文件中:
spring.redis.host=localhost
spring.redis.password=123456
spring.redis.port=6379
Spring Boot提供了大量的基础设施用来配置到Redis的连接,定义到Redis数据库连接的各种方式都可以用在这里。你可以参考该地址的逐步操作指南,来了解如何使用Spring Session和Spring Boot。
package com.dxz.springsession.demo3.httpsession.config; import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @EnableRedisHttpSession
public class Config { @Bean
public LettuceConnectionFactory connectionFactory() {
LettuceConnectionFactory factory = new LettuceConnectionFactory();
factory.setPassword("123456");
return factory;
}
}
package com.dxz.springsession.demo3.httpsession.config;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
public class Initializer extends AbstractHttpSessionApplicationInitializer {
public Initializer() {
super(Config.class);
}
}
package com.dxz.springsession.demo3.httpsession.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.HeaderHttpSessionStrategy;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration
@EnableWebMvc //启动Spring MVC
@ComponentScan("com.dxz.springsession.demo3.httpsession") //启动组件扫描
public class WebConfig extends WebMvcConfigurerAdapter { //配置JSP视图解析器
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
//resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
} //配置静态资源的处理
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
//对"静态文件"开启默认转发给servlet容器(如tomcat)处理
configurer.enable();
}
}
package com.dxz.springsession.demo3.httpsession; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class HomeHttpSessionController { @RequestMapping("/")
public String index() { return "index";
}
}
在传统的web应用中,可以参考该指南来了解如何通过web.xml来使用Spring Session。
在传统的war文件中,可以参考该指南来了解如何不使用web.xml进行配置。
默认情况下,Spring Session会使用HTTP cookie来存储session id,但是我们也可以配置Spring Session使用自定义的HTTP header信息,如x-auth-token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3,当构建REST API的时候,这种方式是很有用的。完整的指南可以参考该地址。
使用Spring Session
Spring Session配置完成之后,我们就可以使用标准的Servlet API与之交互了。例如,如下的代码定义了一个servlet,它使用标准的Servlet session API来访问session。
package com.dxz.springsession.demo3.httpsession.config; import java.io.IOException; 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 doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String attributeName = req.getParameter("attributeName");
String attributeValue = req.getParameter("attributeValue");
System.out.println("session servlet..." + "attributeName:" + attributeName +", attributeValue:" +attributeValue);
req.getSession().setAttribute(attributeName, attributeValue);
resp.sendRedirect(req.getContextPath() + "/");
} private static final long serialVersionUID = 2878267318695777395L;
}
配置sessionListener监听session的创建及销毁,如下:
package com.dxz.springsession.demo3.httpsession; import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; import org.springframework.stereotype.Component; @Component
public class MyListener implements HttpSessionListener { @Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("sessionCreated()" + printHttpSession(se.getSession())); System.out.println("online + 1");
} @Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("sessionDestroyed()" + printHttpSession(se.getSession()));
System.out.println("online - 1");
} private String printHttpSession(HttpSession session) {
StringBuffer sb = new StringBuffer();
sb.append("uin:="+session.getAttribute("uin"));
sb.append(", createtime:="+session.getCreationTime());
sb.append(", value:="+session.getValue("uin"));
return sb.toString();
}
}
每个浏览器多个Session
Spring Session会为每个用户保留多个session,这是通过使用名为“_s”的session别名参数实现的。例如,如果到达的请求为http://example.com/doSomething?_s=0 ,那么Spring Session将会读取“_s”参数的值,并通过它确定这个请求所使用的是默认session。
如果到达的请求是http://example.com/doSomething?_s=1的话,那么Spring Session就能知道这个请求所要使用的session别名为1.如果请求没有指定“_s”参数的话,例如http://example.com/doSomething,那么Spring Session将其视为使用默认的session,也就是说_s=0。
要为某个浏览器创建新的session,只需要调用javax.servlet.http.HttpServletRequest.getSession()就可以了,就像我们通常所做的那样,Spring Session将会返回正确的session或者按照标准Servlet规范的语义创建一个新的session。下面的表格描述了针对同一个浏览器窗口,getSession()面对不同url时的行为。
|
HTTP请求URL |
Session别名 |
getSession()的行为 |
|
example.com/resource |
0 |
如果存在session与别名0关联的话,就返回该session,否则的话创建一个新的session并将其与别名0关联。 |
|
example.com/resource?_s=1 |
1 |
如果存在session与别名1关联的话,就返回该session,否则的话创建一个新的session并将其与别名1关联。 |
|
example.com/resource?_s=0 |
0 |
如果存在session与别名0关联的话,就返回该session,否则的话创建一个新的session并将其与别名0关联。 |
|
example.com/resource?_s=abc |
abc |
如果存在session与别名abc关联的话,就返回该session,否则的话创建一个新的session并将其与别名abc关联。 |
如上面的表格所示,session别名不一定必须是整型,它只需要区别于其他分配给用户的session别名就可以了。但是,整型的session别名可能是最易于使用的,Spring Session提供了HttpSessionManager接口,这个接口包含了一些使用session别名的工具方法。
我们可以在HttpServletRequest中,通过名为“org.springframework.session.web.http.HttpSessionManager”的属性获取当前的HttpSessionManager。如下的样例代码阐述了如何得到HttpSessionManager,并且在样例注释中描述了其关键方法的行为。
@WebServlet("/example")
public class Example extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
/*
* 在请求中,根据名为org.springframework.session.web.http.HttpSessionManager的key
* 获得Spring Session session管理器的引用
*/
HttpSessionManager sessionManager=(HttpSessionManager)request.getAttribute(
"org.springframework.session.web.http.HttpSessionManager");
/*
* 使用session管理器找出所请求session的别名。
* 默认情况下,session别名会包含在url中,并且请求参数的名称为“_s”。
* 例如,http://localhost:8080/example?_s=1
* 将会使如下的代码打印出“Requested Session Alias is: 1”
*/
String requestedSessionAlias=sessionManager.getCurrentSessionAlias(request);
System.out.println("Requested Session Alias is: " + requestedSessionAlias);
/* 返回一个唯一的session别名id,这个别名目前没有被浏览器用来发送请求。
* 这个方法并不会创建新的session,
* 我们需要调用request.getSession()来创建新session。
*/
String newSessionAlias = sessionManager.getNewSessionAlias(request);
/* 使用新创建的session别名来建立URL,这个URL将会包含
* “_s”参数。例如,如果newSessionAlias的值为2的话,
* 那么如下的方法将会返回“/inbox?_s=2”
*/
String encodedURL = sessionManager.encodeURL("/inbox", newSessionAlias);
System.out.println(encodedURL);
/* 返回session别名与session id所组成的Map,
* 它们是由浏览器发送请求所形成的。
*/
Map < String, String > sessionIds = sessionManager.getSessionIds(request);
}
}
结论
Spring Session为企业级Java的session管理带来了革新,使得如下的任务变得更加容易:
- 编写可水平扩展的原生云应用。
- 将session所保存的状态卸载到特定的外部session存储中,如Redis或Apache Geode中,它们能够以独立于应用服务器的方式提供高质量的集群。
- 当用户使用WebSocket发送请求的时候,能够保持HttpSession处于活跃状态。
- 在非Web请求的处理代码中,能够访问session数据,比如在JMS消息的处理代码中。
- 支持每个浏览器上使用多个session,这样就可以很容易地构建更加丰富的终端用户体验。
- 控制客户端和服务器端之间如何进行session id的交换,这样更加易于编写Restful API,因为它可以从HTTP 头信息中获取session id,而不必再依赖于cookie。
如果你想抛弃传统的重量级应用服务器,但受制于已经使用了这些应用服务器的session集群特性,那么Spring Session将是帮助你迈向更加轻量级容器的重要一步,这些轻量级的容器包括Tomcat、Jetty或Undertow。
spring-session之二:简单配置的更多相关文章
- spring cloud微服务快速教程之(八) Spring Cloud Alibaba--nacos(二)、配置中心
0-前言 上一篇我们介绍了nacos作为服务注册发现组件的功能,nacos还具有配置中心的功能,而且支持热加载: 在此之前,配置中心有Spring Cloud Config,实际上,用这个有很多风险和 ...
- Spring项目集成ShiroFilter简单配置
Shiros是我们开发中常用的用来实现权限控制的一种工具包,它主要有认证.授权.加密.会话管理.与Web集成.缓存等功能.我是从事javaweb工作的,我就经常遇到需要实现权限控制的项目,之前我们都是 ...
- Spring dbcp连接池简单配置 示例
一.配置db.properties属性文件 #database connection config connection.username=sa connection.password=sa conn ...
- springMVC+spring+MyBatis(SSM)的简单配置
SSM(Spring+SpringMVC+MyBatis)框架集由Spring.SpringMVC.MyBatis三个开源框架整合而成,常作为数据源较简单的web项目的框架. 其中: Spring是一 ...
- Spring.Net框架二:配置Spring.Net框架环境
一.下载DLL文件 去Spring的官方网站下载并解压,然后直接添加dll文件的引用就可以了.在上一篇文章中,已经介绍过Spring.Net框架中需要使用到的dll文件.这些程序集文件位于Spring ...
- spring整合mybatis二种配置
第一种: <!-- 配置sqlsession --> <bean id="sqlsessionFactory" class="org.mybatis.s ...
- Spring Boot(二)配置分析
回顾一下采用SSM开发项目时,项目中会存在多个配置文件,比如web.xml,配置Spring相关的applicationContext-springmvc.xml, applicationContex ...
- mac攻略(二) -- 简单配置php开发环境
最简单直接的方式还是使用 Mac 上自带的 Apache 和 PHP. 1.启动 Apache 1>启动apache $sudo apachectl start; 2>启动后,在浏览器 ...
- 单点登录实现(spring session+redis完成session共享)
一.前言 项目中用到的SSO,使用开源框架cas做的.简单的了解了一下cas,并学习了一下 单点登录的原理,有兴趣的同学也可以学习一下,写个demo玩一玩. 二.工程结构 我模拟了 sso的客户端和s ...
随机推荐
- Jni_Linux_01_转
1.Linux下JNI的使用(http://www.cnblogs.com/bastard/archive/2012/05/17/2506877.html) Linux下 JNI的使用 学习Andro ...
- ZC_03_创建对象
1. 正如 上一篇文章中所见,反射创建 类实例的方式,主要为2类: (1).Class对象.newInstance() 这是使用 默认的无参构造函数 创建对象 (2).Constructor对象.ne ...
- caffe2 教程入门(python版)
学习思路 1.先看官方文档,学习如何使用python调用caffe2包,包括 Basics of Caffe2 - Workspaces, Operators, and Nets Toy Regres ...
- 四十九 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页
逻辑处理函数 计算搜索耗时 在开始搜索前:start_time = datetime.now()获取当前时间 在搜索结束后:end_time = datetime.now()获取当前时间 last_t ...
- SpringBoot_11_将springboot项目部署到外部tomcat上
一.前言 二. 三.参考资料 如何将Spring Boot项目打包部署到外部Tomcat 2.SpringBoot 项目如何在tomcat容器中运行
- Struts01---入门小案例
创建web项目 实现的效果! 用户点击页面不同的链接,后台调用不同的代码! 创建两个类实现共同的接口! public interface Action { String execute(); } ...
- LeetCode OJ :Unique Binary Search Trees II(唯一二叉搜索树)
题目如下所示:返回的结果是一个Node的Vector: Given n, generate all structurally unique BST's (binary search trees) th ...
- php调用API支付接口(转自刘68)
首先访问 https://charging.teegon.com/ 注册账号, 找到开发配置 记下client_id和client_secret. 点击 天工开放平台 点击天工收银 点击 S ...
- 9.链表中倒数第k个结点[FindReverseKthLinkedListNode]
[题目] 输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针.链表结点定义如下: C++ Code 12345 struct ListNode { int ...
- node.js之npm库
npm库安装可分为本地安装和全局安装,本地安装如下: npm install <Module name> 但是好像会出问题,官方貌似推荐全局安装,so 全局安装官方所给命令如下: npm ...