mirror of
https://gitee.com/orangeform/orange-admin.git
synced 2026-01-18 02:56:30 +08:00
commit:1.6版本发布
This commit is contained in:
@@ -8,6 +8,22 @@ package com.orange.demo.common.core.constant;
|
||||
*/
|
||||
public final class ApplicationConstant {
|
||||
|
||||
/**
|
||||
* 数据同步使用的缺省消息队列主题名称。
|
||||
*/
|
||||
public static final String DEFAULT_DATA_SYNC_TOPIC = "OrangeMultiDemo";
|
||||
/**
|
||||
* 全量数据同步中,新增数据对象的键名称。
|
||||
*/
|
||||
public static final String DEFAULT_FULL_SYNC_DATA_KEY = "data";
|
||||
/**
|
||||
* 全量数据同步中,原有数据对象的键名称。
|
||||
*/
|
||||
public static final String DEFAULT_FULL_SYNC_OLD_DATA_KEY = "oldData";
|
||||
/**
|
||||
* 全量数据同步中,数据对象主键的键名称。
|
||||
*/
|
||||
public static final String DEFAULT_FULL_SYNC_ID_KEY = "id";
|
||||
/**
|
||||
* 为字典表数据缓存时,缓存名称的固定后缀。
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.orange.demo.common.core.exception;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 无效的Redis模式的自定义异常。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class InvalidRedisModeException extends RuntimeException {
|
||||
|
||||
private final String mode;
|
||||
|
||||
/**
|
||||
* 构造函数。
|
||||
*
|
||||
* @param mode 错误的模式。
|
||||
*/
|
||||
public InvalidRedisModeException(String mode) {
|
||||
super("Invalid Redis Mode [" + mode + "], only supports [single/cluster/sentinel/master_slave]");
|
||||
this.mode = mode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.orange.demo.common.core.object;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 在线登录用户信息。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
@Slf4j
|
||||
public class LoginUserInfo {
|
||||
|
||||
/**
|
||||
* 用户Id。
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户所在部门Id。
|
||||
* 仅当系统支持uaa时可用,否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
|
||||
*/
|
||||
private Long deptId;
|
||||
/**
|
||||
* 租户Id。
|
||||
* 仅当系统支持uaa时可用,否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
|
||||
*/
|
||||
private Long tenantId;
|
||||
/**
|
||||
* 是否为超级管理员。
|
||||
*/
|
||||
private Boolean isAdmin;
|
||||
/**
|
||||
* 用户登录名。
|
||||
*/
|
||||
private String loginName;
|
||||
/**
|
||||
* 用户显示名称。
|
||||
*/
|
||||
private String showName;
|
||||
/**
|
||||
* 标识不同登录的会话Id。
|
||||
*/
|
||||
private String sessionId;
|
||||
/**
|
||||
* 登录IP。
|
||||
*/
|
||||
private String loginIp;
|
||||
/**
|
||||
* 登录时间。
|
||||
*/
|
||||
private Date loginTime;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.orange.demo.common.core.constant.ErrorCodeEnum;
|
||||
import com.orange.demo.common.core.util.ContextUtil;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
@@ -15,6 +16,7 @@ import java.io.PrintWriter;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@Slf4j
|
||||
@Data
|
||||
public class ResponseResult<T> {
|
||||
|
||||
@@ -160,6 +162,11 @@ public class ResponseResult<T> {
|
||||
* @throws IOException 异常错误。
|
||||
*/
|
||||
public static <T> void output(int httpStatus, ResponseResult<T> responseResult) throws IOException {
|
||||
if (httpStatus != HttpServletResponse.SC_OK) {
|
||||
log.error(JSON.toJSONString(responseResult));
|
||||
} else {
|
||||
log.info(JSON.toJSONString(responseResult));
|
||||
}
|
||||
HttpServletResponse response = ContextUtil.getHttpResponse();
|
||||
PrintWriter out = response.getWriter();
|
||||
response.setContentType("application/json; charset=utf-8");
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 基于Jwt,用于前后端传递的令牌对象。
|
||||
@@ -45,6 +46,10 @@ public class TokenData {
|
||||
* 是否为超级管理员。
|
||||
*/
|
||||
private Boolean isAdmin;
|
||||
/**
|
||||
* 用户登录名。
|
||||
*/
|
||||
private String loginName;
|
||||
/**
|
||||
* 用户显示名称。
|
||||
*/
|
||||
@@ -58,6 +63,14 @@ public class TokenData {
|
||||
* 仅当系统支持uaa时可用,否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
|
||||
*/
|
||||
private String uaaAccessToken;
|
||||
/**
|
||||
* 登录IP。
|
||||
*/
|
||||
private String loginIp;
|
||||
/**
|
||||
* 登录时间。
|
||||
*/
|
||||
private Date loginTime;
|
||||
|
||||
/**
|
||||
* 将令牌对象添加到Http请求对象。
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.Map;
|
||||
@Slf4j
|
||||
public class JwtUtil {
|
||||
|
||||
private static final String TOKEN_PREFIX = "Bearer:";
|
||||
private static final String TOKEN_PREFIX = "Bearer ";
|
||||
private static final String CLAIM_KEY_CREATEDTIME = "CreatedTime";
|
||||
|
||||
/**
|
||||
@@ -61,7 +61,7 @@ public class JwtUtil {
|
||||
/**
|
||||
* 获取token中的数据对象
|
||||
*
|
||||
* @param token 令牌信息(需要包含令牌前缀,如"Bearer:")
|
||||
* @param token 令牌信息(需要包含令牌前缀,如"Bearer ")
|
||||
* @return 令牌中的数据对象,解析视频返回null。
|
||||
*/
|
||||
public static Claims parseToken(String token, String signingKey) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.orange.demo.common.core.util;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.orange.demo.common.core.exception.InvalidDataFieldException;
|
||||
import com.orange.demo.common.core.annotation.*;
|
||||
import com.orange.demo.common.core.exception.MyRuntimeException;
|
||||
import com.orange.demo.common.core.object.TokenData;
|
||||
@@ -141,6 +142,34 @@ public class MyModelUtil {
|
||||
return columnInfo == null ? null : columnInfo.getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* 映射Model对象的字段反射对象,获取与该字段对应的数据库列名称。
|
||||
* 如果没有匹配到ColumnName,则立刻抛出异常。
|
||||
*
|
||||
* @param field 字段反射对象。
|
||||
* @param modelClazz Model对象的Class类。
|
||||
* @return 该字段所对应的数据表列名称。
|
||||
*/
|
||||
public static String safeMapToColumnName(Field field, Class<?> modelClazz) {
|
||||
return safeMapToColumnName(field.getName(), modelClazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 映射Model对象的字段名称,获取与该字段对应的数据库列名称。
|
||||
* 如果没有匹配到ColumnName,则立刻抛出异常。
|
||||
*
|
||||
* @param fieldName 字段名称。
|
||||
* @param modelClazz Model对象的Class类。
|
||||
* @return 该字段所对应的数据表列名称。
|
||||
*/
|
||||
public static String safeMapToColumnName(String fieldName, Class<?> modelClazz) {
|
||||
String columnName = mapToColumnName(fieldName, modelClazz);
|
||||
if (columnName == null) {
|
||||
throw new InvalidDataFieldException(modelClazz.getSimpleName(), fieldName);
|
||||
}
|
||||
return columnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 映射Model对象的字段名称,获取与该字段对应的数据库列名称和字段类型。
|
||||
*
|
||||
|
||||
@@ -8,6 +8,25 @@ package com.orange.demo.common.core.util;
|
||||
*/
|
||||
public class RedisKeyUtil {
|
||||
|
||||
/**
|
||||
* 获取通用的session缓存的键前缀。
|
||||
*
|
||||
* @return session缓存的键前缀。
|
||||
*/
|
||||
public static String getSessionIdPrefix() {
|
||||
return "SESSIONID__";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户Id的session缓存的键前缀。
|
||||
*
|
||||
* @param loginName 指定的用户登录名。
|
||||
* @return session缓存的键前缀。
|
||||
*/
|
||||
public static String getSessionIdPrefix(String loginName) {
|
||||
return "SESSIONID__" + loginName + "_";
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算SessionId返回存储于Redis中的键。
|
||||
*
|
||||
|
||||
@@ -90,9 +90,6 @@
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: redis.clients:jedis:3.2.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.7.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" />
|
||||
@@ -109,6 +106,7 @@
|
||||
<orderEntry type="library" name="Maven: de.ruedigermoeller:fst:2.57" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.objenesis:objenesis:2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" />
|
||||
|
||||
@@ -20,11 +20,6 @@
|
||||
<artifactId>common-core</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>${jedis.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.common.redis.cache;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.orange.demo.common.core.object.TokenData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.Cache;
|
||||
@@ -73,30 +71,4 @@ public class SessionCacheHelper {
|
||||
cacheManager.getCache(c.name()).evict(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 存放session的Token数据。仅仅单体服务使用。
|
||||
*
|
||||
* @param sessionId 当前会话的SessionId。
|
||||
* @param tokenData 当前会话的JWT Token对象。
|
||||
*/
|
||||
public void putTokenData(String sessionId, TokenData tokenData) {
|
||||
if (sessionId == null || tokenData == null) {
|
||||
return;
|
||||
}
|
||||
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.GLOBAL_CACHE.name());
|
||||
cache.put(sessionId, JSON.toJSONString(tokenData));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取session的JWT Token对象。
|
||||
*
|
||||
* @param sessionId 当前会话的SessionId。
|
||||
* @return 当前会话的JWT Token对象。
|
||||
*/
|
||||
public TokenData getTokenData(String sessionId) {
|
||||
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.GLOBAL_CACHE.name());
|
||||
String tokenString = cache.get(sessionId, String.class);
|
||||
return JSONObject.parseObject(tokenString, TokenData.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package com.orange.demo.common.redis.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
/**
|
||||
* Redis配置类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "redis.jedis.enabled", havingValue = "true")
|
||||
public class JedisConfig {
|
||||
|
||||
@Value("${redis.jedis.port}")
|
||||
private Integer port;
|
||||
|
||||
@Value("${redis.jedis.host}")
|
||||
private String redisHost;
|
||||
|
||||
@Value("${redis.jedis.timeout}")
|
||||
private int timeout;
|
||||
|
||||
@Value("${redis.jedis.pool.maxTotal}")
|
||||
private Integer maxTotal;
|
||||
|
||||
@Value("${redis.jedis.pool.maxIdle}")
|
||||
private Integer maxIdle;
|
||||
|
||||
@Value("${redis.jedis.pool.minIdle}")
|
||||
private Integer minIdle;
|
||||
|
||||
@Value("${redis.jedis.pool.maxWait}")
|
||||
private Integer maxWait;
|
||||
|
||||
@Bean
|
||||
public JedisPool getJedisPool() {
|
||||
// Jedis配置信息
|
||||
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
|
||||
jedisPoolConfig.setMaxTotal(maxTotal);
|
||||
jedisPoolConfig.setMaxIdle(maxIdle);
|
||||
jedisPoolConfig.setMinIdle(minIdle);
|
||||
jedisPoolConfig.setMaxWaitMillis(maxWait);
|
||||
jedisPoolConfig.setEvictorShutdownTimeoutMillis(2000);
|
||||
return new JedisPool(jedisPoolConfig, redisHost, port);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.orange.demo.common.redis.config;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.orange.demo.common.core.exception.InvalidRedisModeException;
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.Config;
|
||||
@@ -9,8 +12,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Redisson配置类。和Jedis一样都是Redis客户端,但是Redisson提供了更多的数据结构抽象。
|
||||
* 这里我们只是使用了Redisson的分布式锁,以及map等数据结构作为字典缓存使用。更多用法请参考其文档。
|
||||
* Redisson配置类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
@@ -22,6 +24,15 @@ public class RedissonConfig {
|
||||
@Value("${redis.redisson.lockWatchdogTimeout}")
|
||||
private Integer lockWatchdogTimeout;
|
||||
|
||||
@Value("${redis.redisson.mode}")
|
||||
private String mode;
|
||||
|
||||
/**
|
||||
* 仅仅用于sentinel模式。
|
||||
*/
|
||||
@Value("${redis.redisson.masterName:}")
|
||||
private String masterName;
|
||||
|
||||
@Value("${redis.redisson.address}")
|
||||
private String address;
|
||||
|
||||
@@ -37,14 +48,45 @@ public class RedissonConfig {
|
||||
@Bean
|
||||
public RedissonClient redissonClient() {
|
||||
Config config = new Config();
|
||||
// 这里config还支持其他redis集群模式,可根据实际需求更换。
|
||||
// 比如useClusterServers()/useMasterSlaveServers()等。
|
||||
config.setLockWatchdogTimeout(lockWatchdogTimeout)
|
||||
.useSingleServer()
|
||||
.setAddress("redis://" + address)
|
||||
.setConnectionPoolSize(poolSize)
|
||||
.setConnectionMinimumIdleSize(minIdle)
|
||||
.setConnectTimeout(timeout);
|
||||
if ("single".equals(mode)) {
|
||||
config.setLockWatchdogTimeout(lockWatchdogTimeout)
|
||||
.useSingleServer()
|
||||
.setAddress(address)
|
||||
.setConnectionPoolSize(poolSize)
|
||||
.setConnectionMinimumIdleSize(minIdle)
|
||||
.setConnectTimeout(timeout);
|
||||
} else if ("cluster".equals(mode)) {
|
||||
String[] clusterAddresses = StrUtil.splitToArray(address, ',');
|
||||
config.setLockWatchdogTimeout(lockWatchdogTimeout)
|
||||
.useClusterServers()
|
||||
.addNodeAddress(clusterAddresses)
|
||||
.setConnectTimeout(timeout)
|
||||
.setMasterConnectionPoolSize(poolSize);
|
||||
} else if ("sentinel".equals(mode)) {
|
||||
String[] sentinelAddresses = StrUtil.splitToArray(address, ',');
|
||||
config.setLockWatchdogTimeout(lockWatchdogTimeout)
|
||||
.useSentinelServers()
|
||||
.setMasterName(masterName)
|
||||
.addSentinelAddress(sentinelAddresses)
|
||||
.setConnectTimeout(timeout)
|
||||
.setMasterConnectionPoolSize(poolSize);
|
||||
} else if ("master-slave".equals(mode)) {
|
||||
String[] masterSlaveAddresses = StrUtil.splitToArray(address, ',');
|
||||
if (masterSlaveAddresses.length == 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"redis.redisson.address MUST have multiple redis addresses for master-slave mode.");
|
||||
}
|
||||
String[] slaveAddresses = new String[masterSlaveAddresses.length - 1];
|
||||
ArrayUtil.copy(masterSlaveAddresses, 1, slaveAddresses, 0, slaveAddresses.length);
|
||||
config.setLockWatchdogTimeout(lockWatchdogTimeout)
|
||||
.useMasterSlaveServers()
|
||||
.setMasterAddress(masterSlaveAddresses[0])
|
||||
.addSlaveAddress(slaveAddresses)
|
||||
.setConnectTimeout(timeout)
|
||||
.setMasterConnectionPoolSize(poolSize);
|
||||
} else {
|
||||
throw new InvalidRedisModeException(mode);
|
||||
}
|
||||
return Redisson.create(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.orange.demo.common.redis.config.JedisConfig,\
|
||||
com.orange.demo.common.redis.config.RedissonConfig
|
||||
Reference in New Issue
Block a user