Spring Session -- HttpSession Integration HttpSession集成

官网:https://spring.io/projects/spring-session

Samples:https://docs.spring.io/spring-session/reference/samples.html#samples

指引

  1. Spring Session – HttpSession Integration HttpSession集成
  2. Spring Session – WebSocket Integration WebSocket 集成
  3. Spring Session – WebSession Integration WebSession 集成
  4. Spring Session – Spring Security Integration Spring Security 集成

HttpSession Integration HttpSession 集成

  • 集群会话:Spring Session 使支持集群会话变得简单,而无需绑定到特定于应用程序容器的解决方案
  • RESTful API:Spring Session 允许在标头中提供会话 ID 与 RESTful API 一起使用

HttpSession 与 Redis

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

Java 配置

@EnableRedisHttpSession 
public class Config {

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

}
  1. @EnableRedisHttpSession 注释创建一个名称为 springSessionRepositoryFilter 的 Spring Bean 来实现负责替换由 Spring Session 支持的 HttpSession 实现的过滤器。在该实例 Spring Session 由 Redis 支持
  2. 创建 RedisConnectionFactory 连接 Spring Session 和 Redis Server 将连接配置为连接到默认端口(6379)上的 localhost 有关配置 Spring Data Redis

Java Servlet 容器初始化

Spring Session 替换 Redis 实现集群会话

public class Initializer extends AbstractHttpSessionApplicationInitializer { 

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

}
  1. AbstractHttpSessionApplicationInitializer 确保每个请求的 Spring Bean 都已注册到我们的 Servlet 容器中
  2. AbstractHttpSessionApplicationInitializer 提供了一种机制来确保 Spring 加载

XML 配置

src/main/webapp/WEB-INF/spring/session.xml
a
context:annotation-config/

<bean class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>

XML Servlet 容器初始化

src/main/webapp/WEB-INF/web.xml

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		/WEB-INF/spring/session.xml
	</param-value>
</context-param>
<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>

<filter>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>ERROR</dispatcher>
</filter-mapping>

HttpSession 与 MongoDB

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-mongodb</artifactId>
</dependency>

Java 配置

@EnableMongoHttpSession 
public class HttpSessionConfig {

	@Bean
	public JdkMongoSessionConverter jdkMongoSessionConverter() {
		return new JdkMongoSessionConverter(Duration.ofMinutes(30)); 
	}

}

Spring Session MongoDB 默认使用 JdkMongoSessionConverter

@Bean
public JdkMongoSessionConverter jdkMongoSessionConverter() {
	return new JdkMongoSessionConverter(Duration.ofMinutes(30)); 
}

Spring Session MongoDB 使用 Jackson 将会话对象序列化为 JSON

@Bean
JacksonMongoSessionConverter mongoSessionConverter() {
    return new JacksonMongoSessionConverter();
}

Spring Session MongoDB

@Configuration
@EnableMongoHttpSession
static class Config extends BaseConfig {

	@Bean
	AbstractMongoSessionConverter mongoSessionConverter() {
		return new JacksonMongoSessionConverter(Collections.singletonList(new GeoModule()));
	}

}

HttpSession 与 JDBC

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-jdbc</artifactId>
</dependency>

Java 配置

@EnableJdbcHttpSession
public class Config {

	@Bean
	public EmbeddedDatabase dataSource() {
		return new EmbeddedDatabaseBuilder()
				.setType(EmbeddedDatabaseType.H2).addScript("org/springframework/session/jdbc/schema-h2.sql").build();
	}

	@Bean
	public PlatformTransactionManager transactionManager(DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

}

Java Servlet 容器初始化

src/main/java/sample/Initializer.java

public class Initializer extends AbstractHttpSessionApplicationInitializer { 

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

}

Multiple DataSources 多数据源

使用 @SpringSessionDataSource 定义 Spring Session 的数据源

Config.java

@EnableJdbcHttpSession
public class Config {

	@Bean
	@SpringSessionDataSource 
	public EmbeddedDatabase firstDataSource() {
		return new EmbeddedDatabaseBuilder()
				.setType(EmbeddedDatabaseType.H2).addScript("org/springframework/session/jdbc/schema-h2.sql").build();
	}

	@Bean
	public HikariDataSource secondDataSource() {
		// ...
	}
}

HttpSession 与 Hazelcast

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-hazelcast</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-hazelcast</artifactId>
</dependency>

Java 配置

@EnableHazelcastHttpSession
@Configuration
public class HazelcastHttpSessionConfig {

