Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
bf712957
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
GitCode(gitcode.net)2024年7月9日维护升级公告
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
bf712957
编写于
7月 14, 2017
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Polish WebSession support code
上级
c802827f
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
90 addition
and
69 deletion
+90
-69
spring-web/src/main/java/org/springframework/web/server/session/CookieWebSessionIdResolver.java
...mework/web/server/session/CookieWebSessionIdResolver.java
+10
-1
spring-web/src/main/java/org/springframework/web/server/session/DefaultWebSessionManager.java
...ramework/web/server/session/DefaultWebSessionManager.java
+51
-46
spring-web/src/main/java/org/springframework/web/server/session/WebSessionIdResolver.java
...ingframework/web/server/session/WebSessionIdResolver.java
+9
-4
spring-web/src/main/java/org/springframework/web/server/session/WebSessionManager.java
...springframework/web/server/session/WebSessionManager.java
+4
-10
spring-web/src/main/java/org/springframework/web/server/session/WebSessionStore.java
...g/springframework/web/server/session/WebSessionStore.java
+8
-8
spring-web/src/test/java/org/springframework/web/server/session/DefaultWebSessionManagerTests.java
...ork/web/server/session/DefaultWebSessionManagerTests.java
+8
-0
未找到文件。
spring-web/src/main/java/org/springframework/web/server/session/CookieWebSessionIdResolver.java
浏览文件 @
bf712957
...
...
@@ -87,8 +87,17 @@ public class CookieWebSessionIdResolver implements WebSessionIdResolver {
@Override
public
void
setSessionId
(
ServerWebExchange
exchange
,
String
id
)
{
Assert
.
notNull
(
id
,
"'id' is required"
);
setSessionCookie
(
exchange
,
id
,
getCookieMaxAge
());
}
@Override
public
void
expireSession
(
ServerWebExchange
exchange
)
{
setSessionCookie
(
exchange
,
""
,
Duration
.
ofSeconds
(
0
));
}
private
void
setSessionCookie
(
ServerWebExchange
exchange
,
String
id
,
Duration
maxAge
)
{
String
name
=
getCookieName
();
Duration
maxAge
=
(
StringUtils
.
hasText
(
id
)
?
getCookieMaxAge
()
:
Duration
.
ofSeconds
(
0
));
boolean
secure
=
"https"
.
equalsIgnoreCase
(
exchange
.
getRequest
().
getURI
().
getScheme
());
MultiValueMap
<
String
,
ResponseCookie
>
cookieMap
=
exchange
.
getResponse
().
getCookies
();
cookieMap
.
set
(
name
,
ResponseCookie
.
from
(
name
,
id
).
maxAge
(
maxAge
).
httpOnly
(
true
).
secure
(
secure
).
build
());
...
...
spring-web/src/main/java/org/springframework/web/server/session/DefaultWebSessionManager.java
浏览文件 @
bf712957
...
...
@@ -30,8 +30,9 @@ import org.springframework.web.server.WebSession;
/**
* Default implementation of {@link WebSessionManager} with a cookie-based web
* session id resolution strategy and simple in-memory session persistence.
* Default implementation of {@link WebSessionManager} delegating to a
* {@link WebSessionIdResolver} for session id resolution and to a
* {@link WebSessionStore}
*
* @author Rossen Stoyanchev
* @since 5.0
...
...
@@ -46,12 +47,12 @@ public class DefaultWebSessionManager implements WebSessionManager {
/**
* Configure the
session id resolution strategy to use
.
* <p>By default
{@link CookieWebSessionIdResolver} is used
.
* @param sessionIdResolver the resolver
* Configure the
id resolution strategy
.
* <p>By default
an instance of {@link CookieWebSessionIdResolver}
.
* @param sessionIdResolver the resolver
to use
*/
public
void
setSessionIdResolver
(
WebSessionIdResolver
sessionIdResolver
)
{
Assert
.
notNull
(
sessionIdResolver
,
"
'sessionIdResolver'
is required."
);
Assert
.
notNull
(
sessionIdResolver
,
"
WebSessionIdResolver
is required."
);
this
.
sessionIdResolver
=
sessionIdResolver
;
}
...
...
@@ -63,12 +64,12 @@ public class DefaultWebSessionManager implements WebSessionManager {
}
/**
* Configure the
session persistence strategy to use
.
* <p>By default
{@link InMemoryWebSessionStore} is used
.
* @param sessionStore the persistence strategy
* Configure the
persistence strategy
.
* <p>By default
an instance of {@link InMemoryWebSessionStore}
.
* @param sessionStore the persistence strategy
to use
*/
public
void
setSessionStore
(
WebSessionStore
sessionStore
)
{
Assert
.
notNull
(
sessionStore
,
"
'sessionStore'
is required."
);
Assert
.
notNull
(
sessionStore
,
"
WebSessionStore
is required."
);
this
.
sessionStore
=
sessionStore
;
}
...
...
@@ -80,10 +81,12 @@ public class DefaultWebSessionManager implements WebSessionManager {
}
/**
* Configure the {@link Clock} for access to current time. During tests you
* may use {code Clock.offset(clock, Duration.ofMinutes(-31))} to set the
* clock back for example to test changes after sessions expire.
* <p>By default {@code Clock.system(ZoneId.of("GMT"))} is used.
* Configure the {@link Clock} to use to set lastAccessTime on every created
* session and to calculate if it is expired.
* <p>This may be useful to align to different timezone or to set the clock
* back in a test, e.g. {@code Clock.offset(clock, Duration.ofMinutes(-31))}
* in order to simulate session expiration.
* <p>By default this is {@code Clock.system(ZoneId.of("GMT"))}.
* @param clock the clock to use
*/
public
void
setClock
(
Clock
clock
)
{
...
...
@@ -92,7 +95,7 @@ public class DefaultWebSessionManager implements WebSessionManager {
}
/**
* Return the configured clock for
access to current time
.
* Return the configured clock for
session lastAccessTime calculations
.
*/
public
Clock
getClock
()
{
return
this
.
clock
;
...
...
@@ -102,48 +105,45 @@ public class DefaultWebSessionManager implements WebSessionManager {
@Override
public
Mono
<
WebSession
>
getSession
(
ServerWebExchange
exchange
)
{
return
Mono
.
defer
(()
->
Flux
.
fromIterable
(
getSessionIdResolver
().
resolveSessionIds
(
exchange
))
.
concatMap
(
this
.
sessionStore
::
retrieveSession
)
.
next
()
.
flatMap
(
session
->
validateSession
(
exchange
,
session
))
.
switchIfEmpty
(
createSession
(
exchange
))
.
map
(
session
->
extendSession
(
exchange
,
session
)));
retrieveSession
(
exchange
)
.
flatMap
(
session
->
removeSessionIfExpired
(
exchange
,
session
))
.
switchIfEmpty
(
createSession
())
.
doOnNext
(
session
->
{
if
(
session
instanceof
ConfigurableWebSession
)
{
ConfigurableWebSession
configurable
=
(
ConfigurableWebSession
)
session
;
configurable
.
setSaveOperation
(()
->
saveSession
(
exchange
,
session
));
configurable
.
setLastAccessTime
(
Instant
.
now
(
getClock
()));
}
exchange
.
getResponse
().
beforeCommit
(
session:
:
save
);
}));
}
protected
Mono
<
WebSession
>
validateSession
(
ServerWebExchange
exchange
,
WebSession
session
)
{
private
Mono
<
WebSession
>
retrieveSession
(
ServerWebExchange
exchange
)
{
return
Flux
.
fromIterable
(
getSessionIdResolver
().
resolveSessionIds
(
exchange
))
.
concatMap
(
this
.
sessionStore
::
retrieveSession
)
.
next
();
}
private
Mono
<
WebSession
>
removeSessionIfExpired
(
ServerWebExchange
exchange
,
WebSession
session
)
{
if
(
session
.
isExpired
())
{
this
.
sessionIdResolver
.
setSessionId
(
exchange
,
""
);
return
this
.
sessionStore
.
removeSession
(
session
.
getId
()).
cast
(
WebSession
.
class
);
}
else
{
return
Mono
.
just
(
session
);
return
this
.
sessionStore
.
removeSession
(
session
.
getId
()).
then
(
Mono
.
empty
());
}
}
protected
Mono
<
WebSession
>
createSession
(
ServerWebExchange
exchange
)
{
String
sessionId
=
UUID
.
randomUUID
().
toString
();
WebSession
session
=
new
DefaultWebSession
(
sessionId
,
getClock
());
return
Mono
.
just
(
session
);
}
protected
WebSession
extendSession
(
ServerWebExchange
exchange
,
WebSession
session
)
{
if
(
session
instanceof
ConfigurableWebSession
)
{
ConfigurableWebSession
managed
=
(
ConfigurableWebSession
)
session
;
managed
.
setSaveOperation
(()
->
saveSession
(
exchange
,
session
));
managed
.
setLastAccessTime
(
Instant
.
now
(
getClock
()));
}
exchange
.
getResponse
().
beforeCommit
(
session:
:
save
);
return
session
;
private
Mono
<
DefaultWebSession
>
createSession
()
{
return
Mono
.
fromSupplier
(()
->
new
DefaultWebSession
(
UUID
.
randomUUID
().
toString
(),
getClock
()));
}
protected
Mono
<
Void
>
saveSession
(
ServerWebExchange
exchange
,
WebSession
session
)
{
private
Mono
<
Void
>
saveSession
(
ServerWebExchange
exchange
,
WebSession
session
)
{
if
(
session
.
isExpired
())
{
return
Mono
.
error
(
new
IllegalStateException
(
"Sessions are checked for expiration and have their "
+
"
access t
ime updated when first accessed during request processing. "
+
"
lastAccessT
ime updated when first accessed during request processing. "
+
"However this session is expired meaning that maxIdleTime elapsed "
+
"
since then and
before the call to session.save()."
));
"before the call to session.save()."
));
}
if
(!
session
.
isStarted
())
{
...
...
@@ -153,11 +153,16 @@ public class DefaultWebSessionManager implements WebSessionManager {
// Force explicit start
session
.
start
();
List
<
String
>
requestedIds
=
getSessionIdResolver
().
resolveSessionIds
(
exchange
);
if
(
requestedIds
.
isEmpty
()
||
!
session
.
getId
().
equals
(
requestedIds
.
get
(
0
)))
{
if
(
hasNewSessionId
(
exchange
,
session
))
{
this
.
sessionIdResolver
.
setSessionId
(
exchange
,
session
.
getId
());
}
return
this
.
sessionStore
.
storeSession
(
session
);
return
this
.
sessionStore
.
storeSession
(
session
);
}
private
boolean
hasNewSessionId
(
ServerWebExchange
exchange
,
WebSession
session
)
{
List
<
String
>
ids
=
getSessionIdResolver
().
resolveSessionIds
(
exchange
);
return
ids
.
isEmpty
()
||
!
session
.
getId
().
equals
(
ids
.
get
(
0
));
}
}
spring-web/src/main/java/org/springframework/web/server/session/WebSessionIdResolver.java
浏览文件 @
bf712957
...
...
@@ -22,8 +22,8 @@ import org.springframework.web.server.ServerWebExchange;
/**
* Contract for session id resolution strategies. Allows for session id
* resolution through the request and for sending the session id
to the
*
client
through the response.
* resolution through the request and for sending the session id
or expiring
*
the session
through the response.
*
* @author Rossen Stoyanchev
* @since 5.0
...
...
@@ -39,11 +39,16 @@ public interface WebSessionIdResolver {
List
<
String
>
resolveSessionIds
(
ServerWebExchange
exchange
);
/**
* Send the given session id to the client or if the session id is "null"
* instruct the client to end the current session.
* Send the given session id to the client.
* @param exchange the current exchange
* @param sessionId the session id
*/
void
setSessionId
(
ServerWebExchange
exchange
,
String
sessionId
);
/**
* Instruct the client to end the current session.
* @param exchange the current exchange
*/
void
expireSession
(
ServerWebExchange
exchange
);
}
spring-web/src/main/java/org/springframework/web/server/session/WebSessionManager.java
浏览文件 @
bf712957
...
...
@@ -21,13 +21,7 @@ import org.springframework.web.server.ServerWebExchange;
import
org.springframework.web.server.WebSession
;
/**
* Main contract abstracting support for access to {@link WebSession} instances
* associated with HTTP requests as well as the subsequent management such as
* persistence and others.
*
* <p>The {@link DefaultWebSessionManager} implementation in turn delegates to
* {@link WebSessionIdResolver} and {@link WebSessionStore} which abstract
* underlying concerns related to the management of web sessions.
* Main class for for access to the {@link WebSession} for an HTTP request.
*
* @author Rossen Stoyanchev
* @since 5.0
...
...
@@ -39,10 +33,10 @@ public interface WebSessionManager {
/**
* Return the {@link WebSession} for the given exchange. Always guaranteed
* to return an instance either matching to the session id requested by the
* client, or
with a new session id either because the client did not
*
specify one or because the underlying session had
expired.
* client, or
a new session either because the client did not specify one
*
or because the underlying session
expired.
* @param exchange the current exchange
* @return
{@code Mono} for async access to the s
ession
* @return
promise for the WebS
ession
*/
Mono
<
WebSession
>
getSession
(
ServerWebExchange
exchange
);
...
...
spring-web/src/main/java/org/springframework/web/server/session/WebSessionStore.java
浏览文件 @
bf712957
/*
* Copyright 2002-201
6
the original author or authors.
* Copyright 2002-201
7
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -28,23 +28,23 @@ import org.springframework.web.server.WebSession;
public
interface
WebSessionStore
{
/**
* Store the given
s
ession.
* Store the given
WebS
ession.
* @param session the session to store
* @return
{@code Mono} for completion notification
* @return
a completion notification (success or error)
*/
Mono
<
Void
>
storeSession
(
WebSession
session
);
/**
*
Load the session for the given sessio
n id.
*
Return the WebSession for the give
n id.
* @param sessionId the session to load
* @return
{@code Mono} for async access to the loaded session
* @return
the session, or an empty {@code Mono}.
*/
Mono
<
WebSession
>
retrieveSession
(
String
sessionId
);
/**
* Remove the
session with the given
id.
* @param sessionId the session to remove
* @return
{@code Mono} for completion notification
* Remove the
WebSession for the specified
id.
* @param sessionId the
id of the
session to remove
* @return
a completion notification (success or error)
*/
Mono
<
Void
>
removeSession
(
String
sessionId
);
...
...
spring-web/src/test/java/org/springframework/web/server/session/DefaultWebSessionManagerTests.java
浏览文件 @
bf712957
...
...
@@ -27,6 +27,7 @@ import org.junit.Before;
import
org.junit.Test
;
import
org.springframework.http.codec.ServerCodecConfigurer
;
import
org.springframework.lang.Nullable
;
import
org.springframework.mock.http.server.reactive.test.MockServerHttpRequest
;
import
org.springframework.mock.http.server.reactive.test.MockServerHttpResponse
;
import
org.springframework.web.server.ServerWebExchange
;
...
...
@@ -139,6 +140,7 @@ public class DefaultWebSessionManagerTests {
private
List
<
String
>
idsToResolve
=
new
ArrayList
<>();
@Nullable
private
String
id
=
null
;
...
...
@@ -146,6 +148,7 @@ public class DefaultWebSessionManagerTests {
this
.
idsToResolve
=
idsToResolve
;
}
@Nullable
public
String
getSavedId
()
{
return
this
.
id
;
}
...
...
@@ -159,6 +162,11 @@ public class DefaultWebSessionManagerTests {
public
void
setSessionId
(
ServerWebExchange
exchange
,
String
sessionId
)
{
this
.
id
=
sessionId
;
}
@Override
public
void
expireSession
(
ServerWebExchange
exchange
)
{
this
.
id
=
null
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录