mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-05 17:37:53 +08:00
refactor: 重构 sa-token-redisson 插件
This commit is contained in:
parent
6b273a3181
commit
f3cec926c6
@ -136,7 +136,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.dev33</groupId>
|
<groupId>cn.dev33</groupId>
|
||||||
<artifactId>sa-token-redisson-jackson</artifactId>
|
<artifactId>sa-token-redisson</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -42,9 +42,14 @@
|
|||||||
<!-- Sa-Token整合 Redisson (使用jackson序列化方式) -->
|
<!-- Sa-Token整合 Redisson (使用jackson序列化方式) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.dev33</groupId>
|
<groupId>cn.dev33</groupId>
|
||||||
<artifactId>sa-token-redisson-jackson</artifactId>
|
<artifactId>sa-token-redisson</artifactId>
|
||||||
<version>${sa-token.version}</version>
|
<version>${sa-token.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-jackson</artifactId>
|
||||||
|
<version>${sa-token.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- 无需提供Redis连接池 Redisson使用Netty管理 -->
|
<!-- 无需提供Redis连接池 Redisson使用Netty管理 -->
|
||||||
<!-- <dependency>-->
|
<!-- <dependency>-->
|
||||||
|
@ -41,11 +41,11 @@
|
|||||||
<module>sa-token-spring-el</module>
|
<module>sa-token-spring-el</module>
|
||||||
<module>sa-token-grpc</module>
|
<module>sa-token-grpc</module>
|
||||||
<module>sa-token-quick-login</module>
|
<module>sa-token-quick-login</module>
|
||||||
|
<module>sa-token-redisson</module>
|
||||||
|
|
||||||
<!-- Solon 环境插件 -->
|
<!-- Solon 环境插件 -->
|
||||||
<module>sa-token-redisx</module>
|
<module>sa-token-redisx</module>
|
||||||
|
|
||||||
<module>sa-token-redisson-jackson</module>
|
|
||||||
<module>sa-token-redisson-jackson2</module>
|
<module>sa-token-redisson-jackson2</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
@ -28,6 +28,13 @@ public class SaSessionForFastjsonCustomized extends SaSession {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -7600983549653130681L;
|
private static final long serialVersionUID = -7600983549653130681L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建一个 SaSession 对象
|
||||||
|
*/
|
||||||
|
public SaSessionForFastjsonCustomized() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建一个 SaSession 对象
|
* 构建一个 SaSession 对象
|
||||||
* @param id Session 的 id
|
* @param id Session 的 id
|
||||||
|
@ -28,6 +28,13 @@ public class SaSessionForFastjson2Customized extends SaSession {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -7600983549653130681L;
|
private static final long serialVersionUID = -7600983549653130681L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建一个 SaSession 对象
|
||||||
|
*/
|
||||||
|
public SaSessionForFastjson2Customized() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建一个 SaSession 对象
|
* 构建一个 SaSession 对象
|
||||||
* @param id Session 的 id
|
* @param id Session 的 id
|
||||||
|
@ -106,7 +106,11 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String objectToJson(Object obj) {
|
public String objectToJson(Object obj) {
|
||||||
|
if(SaFoxUtil.isEmpty(obj)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
|
System.out.println("序列化的啥:" + objectMapper.writeValueAsString(obj));
|
||||||
return objectMapper.writeValueAsString(obj);
|
return objectMapper.writeValueAsString(obj);
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
throw new SaJsonConvertException(e);
|
throw new SaJsonConvertException(e);
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020-2099 sa-token.cc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.dev33.satoken.dao;
|
|
||||||
|
|
||||||
import cn.dev33.satoken.session.SaSession;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Jackson定制版SaSession,忽略 timeout 等属性的序列化
|
|
||||||
*
|
|
||||||
* @author click33
|
|
||||||
* @since 1.34.0
|
|
||||||
*/
|
|
||||||
@JsonIgnoreProperties({"timeout"})
|
|
||||||
public class SaSessionForJacksonCustomized extends SaSession {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = -7600983549653130681L;
|
|
||||||
|
|
||||||
public SaSessionForJacksonCustomized() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建一个Session对象
|
|
||||||
* @param id Session的id
|
|
||||||
*/
|
|
||||||
public SaSessionForJacksonCustomized(String id) {
|
|
||||||
super(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,311 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020-2099 sa-token.cc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.dev33.satoken.dao;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.LocalTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.redisson.api.RBatch;
|
|
||||||
import org.redisson.api.RBucket;
|
|
||||||
import org.redisson.api.RBucketAsync;
|
|
||||||
import org.redisson.api.RedissonClient;
|
|
||||||
import org.redisson.client.codec.Codec;
|
|
||||||
import org.redisson.codec.JsonJacksonCodec;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
|
||||||
|
|
||||||
import cn.dev33.satoken.strategy.SaStrategy;
|
|
||||||
import cn.dev33.satoken.util.SaFoxUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sa-Token 持久层实现 [ Redisson客户端、Redis存储、Jackson序列化 ]
|
|
||||||
*
|
|
||||||
* @author 疯狂的狮子Li
|
|
||||||
* @since 1.34.0
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class SaTokenDaoRedissonJackson implements SaTokenDao {
|
|
||||||
|
|
||||||
public static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
|
||||||
public static final String DATE_PATTERN = "yyyy-MM-dd";
|
|
||||||
public static final String TIME_PATTERN = "HH:mm:ss";
|
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DATE_TIME_PATTERN);
|
|
||||||
public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DATE_PATTERN);
|
|
||||||
public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(TIME_PATTERN);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ObjectMapper 对象 (以 public 作用域暴露出此对象,方便开发者二次更改配置)
|
|
||||||
*
|
|
||||||
* <p> 例如:
|
|
||||||
* <pre>
|
|
||||||
* SaTokenDaoRedisJackson redisJackson = (SaTokenDaoRedisJackson) SaManager.getSaTokenDao();
|
|
||||||
* redisJackson.objectMapper.xxx = xxx;
|
|
||||||
* </pre>
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 序列化方式
|
|
||||||
*/
|
|
||||||
public Codec codec;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* redisson 客户端
|
|
||||||
*/
|
|
||||||
public RedissonClient redissonClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标记:是否已初始化成功
|
|
||||||
*/
|
|
||||||
public boolean isInit;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public void init(RedissonClient redissonClient) {
|
|
||||||
// 不重复初始化
|
|
||||||
if(this.isInit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 指定相应的序列化方案
|
|
||||||
GenericJackson2JsonRedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer();
|
|
||||||
// 通过反射获取Mapper对象, 增加一些配置, 增强兼容性
|
|
||||||
try {
|
|
||||||
Field field = GenericJackson2JsonRedisSerializer.class.getDeclaredField("mapper");
|
|
||||||
field.setAccessible(true);
|
|
||||||
this.objectMapper = (ObjectMapper) field.get(valueSerializer);
|
|
||||||
// 配置[忽略未知字段]
|
|
||||||
this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
|
||||||
// 配置[时间类型转换]
|
|
||||||
JavaTimeModule timeModule = new JavaTimeModule();
|
|
||||||
// LocalDateTime序列化与反序列化
|
|
||||||
timeModule.addSerializer(new LocalDateTimeSerializer(DATE_TIME_FORMATTER));
|
|
||||||
timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_TIME_FORMATTER));
|
|
||||||
// LocalDate序列化与反序列化
|
|
||||||
timeModule.addSerializer(new LocalDateSerializer(DATE_FORMATTER));
|
|
||||||
timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DATE_FORMATTER));
|
|
||||||
// LocalTime序列化与反序列化
|
|
||||||
timeModule.addSerializer(new LocalTimeSerializer(TIME_FORMATTER));
|
|
||||||
timeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(TIME_FORMATTER));
|
|
||||||
this.objectMapper.registerModule(timeModule);
|
|
||||||
// 重写 SaSession 生成策略
|
|
||||||
SaStrategy.instance.createSession = (sessionId) -> new SaSessionForJacksonCustomized(sessionId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 开始初始化相关组件
|
|
||||||
this.codec = new JsonJacksonCodec(objectMapper);
|
|
||||||
this.redissonClient = redissonClient;
|
|
||||||
this.isInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取Value,如无返空
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String get(String key) {
|
|
||||||
RBucket<String> rBucket = redissonClient.getBucket(key, codec);
|
|
||||||
return rBucket.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 写入Value,并设定存活时间 (单位: 秒)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void set(String key, String value, long timeout) {
|
|
||||||
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 判断是否为永不过期
|
|
||||||
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
|
||||||
RBucket<String> bucket = redissonClient.getBucket(key, codec);
|
|
||||||
bucket.set(value);
|
|
||||||
} else {
|
|
||||||
RBatch batch = redissonClient.createBatch();
|
|
||||||
RBucketAsync<String> bucket = batch.getBucket(key, codec);
|
|
||||||
bucket.setAsync(value);
|
|
||||||
bucket.expireAsync(Duration.ofSeconds(timeout));
|
|
||||||
batch.execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修修改指定key-value键值对 (过期时间不变)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void update(String key, String value) {
|
|
||||||
long expire = getTimeout(key);
|
|
||||||
// -2 = 无此键
|
|
||||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.set(key, value, expire);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除Value
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void delete(String key) {
|
|
||||||
redissonClient.getBucket(key, codec).delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取Value的剩余存活时间 (单位: 秒)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public long getTimeout(String key) {
|
|
||||||
RBucket<String> rBucket = redissonClient.getBucket(key, codec);
|
|
||||||
long timeout = rBucket.remainTimeToLive();
|
|
||||||
return timeout < 0 ? timeout : timeout / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改Value的剩余存活时间 (单位: 秒)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void updateTimeout(String key, long timeout) {
|
|
||||||
// 判断是否想要设置为永久
|
|
||||||
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
|
||||||
long expire = getTimeout(key);
|
|
||||||
if(expire == SaTokenDao.NEVER_EXPIRE) {
|
|
||||||
// 如果其已经被设置为永久,则不作任何处理
|
|
||||||
} else {
|
|
||||||
// 如果尚未被设置为永久,那么再次set一次
|
|
||||||
this.set(key, this.get(key), timeout);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RBucket<String> rBucket = redissonClient.getBucket(key, codec);
|
|
||||||
rBucket.expire(Duration.ofSeconds(timeout));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取Object,如无返空
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object getObject(String key) {
|
|
||||||
RBucket<Object> rBucket = redissonClient.getBucket(key, codec);
|
|
||||||
return rBucket.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 写入Object,并设定存活时间 (单位: 秒)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setObject(String key, Object object, long timeout) {
|
|
||||||
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 判断是否为永不过期
|
|
||||||
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
|
||||||
RBucket<Object> bucket = redissonClient.getBucket(key, codec);
|
|
||||||
bucket.set(object);
|
|
||||||
} else {
|
|
||||||
RBatch batch = redissonClient.createBatch();
|
|
||||||
RBucketAsync<Object> bucket = batch.getBucket(key, codec);
|
|
||||||
bucket.setAsync(object);
|
|
||||||
bucket.expireAsync(Duration.ofSeconds(timeout));
|
|
||||||
batch.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新Object (过期时间不变)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void updateObject(String key, Object object) {
|
|
||||||
long expire = getObjectTimeout(key);
|
|
||||||
// -2 = 无此键
|
|
||||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setObject(key, object, expire);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除Object
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteObject(String key) {
|
|
||||||
redissonClient.getBucket(key, codec).delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取Object的剩余存活时间 (单位: 秒)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public long getObjectTimeout(String key) {
|
|
||||||
RBucket<String> rBucket = redissonClient.getBucket(key, codec);
|
|
||||||
long timeout = rBucket.remainTimeToLive();
|
|
||||||
return timeout < 0 ? timeout : timeout / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改Object的剩余存活时间 (单位: 秒)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void updateObjectTimeout(String key, long timeout) {
|
|
||||||
// 判断是否想要设置为永久
|
|
||||||
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
|
||||||
long expire = getObjectTimeout(key);
|
|
||||||
if(expire == SaTokenDao.NEVER_EXPIRE) {
|
|
||||||
// 如果其已经被设置为永久,则不作任何处理
|
|
||||||
} else {
|
|
||||||
// 如果尚未被设置为永久,那么再次set一次
|
|
||||||
this.setObject(key, this.getObject(key), timeout);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RBucket<Object> rBucket = redissonClient.getBucket(key, codec);
|
|
||||||
rBucket.expire(Duration.ofSeconds(timeout));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搜索数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
|
|
||||||
Stream<String> stream = redissonClient.getKeys().getKeysStreamByPattern(prefix + "*" + keyword + "*");
|
|
||||||
List<String> list = stream.collect(Collectors.toList());
|
|
||||||
return SaFoxUtil.searchList(list, start, size, sortType);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
cn.dev33.satoken.dao.SaTokenDaoRedissonJackson
|
|
@ -13,7 +13,7 @@
|
|||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>sa-token-redisson-jackson</name>
|
<name>sa-token-redisson-jackson</name>
|
||||||
<artifactId>sa-token-redisson-jackson</artifactId>
|
<artifactId>sa-token-redisson</artifactId>
|
||||||
<description>sa-token integrate redisson (to jackson)</description>
|
<description>sa-token integrate redisson (to jackson)</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -28,19 +28,6 @@
|
|||||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- jackson-databind -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
<!-- jackson-datatype-jsr310 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
|
||||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020-2099 sa-token.cc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.dev33.satoken.dao;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.dao.auto.SaTokenDaoByObjectFollowStringUseJsonSerializer;
|
||||||
|
import cn.dev33.satoken.util.SaFoxUtil;
|
||||||
|
import org.redisson.api.RBatch;
|
||||||
|
import org.redisson.api.RBucket;
|
||||||
|
import org.redisson.api.RBucketAsync;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sa-Token 持久层实现 [ Redisson客户端、Redis存储、Jackson序列化 ]
|
||||||
|
*
|
||||||
|
* @author 疯狂的狮子Li
|
||||||
|
* @since 1.34.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SaTokenDaoForRedisson implements SaTokenDaoByObjectFollowStringUseJsonSerializer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* redisson 客户端
|
||||||
|
*/
|
||||||
|
public RedissonClient redissonClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记:是否已初始化成功
|
||||||
|
*/
|
||||||
|
public boolean isInit;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void init(RedissonClient redissonClient) {
|
||||||
|
// 不重复初始化
|
||||||
|
if(this.isInit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始初始化相关组件
|
||||||
|
this.redissonClient = redissonClient;
|
||||||
|
this.isInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Value,如无返空
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String get(String key) {
|
||||||
|
RBucket<String> rBucket = redissonClient.getBucket(key);
|
||||||
|
return rBucket.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写入Value,并设定存活时间 (单位: 秒)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void set(String key, String value, long timeout) {
|
||||||
|
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 判断是否为永不过期
|
||||||
|
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
||||||
|
RBucket<String> bucket = redissonClient.getBucket(key);
|
||||||
|
bucket.set(value);
|
||||||
|
} else {
|
||||||
|
RBatch batch = redissonClient.createBatch();
|
||||||
|
RBucketAsync<String> bucket = batch.getBucket(key);
|
||||||
|
bucket.setAsync(value);
|
||||||
|
bucket.expireAsync(Duration.ofSeconds(timeout));
|
||||||
|
batch.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修修改指定key-value键值对 (过期时间不变)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void update(String key, String value) {
|
||||||
|
long expire = getTimeout(key);
|
||||||
|
// -2 = 无此键
|
||||||
|
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.set(key, value, expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除Value
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void delete(String key) {
|
||||||
|
redissonClient.getBucket(key).delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Value的剩余存活时间 (单位: 秒)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getTimeout(String key) {
|
||||||
|
RBucket<String> rBucket = redissonClient.getBucket(key);
|
||||||
|
long timeout = rBucket.remainTimeToLive();
|
||||||
|
return timeout < 0 ? timeout : timeout / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改Value的剩余存活时间 (单位: 秒)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void updateTimeout(String key, long timeout) {
|
||||||
|
// 判断是否想要设置为永久
|
||||||
|
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
||||||
|
long expire = getTimeout(key);
|
||||||
|
if(expire == SaTokenDao.NEVER_EXPIRE) {
|
||||||
|
// 如果其已经被设置为永久,则不作任何处理
|
||||||
|
} else {
|
||||||
|
// 如果尚未被设置为永久,那么再次set一次
|
||||||
|
this.set(key, this.get(key), timeout);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RBucket<String> rBucket = redissonClient.getBucket(key);
|
||||||
|
rBucket.expire(Duration.ofSeconds(timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
|
||||||
|
Stream<String> stream = redissonClient.getKeys().getKeysStreamByPattern(prefix + "*" + keyword + "*");
|
||||||
|
List<String> list = stream.collect(Collectors.toList());
|
||||||
|
return SaFoxUtil.searchList(list, start, size, sortType);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.dao.SaTokenDaoRedissonJackson
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.dao.SaTokenDaoForRedisson
|
@ -0,0 +1 @@
|
|||||||
|
cn.dev33.satoken.dao.SaTokenDaoForRedisson
|
Loading…
Reference in New Issue
Block a user