	@Bean
	public HazelcastInstance hazelcastInstance() {
		Config config = new Config();
		MapAttributeConfig attributeConfig = new MapAttributeConfig()
				.setName(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
				.setExtractor(PrincipalNameExtractor.class.getName());
		config.getMapConfig(HazelcastIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME)
				.addMapAttributeConfig(attributeConfig).addMapIndexConfig(
						new MapIndexConfig(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false));
		SerializerConfig serializerConfig = new SerializerConfig();
		serializerConfig.setImplementation(new HazelcastSessionSerializer()).setTypeClass(MapSession.class);
		config.getSerializationConfig().addSerializerConfig(serializerConfig);
		return Hazelcast.newHazelcastInstance(config);
	}

}

Servlet 容器初始化

src/main/java/sample/SecurityInitializer.java

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {

	public SecurityInitializer() {
		super(SecurityConfig.class, SessionConfig.class);
	}

}

确保 Spring Security 使用的 Spring Session 支持

src/main/java/sample/Initializer.java

public class Initializer extends AbstractHttpSessionApplicationInitializer {

}

HttpSession 集成的工作原理

创建 SessionRepositoryRequestWrapper 继承 HttpServletRequestWrapper 重写 getSession 方法,创建 SessionRepositoryFilter 实现 Filter 接口 重写 doFilter 方法

HttpSession HttpServletRequest

创建 SessionRepositoryRequestWrapper 继承 HttpServletRequestWrapper 实现

public class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper {

	public SessionRepositoryRequestWrapper(HttpServletRequest original) {
		super(original);
	}

	public HttpSession getSession() {
		return getSession(true);
	}

	public HttpSession getSession(boolean createNew) {
		// create an HttpSession implementation from Spring Session
	}

	// ... other methods delegate to the original HttpServletRequest ...
}

HttpServletRequest Filter SessionRepositoryFilter

创建 SessionRepositoryFilter 实现 Filter 接口以注册使用

public class SessionRepositoryFilter implements Filter {

	public doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		SessionRepositoryRequestWrapper customRequest =
			new SessionRepositoryRequestWrapper(httpRequest);

		chain.doFilter(customRequest, response, chain);
	}

	// ...
}

HttpSession 和 RESTful API

Java 配置

@Configuration
@EnableRedisHttpSession
public class HttpSessionConfig {

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

	@Bean
	public HttpSessionIdResolver httpSessionIdResolver() {
		return HeaderHttpSessionIdResolver.xAuthToken();
	}

}

Servlet 容器初始化

src/main/java/sample/mvc/MvcInitializer.java

@Override
protected Class<?>[] getRootConfigClasses() {
	return new Class[] { SecurityConfig.class, HttpSessionConfig.class };
}

src/main/java/sample/Initializer.java

public class Initializer extends AbstractHttpSessionApplicationInitializer {

}

使用 HttpSessionListener

Spring Session 通过声明 SessionEventHttpSessionListenerAdapter,将 SessionDestroyedEvent 和 SessionCreatedEvent 转换为 HttpSessionEvent 支持 HttpSessionListener

  • 确保实现支持和已配置:SessionRepository SessionDestroyedEvent SessionCreatedEvent
  • 配置 Spring Bean:SessionEventHttpSessionListenerAdapter
  • 将 every 注入:HttpSessionListener SessionEventHttpSessionListenerAdapter

如果使用 Redis 支持,将 enableIndexingAndEvents 设置为 true, @EnableRedisHttpSession(enableIndexingAndEvents = true),所需要做的就是将每个 HttpSessionEventPublisher 注册为bean

支持 Spring Security 的并发控制,并且需要使用 HttpSessionEventPublisher。可如下配置:

Java 配置

@Configuration
@EnableRedisHttpSession
public class RedisHttpSessionConfig {

	@Bean
	public HttpSessionEventPublisher httpSessionEventPublisher() {
		return new HttpSessionEventPublisher();
	}

	// ...

}

XML 配置

<bean class="org.springframework.security.web.session.HttpSessionEventPublisher"/>

Cookie 序列化器

// tag::cookie-serializer[]
@Bean
public CookieSerializer cookieSerializer() {
    DefaultCookieSerializer serializer = new DefaultCookieSerializer();
    serializer.setCookieName("JSESSIONID");
    serializer.setCookiePath("/");
    serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
    return serializer;
}
// end::cookie-serializer[]
  1. 将cookie的名称定制为JSESSIONID
  2. 将cookie的路径定制为/(而不是默认的上下文根目录)
  3. 将cookie的域名模式定制为^.+?\.(\w+\.[a-z]+)$
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值