Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
街头小贩
Jforum2
提交
0650ed47
J
Jforum2
项目概览
街头小贩
/
Jforum2
通知
2
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
1
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
Jforum2
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
0650ed47
编写于
9月 08, 2020
作者:
街头小贩
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
thrones增加OnlineMemberRedisStorage
上级
2d937203
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
213 addition
and
21 deletion
+213
-21
thrones/pom.xml
thrones/pom.xml
+8
-2
thrones/src/main/java/com/apobates/forum/member/storage/redis/OnlineMemberRedisStorage.java
.../forum/member/storage/redis/OnlineMemberRedisStorage.java
+179
-0
thrones/src/main/java/com/apobates/forum/thrones/ThronesAppConfig.java
...ain/java/com/apobates/forum/thrones/ThronesAppConfig.java
+6
-0
thrones/src/main/java/com/apobates/forum/thrones/ThronesFrontConfig.java
...n/java/com/apobates/forum/thrones/ThronesFrontConfig.java
+18
-4
thrones/src/main/java/com/apobates/forum/thrones/controller/helper/RedisMemberStorageCondition.java
...hrones/controller/helper/RedisMemberStorageCondition.java
+1
-9
thrones/src/main/resources/global.properties
thrones/src/main/resources/global.properties
+1
-6
未找到文件。
thrones/pom.xml
浏览文件 @
0650ed47
...
...
@@ -147,8 +147,8 @@
<version>
${spring-framework.version}
</version>
<exclusions>
<exclusion>
<groupId>
commons-logging
</groupId>
<artifactId>
commons-logging
</artifactId>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-jcl
</artifactId>
</exclusion>
</exclusions>
</dependency>
...
...
@@ -215,6 +215,12 @@
<groupId>
org.springframework.session
</groupId>
<artifactId>
spring-session-core
</artifactId>
<version>
2.3.0.RELEASE
</version>
<exclusions>
<exclusion>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-jcl
</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
org.springframework.session
</groupId>
...
...
thrones/src/main/java/com/apobates/forum/member/storage/redis/OnlineMemberRedisStorage.java
0 → 100644
浏览文件 @
0650ed47
package
com.apobates.forum.member.storage.redis
;
import
com.apobates.forum.member.storage.MetaConfig
;
import
com.apobates.forum.member.storage.OnlineMemberStorage
;
import
com.apobates.forum.member.storage.cookie.CookieMetaConfig
;
import
com.apobates.forum.member.storage.core.MemberSessionBean
;
import
com.apobates.forum.member.storage.core.MemberSessionBeanConverter
;
import
com.apobates.forum.utils.Commons
;
import
com.apobates.forum.utils.CookieUtils
;
import
java.util.Map
;
import
java.util.Optional
;
import
java.util.UUID
;
import
java.util.concurrent.TimeUnit
;
import
javax.servlet.http.Cookie
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.HashOperations
;
import
org.springframework.data.redis.core.RedisTemplate
;
/**
* 使用Redis存储会员在线信息,Cookie中存储的是票根
* 支持redis 3.0.5
*
* @author xiaofanku
* @since 20200908
*/
public
class
OnlineMemberRedisStorage
implements
OnlineMemberStorage
{
@Autowired
private
CookieMetaConfig
metaConfig
;
@Autowired
private
RedisTemplate
<
String
,
Object
>
template
;
private
final
static
Logger
logger
=
LoggerFactory
.
getLogger
(
OnlineMemberRedisStorage
.
class
);
@Override
public
void
store
(
MemberSessionBean
memberSessionBean
,
HttpServletRequest
request
,
HttpServletResponse
response
)
{
if
(!
isContinue
()){
return
;
}
String
passStub
=
rndStub
();
Optional
<
String
>
afterPart
=
hash
(
passStub
,
memberSessionBean
.
getIpAddr
());
//前缀:hashValue
Map
<
String
,
String
>
val
=
MemberSessionBeanConverter
.
toMap
(
memberSessionBean
);
if
(
afterPart
.
isPresent
()
&&
null
!=
val
&&
!
val
.
isEmpty
())
{
String
key
=
metaConfig
.
getName
()
+
":"
+
afterPart
.
get
();
template
.
opsForHash
().
putAll
(
key
,
val
);
if
(
template
.
expire
(
key
,
1
,
TimeUnit
.
DAYS
))
{
serializeCookie
(
passStub
,
request
,
response
,
metaConfig
.
getName
(),
metaConfig
.
getPath
(),
metaConfig
.
getDomain
(),
metaConfig
.
isHttps
());
}
}
}
@Override
public
Optional
<
MemberSessionBean
>
query
(
long
memberId
)
{
return
Optional
.
empty
();
}
@Override
public
void
delete
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
if
(!
isContinue
()){
return
;
}
Cookie
cookie
=
CookieUtils
.
queryCookie
(
request
,
metaConfig
.
getName
()).
orElse
(
null
);
if
(
null
==
cookie
)
{
return
;
}
String
passStub
=
cookie
.
getValue
();
Optional
<
String
>
afterPart
=
hash
(
passStub
,
Commons
.
getRequestIp
(
request
));
//前缀:hashValue
if
(
afterPart
.
isPresent
())
{
if
(
template
.
delete
(
metaConfig
.
getName
()
+
":"
+
afterPart
.
get
()))
{
expireCookie
(
request
,
response
,
metaConfig
.
getName
(),
metaConfig
.
getPath
(),
metaConfig
.
getDomain
());
}
}
}
@Override
public
Optional
<
MemberSessionBean
>
getInstance
(
HttpServletRequest
request
,
String
sentinel
)
{
if
(!
isContinue
()){
return
Optional
.
empty
();
}
Cookie
cookie
=
CookieUtils
.
queryCookie
(
request
,
metaConfig
.
getName
()).
orElse
(
null
);
if
(
null
==
cookie
)
{
return
Optional
.
empty
();
}
String
passStub
=
cookie
.
getValue
();
Optional
<
String
>
afterPart
=
hash
(
passStub
,
Commons
.
getRequestIp
(
request
));
//前缀:hashValue
if
(
afterPart
.
isPresent
())
{
String
redisKey
=
metaConfig
.
getName
()
+
":"
+
afterPart
.
get
();
HashOperations
<
String
,
String
,
String
>
operation
=
template
.
opsForHash
();
Map
<
String
,
String
>
val
=
operation
.
entries
(
redisKey
);
if
(
null
!=
val
&&
!
val
.
isEmpty
())
{
return
MemberSessionBeanConverter
.
toInstance
(
val
,
Commons
.
getRequestIp
(
request
),
sentinel
);
}
}
return
Optional
.
empty
();
}
@Override
public
boolean
isSupportRevival
()
{
return
true
;
}
@Override
public
MetaConfig
getMetaConfig
()
{
return
metaConfig
;
}
private
boolean
isContinue
(){
return
null
!=
template
;
}
/**
* 序列化会员信息到Cookie中 A positive value indicates that the cookie will expire
* after that many seconds have passed.Note that the value is the maximum
age when the cookie will expire, not the cookie's current age. A negative
value means that the cookie is not stored persistently and will be
deleted when the Web browser exits. A zero value causes the cookie to be
deleted.
*
* @param cookieValue cookie中保存的值
* @param request
* @param response Http响应对象
* @param cookieSymbol cookie的Key
* @param cookiePath cookie的路径
* @param cookieDomain cookie的域名
* @param isHttps work on HTTPS/true,false work on http
*/
protected
void
serializeCookie
(
String
cookieValue
,
HttpServletRequest
request
,
HttpServletResponse
response
,
String
cookieSymbol
,
String
cookiePath
,
String
cookieDomain
,
boolean
isHttps
)
{
try
{
CookieUtils
.
serializeCookie
(
cookieValue
,
60
*
60
*
24
*
1
,
request
,
response
,
cookieSymbol
,
cookiePath
,
cookieDomain
,
isHttps
);
}
catch
(
IllegalStateException
e
)
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"[OM][CS]write cookie fail, reason: "
+
e
.
getMessage
(),
e
);
}
}
}
/**
* 清空Cookie中的会员信息
*
* @param request Http请求对象
* @param response Http响应对象
* @param cookieSymbol cookie的Key
* @param cookiePath cookie的路径
* @param cookieDomain cookie的域名
*/
protected
void
expireCookie
(
HttpServletRequest
request
,
HttpServletResponse
response
,
String
cookieSymbol
,
String
cookiePath
,
String
cookieDomain
)
{
CookieUtils
.
expireCookie
(
request
,
response
,
cookieSymbol
,
cookiePath
,
cookieDomain
);
}
/**
*
* @param stub 长度12位
* @param ipAddr ipv4
* @return
*/
private
Optional
<
String
>
hash
(
String
stub
,
String
ipAddr
){
//redis key的长度
if
(!
Commons
.
isNotBlank
(
stub
)
||
!
Commons
.
isNotBlank
(
ipAddr
)){
return
Optional
.
empty
();
}
return
Optional
.
of
(
stub
);
}
private
String
rndStub
(){
return
UUID
.
randomUUID
().
toString
().
substring
(
24
);
}
}
\ No newline at end of file
thrones/src/main/java/com/apobates/forum/thrones/ThronesAppConfig.java
浏览文件 @
0650ed47
...
...
@@ -36,6 +36,8 @@ import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
import
org.springframework.transaction.annotation.EnableTransactionManagement
;
import
java.time.Duration
;
import
org.springframework.data.redis.connection.jedis.JedisClientConfiguration
;
import
org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer
;
import
org.springframework.data.redis.serializer.StringRedisSerializer
;
import
redis.clients.jedis.JedisPoolConfig
;
/**
* Spring framework配置类
...
...
@@ -159,6 +161,10 @@ public class ThronesAppConfig {
public
RedisTemplate
<
String
,
Object
>
redisTemplate
(
RedisConnectionFactory
cf
)
{
RedisTemplate
<
String
,
Object
>
redisTemplate
=
new
RedisTemplate
<>();
redisTemplate
.
setConnectionFactory
(
cf
);
redisTemplate
.
setKeySerializer
(
new
StringRedisSerializer
());
redisTemplate
.
setValueSerializer
(
new
GenericJackson2JsonRedisSerializer
());
redisTemplate
.
setHashKeySerializer
(
new
StringRedisSerializer
());
redisTemplate
.
setHashValueSerializer
(
new
GenericJackson2JsonRedisSerializer
());
return
redisTemplate
;
}
@Bean
...
...
thrones/src/main/java/com/apobates/forum/thrones/ThronesFrontConfig.java
浏览文件 @
0650ed47
...
...
@@ -5,12 +5,15 @@ import com.apobates.forum.attention.ImageStoreDomain;
import
com.apobates.forum.core.ImageIOMeta
;
import
com.apobates.forum.member.storage.OnlineMemberStorage
;
import
com.apobates.forum.member.storage.cookie.CookieMetaConfig
;
import
com.apobates.forum.member.storage.redis.OnlineMemberRedisStorage
;
import
com.apobates.forum.thrones.controller.helper.AuthenticationInterceptor
;
import
com.apobates.forum.thrones.controller.helper.MemberInviteCodeInterceptorAdapter
;
import
com.apobates.forum.thrones.controller.helper.OnlineDescriptorAspect
;
import
com.apobates.forum.thrones.controller.helper.RedisMemberStorageCondition
;
import
com.apobates.forum.thrones.controller.helper.RegisteChannelInterceptor
;
import
com.apobates.forum.thrones.controller.helper.StrategyInterceptorAdapter
;
import
com.apobates.forum.thrones.rss.TopicRssView
;
import
com.apobates.forum.utils.Commons
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.MessageSource
;
import
org.springframework.context.annotation.Bean
;
...
...
@@ -23,7 +26,10 @@ import org.springframework.context.annotation.Import;
import
org.springframework.context.annotation.PropertySource
;
import
org.springframework.context.support.PropertySourcesPlaceholderConfigurer
;
import
org.springframework.context.support.ResourceBundleMessageSource
;
import
org.springframework.core.env.Environment
;
import
org.springframework.data.redis.connection.jedis.JedisConnectionFactory
;
import
org.springframework.http.MediaType
;
import
org.springframework.lang.Nullable
;
import
org.springframework.validation.Validator
;
import
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
;
import
org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer
;
...
...
@@ -205,11 +211,19 @@ public class ThronesFrontConfig implements WebMvcConfigurer {
return
cnf
;
}
@Bean
(
name
=
"onlineMemberStorage"
)
public
OnlineMemberStorage
getMemberStorage
(
CookieMetaConfig
cookieConfig
)
{
//cookie
return
new
com
.
apobates
.
forum
.
member
.
storage
.
cookie
.
HttpCookieProvider
(
cookieConfig
);
public
OnlineMemberStorage
getMemberStorage
(
CookieMetaConfig
cookieConfig
,
@Nullable
OnlineMemberRedisStorage
redisStorageProvider
)
{
if
(
null
==
redisStorageProvider
){
//cookie
return
new
com
.
apobates
.
forum
.
member
.
storage
.
cookie
.
HttpCookieProvider
(
cookieConfig
);
}
return
redisStorageProvider
;
}
@Bean
@Conditional
(
RedisMemberStorageCondition
.
class
)
public
OnlineMemberRedisStorage
getMemberRedisStorage
(){
//redis
return
new
com
.
apobates
.
forum
.
member
.
storage
.
redis
.
OnlineMemberRedisStorage
();
}
@Bean
(
name
=
"imageStoreDomain"
)
public
ImageStoreDomain
getImageStore
(){
return
new
com
.
apobates
.
forum
.
attention
.
ImageStoreDomain
(){
...
...
thrones/src/main/java/com/apobates/forum/thrones/controller/helper/RedisMemberStorageCondition.java
浏览文件 @
0650ed47
package
com.apobates.forum.thrones.controller.helper
;
import
com.apobates.forum.utils.Commons
;
import
org.springframework.context.annotation.Condition
;
import
org.springframework.context.annotation.ConditionContext
;
import
org.springframework.core.env.Environment
;
...
...
@@ -17,13 +16,6 @@ public class RedisMemberStorageCondition implements Condition{
@Override
public
boolean
matches
(
ConditionContext
cc
,
AnnotatedTypeMetadata
atm
)
{
Environment
env
=
cc
.
getEnvironment
();
if
(
null
==
env
){
return
false
;
}
return
Commons
.
isNotBlank
(
env
.
getProperty
(
"redis.host"
))
&&
Commons
.
isNotBlank
(
env
.
getProperty
(
"redis.port"
))
&&
Commons
.
isNotBlank
(
env
.
getProperty
(
"redis.timeout"
))
&&
Commons
.
isNotBlank
(
env
.
getProperty
(
"redis.database"
))
&&
Commons
.
isNotBlank
(
env
.
getProperty
(
"redis.password"
));
return
null
!=
env
&&
"true"
.
equalsIgnoreCase
(
env
.
getProperty
(
"site.member.redis"
));
}
}
\ No newline at end of file
thrones/src/main/resources/global.properties
浏览文件 @
0650ed47
...
...
@@ -27,6 +27,7 @@ site.defat.avtar=avatar
site.member.freeze
=
10
site.member.invite
=
false
site.member.register
=
true
site.member.redis
=
true
site.meta.description
=
In this tutorial we show a Spring MVC RSS ATOM Content Negotiation example. Using Content Negotiation we can serve different versions of a document (or resource) at the same URI.
# \u83b7\u53d6\u5931\u8d25\u65f6\u663e\u793a\u7684\u56fe\u7247
site.upload.fail
=
static/image/photo_album.jpg
...
...
@@ -55,12 +56,6 @@ jpa.vendor=MYSQL
jpa.log
=
/home/admin/logs/jforum-sql.log
jpa.plat
=
org.eclipse.persistence.platform.database.MySQLPlatform
jpa.batch.size
=
1000
# redis member storage
# redis.host=127.0.0.1
# redis.port=6379
# redis.timeout=60
# redis.password=jedisroot
# redis.database=0
# redis cache provider
cache.redis.host
=
127.0.0.1
cache.redis.port
=
6379
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录