search(SearchDto searchDto) {
searchDto.setIsHighlighter(true);
searchDto.setSortCol("createTime");
return queryService.strQuery("sys_user", searchDto, SEARCH_LOGIC_DEL_DTO);
diff --git a/zlt-business/user-center/src/main/java/com/central/user/service/ISysRoleService.java b/zlt-business/user-center/src/main/java/com/central/user/service/ISysRoleService.java
index 716a48a5..2d29f858 100644
--- a/zlt-business/user-center/src/main/java/com/central/user/service/ISysRoleService.java
+++ b/zlt-business/user-center/src/main/java/com/central/user/service/ISysRoleService.java
@@ -9,10 +9,13 @@
import com.central.common.service.ISuperService;
/**
-* @author zlt
+ * @author zlt
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
public interface ISysRoleService extends ISuperService {
- void saveRole(SysRole sysRole);
+ void saveRole(SysRole sysRole) throws Exception;
void deleteRole(Long id);
@@ -28,7 +31,7 @@ public interface ISysRoleService extends ISuperService {
* @param sysRole
* @return Result
*/
- Result saveOrUpdateRole(SysRole sysRole);
+ Result saveOrUpdateRole(SysRole sysRole) throws Exception;
/**
* 查询所有角色
diff --git a/zlt-business/user-center/src/main/java/com/central/user/service/ISysUserService.java b/zlt-business/user-center/src/main/java/com/central/user/service/ISysUserService.java
index 26adcb5d..aaf899fd 100644
--- a/zlt-business/user-center/src/main/java/com/central/user/service/ISysUserService.java
+++ b/zlt-business/user-center/src/main/java/com/central/user/service/ISysUserService.java
@@ -13,7 +13,10 @@
import com.central.common.model.SysUser;
/**
-* @author zlt
+ * @author zlt
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
public interface ISysUserService extends ISuperService {
/**
@@ -98,7 +101,7 @@ public interface ISysUserService extends ISuperService {
*/
List findAllUsers(Map params);
- Result saveOrUpdateUser(SysUser sysUser);
+ Result saveOrUpdateUser(SysUser sysUser) throws Exception;
/**
* 删除用户
diff --git a/zlt-business/user-center/src/main/java/com/central/user/service/impl/SysRoleServiceImpl.java b/zlt-business/user-center/src/main/java/com/central/user/service/impl/SysRoleServiceImpl.java
index 4d28373d..8550e08d 100644
--- a/zlt-business/user-center/src/main/java/com/central/user/service/impl/SysRoleServiceImpl.java
+++ b/zlt-business/user-center/src/main/java/com/central/user/service/impl/SysRoleServiceImpl.java
@@ -29,7 +29,7 @@
@Slf4j
@Service
public class SysRoleServiceImpl extends SuperServiceImpl implements ISysRoleService {
- private final static String LOCK_KEY_ROLECODE = CommonConstant.LOCK_KEY_PREFIX+"rolecode:";
+ private final static String LOCK_KEY_ROLECODE = "rolecode:";
@Resource
private SysUserRoleMapper userRoleMapper;
@@ -42,7 +42,7 @@ public class SysRoleServiceImpl extends SuperServiceImpl
@Transactional(rollbackFor = Exception.class)
@Override
- public void saveRole(SysRole sysRole) {
+ public void saveRole(SysRole sysRole) throws Exception {
String roleCode = sysRole.getCode();
super.saveIdempotency(sysRole, lock
, LOCK_KEY_ROLECODE+roleCode, new QueryWrapper().eq("code", roleCode), "角色code已存在");
@@ -67,7 +67,7 @@ public PageResult findRoles(Map params) {
@Override
@Transactional
- public Result saveOrUpdateRole(SysRole sysRole) {
+ public Result saveOrUpdateRole(SysRole sysRole) throws Exception {
if (sysRole.getId() == null) {
this.saveRole(sysRole);
} else {
diff --git a/zlt-business/user-center/src/main/java/com/central/user/service/impl/SysUserServiceImpl.java b/zlt-business/user-center/src/main/java/com/central/user/service/impl/SysUserServiceImpl.java
index ce667390..eedada4c 100644
--- a/zlt-business/user-center/src/main/java/com/central/user/service/impl/SysUserServiceImpl.java
+++ b/zlt-business/user-center/src/main/java/com/central/user/service/impl/SysUserServiceImpl.java
@@ -37,7 +37,7 @@
@Slf4j
@Service
public class SysUserServiceImpl extends SuperServiceImpl implements ISysUserService {
- private final static String LOCK_KEY_USERNAME = CommonConstant.LOCK_KEY_PREFIX+"username:";
+ private final static String LOCK_KEY_USERNAME = "username:";
@Autowired
private PasswordEncoder passwordEncoder;
@@ -80,10 +80,10 @@ public LoginAppUser getLoginAppUser(SysUser sysUser) {
loginAppUser.setRoles(sysRoles);
if (!CollectionUtils.isEmpty(sysRoles)) {
- Set roleIds = sysRoles.parallelStream().map(SuperEntity::getId).collect(Collectors.toSet());
+ Set roleIds = sysRoles.stream().map(SuperEntity::getId).collect(Collectors.toSet());
List menus = roleMenuMapper.findMenusByRoleIds(roleIds, CommonConstant.PERMISSION);
if (!CollectionUtils.isEmpty(menus)) {
- Set permissions = menus.parallelStream().map(p -> p.getPath())
+ Set permissions = menus.stream().map(p -> p.getPath())
.collect(Collectors.toSet());
// 设置权限集合
loginAppUser.setPermissions(permissions);
@@ -219,7 +219,7 @@ public Result updateEnabled(Map params) {
@Transactional(rollbackFor = Exception.class)
@Override
- public Result saveOrUpdateUser(SysUser sysUser) {
+ public Result saveOrUpdateUser(SysUser sysUser) throws Exception {
if (sysUser.getId() == null) {
if (StringUtils.isBlank(sysUser.getType())) {
sysUser.setType(UserType.BACKEND.name());
diff --git a/zlt-business/user-center/src/main/resources/application.yml b/zlt-business/user-center/src/main/resources/application.yml
index a9c65586..f9a8c71b 100644
--- a/zlt-business/user-center/src/main/resources/application.yml
+++ b/zlt-business/user-center/src/main/resources/application.yml
@@ -34,7 +34,10 @@ zlt:
- sys_role_user
- sys_role_menu
ignoreSqls:
+ # 用户关联角色时,显示所有角色
- com.central.user.mapper.SysRoleMapper.findAll
+ # 用户列表显示用户所关联的所有角色
+ - com.central.user.mapper.SysUserRoleMapper.findRolesByUserIds
#审计日志
# audit-log:
# enabled: true
diff --git a/zlt-commons/pom.xml b/zlt-commons/pom.xml
index 2fbe456a..cad68d5e 100644
--- a/zlt-commons/pom.xml
+++ b/zlt-commons/pom.xml
@@ -4,7 +4,7 @@
com.zlt
central-platform
- 3.5.0
+ 5.3.0
zlt-commons
通用组件
@@ -16,10 +16,12 @@
zlt-db-spring-boot-starter
zlt-swagger2-spring-boot-starter
zlt-log-spring-boot-starter
- zlt-ribbon-spring-boot-starter
+ zlt-loadbalancer-spring-boot-starter
zlt-auth-client-spring-boot-starter
zlt-sentinel-spring-boot-starter
zlt-common-core
zlt-elasticsearch-spring-boot-starter
+ zlt-oss-spring-boot-starter
+ zlt-zookeeper-spring-boot-starter
\ No newline at end of file
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/pom.xml b/zlt-commons/zlt-auth-client-spring-boot-starter/pom.xml
index 710df120..5ba6a048 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/pom.xml
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
com.zlt
zlt-commons
- 3.5.0
+ 5.3.0
4.0.0
jar
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/AuthClientAutoConfiguration.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/AuthClientAutoConfiguration.java
new file mode 100644
index 00000000..17ede133
--- /dev/null
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/AuthClientAutoConfiguration.java
@@ -0,0 +1,21 @@
+package com.central.oauth2.common;
+
+import com.central.oauth2.common.properties.SecurityProperties;
+import com.central.oauth2.common.properties.TokenStoreProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * 鉴权自动配置
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/7/24
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@EnableConfigurationProperties({SecurityProperties.class, TokenStoreProperties.class})
+@ComponentScan
+public class AuthClientAutoConfiguration {
+}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/SecurityPropertiesConfig.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/SecurityPropertiesConfig.java
deleted file mode 100644
index e85ed2a2..00000000
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/SecurityPropertiesConfig.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.central.oauth2.common.config;
-
-import com.central.oauth2.common.properties.SecurityProperties;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-
-/**
- * @author zlt
- * @date 2019/10/7
- *
- * Blog: https://blog.csdn.net/zlt2000
- * Github: https://github.com/zlt2000
- */
-@EnableConfigurationProperties(SecurityProperties.class)
-public class SecurityPropertiesConfig {
-}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/constants/IdTokenClaimNames.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/constants/IdTokenClaimNames.java
new file mode 100644
index 00000000..23865987
--- /dev/null
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/constants/IdTokenClaimNames.java
@@ -0,0 +1,89 @@
+package com.central.oauth2.common.constants;
+
+/**
+ * id_token属性名常量
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/4/23
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+public class IdTokenClaimNames {
+ /**
+ * {@code iss} - the Issuer identifier
+ */
+ public final static String ISS = "iss";
+
+ /**
+ * {@code sub} - the Subject identifier
+ */
+ public final static String SUB = "sub";
+
+ /**
+ * {@code aud} - the Audience(s) that the ID Token is intended for
+ */
+ public final static String AUD = "aud";
+
+ /**
+ * {@code exp} - the Expiration time on or after which the ID Token MUST NOT be accepted
+ */
+ public final static String EXP = "exp";
+
+ /**
+ * {@code iat} - the time at which the ID Token was issued
+ */
+ public final static String IAT = "iat";
+
+ /**
+ * {@code auth_time} - the time when the End-User authentication occurred
+ */
+ public final static String AUTH_TIME = "auth_time";
+
+ /**
+ * {@code nonce} - a {@code String} value used to associate a Client session with an ID Token,
+ * and to mitigate replay attacks.
+ */
+ public final static String NONCE = "nonce";
+
+ /**
+ * {@code acr} - the Authentication Context Class Reference
+ */
+ public final static String ACR = "acr";
+
+ /**
+ * {@code amr} - the Authentication Methods References
+ */
+ public final static String AMR = "amr";
+
+ /**
+ * {@code azp} - the Authorized party to which the ID Token was issued
+ */
+ public final static String AZP = "azp";
+
+ /**
+ * {@code at_hash} - the Access Token hash value
+ */
+ public final static String AT_HASH = "at_hash";
+
+ /**
+ * {@code c_hash} - the Authorization Code hash value
+ */
+ public final static String C_HASH = "c_hash";
+
+ /**
+ * {@code name} - 用户姓名
+ */
+ public final static String NAME = "name";
+
+ /**
+ * {@code login_name} - 登录名
+ */
+ public final static String L_NAME = "login_name";
+
+ /**
+ * {@code picture} - 头像照片
+ */
+ public final static String PIC = "picture";
+}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/converter/CustomUserAuthenticationConverter.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/converter/CustomUserAuthenticationConverter.java
index 7bf24315..fbc86581 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/converter/CustomUserAuthenticationConverter.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/converter/CustomUserAuthenticationConverter.java
@@ -1,5 +1,6 @@
package com.central.oauth2.common.converter;
+import com.central.common.model.LoginAppUser;
import com.central.common.model.SysUser;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
@@ -68,7 +69,7 @@ public Authentication extractAuthentication(Map map) {
principal = user;
} else {
Integer id = (Integer)map.get("id");
- SysUser user = new SysUser();
+ LoginAppUser user = new LoginAppUser();
user.setUsername((String)principal);
user.setId(Long.valueOf(id));
principal = user;
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/AuthProperties.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/AuthProperties.java
index bdc0048c..c89860b9 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/AuthProperties.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/AuthProperties.java
@@ -28,4 +28,23 @@ public class AuthProperties {
* url权限配置
*/
private UrlPermissionProperties urlPermission = new UrlPermissionProperties();
+
+ /**
+ * 是否开启统一登出
+ * 1. 登出时把同一个用户名下的所有token都注销
+ * 2. 登出信息通知所有单点登录系统
+ */
+ private Boolean unifiedLogout = false;
+
+ /**
+ * 是否同应用同账号登录互踢
+ */
+ private Boolean isSingleLogin = false;
+
+ /**
+ * 是否同应用同账号登录时共用token
+ * true: 多个用户使用同一账号登录时共用一个token
+ * false: 就算使用同一账号登录时都会新建一个token
+ */
+ private Boolean isShareToken = true;
}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/PermitProperties.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/PermitProperties.java
index 16a5b653..e0c3c15f 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/PermitProperties.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/PermitProperties.java
@@ -23,6 +23,7 @@ public class PermitProperties {
"/*/v2/api-docs",
"/swagger/api-docs",
"/swagger-ui.html",
+ "/doc.html",
"/swagger-resources/**",
"/webjars/**",
"/druid/**"
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/TokenStoreProperties.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/TokenStoreProperties.java
new file mode 100644
index 00000000..0f2687fb
--- /dev/null
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/TokenStoreProperties.java
@@ -0,0 +1,27 @@
+package com.central.oauth2.common.properties;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+
+/**
+ * Token配置
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/5/19
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Setter
+@Getter
+@ConfigurationProperties(prefix = "zlt.oauth2.token.store")
+@RefreshScope
+public class TokenStoreProperties {
+ /**
+ * token存储类型(redis/db/authJwt/resJwt)
+ */
+ private String type = "redis";
+}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/service/impl/DefaultPermissionServiceImpl.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/service/impl/DefaultPermissionServiceImpl.java
index 954cf054..c08a178b 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/service/impl/DefaultPermissionServiceImpl.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/service/impl/DefaultPermissionServiceImpl.java
@@ -25,6 +25,9 @@
*
* @author zlt
* @date 2018/10/28
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
@Slf4j
public abstract class DefaultPermissionServiceImpl {
@@ -32,7 +35,7 @@ public abstract class DefaultPermissionServiceImpl {
@Autowired
private SecurityProperties securityProperties;
- private AntPathMatcher antPathMatcher = new AntPathMatcher();
+ private final AntPathMatcher antPathMatcher = new AntPathMatcher();
/**
* 查询当前用户拥有的资源权限
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthDbTokenStore.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthDbTokenStore.java
index d084e549..1d0b1ec9 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthDbTokenStore.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthDbTokenStore.java
@@ -3,6 +3,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
@@ -14,6 +15,7 @@
* @author zlt
* @date 2018/7/24 16:23
*/
+@Configuration
@ConditionalOnProperty(prefix = "zlt.oauth2.token.store", name = "type", havingValue = "db")
public class AuthDbTokenStore {
@Autowired
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthJwtTokenStore.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthJwtTokenStore.java
index 9b99fb79..2d261222 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthJwtTokenStore.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthJwtTokenStore.java
@@ -5,6 +5,8 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.bootstrap.encrypt.KeyProperties;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
@@ -23,16 +25,14 @@
*
* @author zlt
* @date 2018/7/24 16:21
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
+@Configuration
@ConditionalOnProperty(prefix = "zlt.oauth2.token.store", name = "type", havingValue = "authJwt")
public class AuthJwtTokenStore {
-
- @Bean("keyProp")
- public KeyProperties keyProperties() {
- return new KeyProperties();
- }
-
- @Resource(name = "keyProp")
+ @Resource
private KeyProperties keyProperties;
@Bean
@@ -41,6 +41,7 @@ public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
}
@Bean
+ @Order(2)
public JwtAccessTokenConverter jwtAccessTokenConverter() {
final JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory
@@ -51,25 +52,4 @@ public JwtAccessTokenConverter jwtAccessTokenConverter() {
tokenConverter.setUserTokenConverter(new CustomUserAuthenticationConverter());
return converter;
}
-
- /**
- * jwt 生成token 定制化处理
- * 添加一些额外的用户信息到token里面
- *
- * @return TokenEnhancer
- */
- @Bean
- public TokenEnhancer tokenEnhancer() {
- return (accessToken, authentication) -> {
- final Map additionalInfo = new HashMap<>(1);
- Object principal = authentication.getPrincipal();
- //增加id参数
- if (principal instanceof SysUser) {
- SysUser user = (SysUser)principal;
- additionalInfo.put("id", user.getId());
- }
- ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
- return accessToken;
- };
- }
}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthRedisTokenStore.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthRedisTokenStore.java
index a8651589..239dc420 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthRedisTokenStore.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthRedisTokenStore.java
@@ -4,7 +4,9 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.security.oauth2.provider.token.TokenStore;
/**
@@ -13,17 +15,15 @@
*
* @author zlt
* @date 2018/7/25 9:36
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
+@Configuration
@ConditionalOnProperty(prefix = "zlt.oauth2.token.store", name = "type", havingValue = "redis", matchIfMissing = true)
public class AuthRedisTokenStore {
- @Autowired
- private RedisConnectionFactory connectionFactory;
-
- @Autowired
- private SecurityProperties securityProperties;
-
@Bean
- public TokenStore tokenStore() {
- return new CustomRedisTokenStore(connectionFactory, securityProperties);
+ public TokenStore tokenStore(RedisConnectionFactory connectionFactory, SecurityProperties securityProperties, RedisSerializer redisValueSerializer) {
+ return new CustomRedisTokenStore(connectionFactory, securityProperties, redisValueSerializer);
}
}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/CustomRedisTokenStore.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/CustomRedisTokenStore.java
index 43193a37..f07ddb0d 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/CustomRedisTokenStore.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/CustomRedisTokenStore.java
@@ -4,6 +4,7 @@
import com.central.oauth2.common.properties.SecurityProperties;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
@@ -38,6 +39,7 @@
*/
public class CustomRedisTokenStore implements TokenStore {
private static final String ACCESS = "access:";
+ private static final String ACCESS_BAK = "access_bak:";
private static final String AUTH_TO_ACCESS = "auth_to_access:";
private static final String REFRESH_AUTH = "refresh_auth:";
private static final String ACCESS_TO_REFRESH = "access_to_refresh:";
@@ -61,9 +63,15 @@ public class CustomRedisTokenStore implements TokenStore {
*/
private SecurityProperties securityProperties;
- public CustomRedisTokenStore(RedisConnectionFactory connectionFactory, SecurityProperties securityProperties) {
+ /**
+ * 业务redis的value序列化
+ */
+ private RedisSerializer redisValueSerializer;
+
+ public CustomRedisTokenStore(RedisConnectionFactory connectionFactory, SecurityProperties securityProperties, RedisSerializer redisValueSerializer) {
this.connectionFactory = connectionFactory;
this.securityProperties = securityProperties;
+ this.redisValueSerializer = redisValueSerializer;
if (springDataRedis_2_0) {
this.loadRedisConnectionMethods_2_0();
}
@@ -111,7 +119,7 @@ private OAuth2RefreshToken deserializeRefreshToken(byte[] bytes) {
}
private ClientDetails deserializeClientDetails(byte[] bytes) {
- return serializationStrategy.deserialize(bytes, ClientDetails.class);
+ return (ClientDetails) redisValueSerializer.deserialize(bytes);
}
private byte[] serialize(String string) {
@@ -159,7 +167,7 @@ public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
//获取过期时长
int validitySeconds = getAccessTokenValiditySeconds(clientAuth.getClientId());
if (validitySeconds > 0) {
- double expiresRatio = token.getExpiresIn() / (double)validitySeconds;
+ double expiresRatio = token.getExpiresIn() / (double) validitySeconds;
//判断是否需要续签,当前剩余时间小于过期时长的50%则续签
if (expiresRatio <= securityProperties.getAuth().getRenew().getTimeRatio()) {
//更新AccessToken过期时间
@@ -175,6 +183,7 @@ public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
/**
* 判断应用自动续签是否满足白名单和黑名单的过滤逻辑
+ *
* @param clientId 应用id
* @return 是否满足
*/
@@ -186,7 +195,7 @@ private boolean checkRenewClientId(String clientId) {
List exclusiveClientIds = securityProperties.getAuth().getRenew().getExclusiveClientIds();
if (includeClientIds.size() > 0) {
result = includeClientIds.contains(clientId);
- } else if(exclusiveClientIds.size() > 0) {
+ } else if (exclusiveClientIds.size() > 0) {
result = !exclusiveClientIds.contains(clientId);
}
return result;
@@ -194,6 +203,7 @@ private boolean checkRenewClientId(String clientId) {
/**
* 获取token的总有效时长
+ *
* @param clientId 应用id
*/
private int getAccessTokenValiditySeconds(String clientId) {
@@ -249,12 +259,14 @@ public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authe
/**
* 存储token
+ *
* @param isRenew 是否续签
*/
private void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication, boolean isRenew) {
byte[] serializedAccessToken = serialize(token);
byte[] serializedAuth = serialize(authentication);
byte[] accessKey = serializeKey(ACCESS + token.getValue());
+ byte[] accessBakKey = serializeKey(ACCESS_BAK + token.getValue());
byte[] authKey = serializeKey(SecurityConstants.REDIS_TOKEN_AUTH + token.getValue());
byte[] authToAccessKey = serializeKey(AUTH_TO_ACCESS + authenticationKeyGenerator.extractKey(authentication));
byte[] approvalKey = serializeKey(SecurityConstants.REDIS_UNAME_TO_ACCESS + getApprovalKey(authentication));
@@ -272,6 +284,7 @@ private void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication auth
if (springDataRedis_2_0) {
try {
this.redisConnectionSet_2_0.invoke(conn, accessKey, serializedAccessToken);
+ this.redisConnectionSet_2_0.invoke(conn, accessBakKey, serializedAccessToken);
this.redisConnectionSet_2_0.invoke(conn, authKey, serializedAuth);
this.redisConnectionSet_2_0.invoke(conn, authToAccessKey, serializedAccessToken);
} catch (Exception ex) {
@@ -279,6 +292,7 @@ private void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication auth
}
} else {
conn.set(accessKey, serializedAccessToken);
+ conn.set(accessBakKey, serializedAccessToken);
conn.set(authKey, serializedAuth);
conn.set(authToAccessKey, serializedAccessToken);
}
@@ -296,6 +310,7 @@ private void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication auth
if (token.getExpiration() != null) {
int seconds = token.getExpiresIn();
conn.expire(accessKey, seconds);
+ conn.expire(accessBakKey, seconds + 60);
conn.expire(authKey, seconds);
conn.expire(authToAccessKey, seconds);
conn.expire(clientId, seconds);
@@ -356,20 +371,20 @@ public OAuth2AccessToken readAccessToken(String tokenValue) {
public void removeAccessToken(String tokenValue) {
byte[] accessKey = serializeKey(ACCESS + tokenValue);
+ byte[] accessBakKey = serializeKey(ACCESS_BAK + tokenValue);
byte[] authKey = serializeKey(SecurityConstants.REDIS_TOKEN_AUTH + tokenValue);
byte[] accessToRefreshKey = serializeKey(ACCESS_TO_REFRESH + tokenValue);
RedisConnection conn = getConnection();
try {
+ byte[] access = conn.get(accessKey);
+ byte[] auth = conn.get(authKey);
conn.openPipeline();
- conn.get(accessKey);
- conn.get(authKey);
conn.del(accessKey);
+ conn.del(accessBakKey);
conn.del(accessToRefreshKey);
// Don't remove the refresh token - it's up to the caller to do that
conn.del(authKey);
- List results = conn.closePipeline();
- byte[] access = (byte[]) results.get(0);
- byte[] auth = (byte[]) results.get(1);
+ conn.closePipeline();
OAuth2Authentication authentication = deserializeAuthentication(auth);
if (authentication != null) {
@@ -471,20 +486,17 @@ public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken)
private void removeAccessTokenUsingRefreshToken(String refreshToken) {
byte[] key = serializeKey(REFRESH_TO_ACCESS + refreshToken);
- List results = null;
RedisConnection conn = getConnection();
+ byte[] bytes = null;
try {
- conn.openPipeline();
- conn.get(key);
+ bytes = conn.get(key);
conn.del(key);
- results = conn.closePipeline();
} finally {
conn.close();
}
- if (results == null) {
+ if (bytes == null) {
return;
}
- byte[] bytes = (byte[]) results.get(0);
String accessToken = deserializeString(bytes);
if (accessToken != null) {
removeAccessToken(accessToken);
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/ResJwtTokenStore.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/ResJwtTokenStore.java
index 606fbb68..c7655696 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/ResJwtTokenStore.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/ResJwtTokenStore.java
@@ -7,6 +7,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
@@ -31,6 +32,7 @@
* @author zlt
* @date 2018/8/20 9:25
*/
+@Configuration
@ConditionalOnProperty(prefix = "zlt.oauth2.token.store", name = "type", havingValue = "resJwt")
public class ResJwtTokenStore {
@Autowired
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/token/CustomWebAuthenticationDetails.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/token/CustomWebAuthenticationDetails.java
new file mode 100644
index 00000000..95dd1c18
--- /dev/null
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/token/CustomWebAuthenticationDetails.java
@@ -0,0 +1,37 @@
+package com.central.oauth2.common.token;
+
+import lombok.Getter;
+
+import java.io.Serializable;
+
+/**
+ * 表单登录的认证信息对象
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/7/24
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Getter
+public class CustomWebAuthenticationDetails implements Serializable {
+ private static final long serialVersionUID = - 1;
+
+ private final String accountType;
+ private final String remoteAddress;
+ private final String sessionId;
+
+ public CustomWebAuthenticationDetails(String remoteAddress, String sessionId, String accountType) {
+ this.remoteAddress = remoteAddress;
+ this.sessionId = sessionId;
+ this.accountType = accountType;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString()).append("; accountType: ").append(this.getAccountType());
+ return sb.toString();
+ }
+}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/token/TenantUsernamePasswordAuthenticationToken.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/token/TenantUsernamePasswordAuthenticationToken.java
new file mode 100644
index 00000000..e9546d50
--- /dev/null
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/token/TenantUsernamePasswordAuthenticationToken.java
@@ -0,0 +1,37 @@
+package com.central.oauth2.common.token;
+
+import lombok.Getter;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.Collection;
+
+/**
+ * 增加租户id,解决不同租户单点登录时角色没变化
+ *
+ * @author zlt
+ * @date 2020/6/10
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+public class TenantUsernamePasswordAuthenticationToken extends UsernamePasswordAuthenticationToken {
+ private static final long serialVersionUID = -5638287853803374687L;
+
+ /**
+ * 租户id
+ */
+ @Getter
+ private final String clientId;
+
+ public TenantUsernamePasswordAuthenticationToken(Object principal, Object credentials, String clientId) {
+ super(principal, credentials);
+ this.clientId = clientId;
+ }
+
+ public TenantUsernamePasswordAuthenticationToken(Object principal, Object credentials,
+ Collection extends GrantedAuthority> authorities, String clientId) {
+ super(principal, credentials, authorities);
+ this.clientId = clientId;
+ }
+}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/util/AuthUtils.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/util/AuthUtils.java
index bad4669f..db7c3642 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/util/AuthUtils.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/util/AuthUtils.java
@@ -1,17 +1,19 @@
package com.central.oauth2.common.util;
import com.central.common.constant.CommonConstant;
+import com.central.common.constant.SecurityConstants;
import com.central.common.model.SysUser;
+import com.central.oauth2.common.token.CustomWebAuthenticationDetails;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
import javax.servlet.http.HttpServletRequest;
-import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Enumeration;
+import java.util.Map;
/**
* 认证授权相关工具类
@@ -104,4 +106,26 @@ public static String getUsername(Authentication authentication) {
}
return username;
}
+
+ /**
+ * 获取登陆的帐户类型
+ */
+ public static String getAccountType(Authentication authentication) {
+ String accountType = null;
+ if (authentication != null) {
+ Object details = authentication.getDetails();
+ if (details != null) {
+ if (details instanceof CustomWebAuthenticationDetails) {
+ CustomWebAuthenticationDetails detailsObj = (CustomWebAuthenticationDetails) details;
+ accountType = detailsObj.getAccountType();
+ } else {
+ Map detailsMap = (Map) details;
+ if (detailsMap != null) {
+ accountType = detailsMap.get(SecurityConstants.ACCOUNT_TYPE_PARAM_NAME);
+ }
+ }
+ }
+ }
+ return accountType;
+ }
}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/util/JwtUtils.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/util/JwtUtils.java
index 507dfdef..e5627405 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/util/JwtUtils.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/util/JwtUtils.java
@@ -1,17 +1,25 @@
package com.central.oauth2.common.util;
-import com.alibaba.fastjson.JSONObject;
import com.central.common.constant.SecurityConstants;
+import com.central.common.utils.JsonUtil;
import com.central.common.utils.RsaUtils;
+import com.fasterxml.jackson.databind.JsonNode;
+import org.springframework.cloud.bootstrap.encrypt.KeyProperties;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
+import org.springframework.security.jwt.crypto.sign.RsaSigner;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
+import org.springframework.security.jwt.crypto.sign.Signer;
+import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
import java.io.BufferedReader;
import java.io.InputStreamReader;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.stream.Collectors;
@@ -46,10 +54,10 @@ public static RSAPublicKey getPubKeyObj() {
* @param rsaPublicKey 公钥
* @return
*/
- public static JSONObject decodeAndVerify(String jwtToken, RSAPublicKey rsaPublicKey) {
+ public static JsonNode decodeAndVerify(String jwtToken, RSAPublicKey rsaPublicKey) {
SignatureVerifier rsaVerifier = new RsaVerifier(rsaPublicKey);
Jwt jwt = JwtHelper.decodeAndVerify(jwtToken, rsaVerifier);
- return JSONObject.parseObject(jwt.getClaims());
+ return JsonUtil.parse(jwt.getClaims());
}
/**
@@ -57,7 +65,7 @@ public static JSONObject decodeAndVerify(String jwtToken, RSAPublicKey rsaPublic
* @param jwtToken token值
* @return
*/
- public static JSONObject decodeAndVerify(String jwtToken) {
+ public static JsonNode decodeAndVerify(String jwtToken) {
return decodeAndVerify(jwtToken, getPubKeyObj());
}
@@ -67,8 +75,8 @@ public static JSONObject decodeAndVerify(String jwtToken) {
* @param currTime 当前时间
* @return 未过期:true,已过期:false
*/
- public static boolean checkExp(JSONObject claims, long currTime) {
- long exp = claims.getLong("exp");
+ public static boolean checkExp(JsonNode claims, long currTime) {
+ long exp = claims.get("exp").asLong();
if (exp < currTime) {
return false;
}
@@ -80,7 +88,21 @@ public static boolean checkExp(JSONObject claims, long currTime) {
* @param claims jwt内容
* @return 未过期:true,已过期:false
*/
- public static boolean checkExp(JSONObject claims) {
+ public static boolean checkExp(JsonNode claims) {
return checkExp(claims, System.currentTimeMillis());
}
+
+ public static Jwt encode(CharSequence content, KeyProperties keyProperties) {
+ KeyPair keyPair = new KeyStoreKeyFactory(
+ keyProperties.getKeyStore().getLocation(),
+ keyProperties.getKeyStore().getSecret().toCharArray())
+ .getKeyPair(keyProperties.getKeyStore().getAlias());
+ PrivateKey privateKey = keyPair.getPrivate();
+ Signer rsaSigner = new RsaSigner((RSAPrivateKey) privateKey);
+ return JwtHelper.encode(content, rsaSigner);
+ }
+
+ public static String encodeStr(CharSequence content, KeyProperties keyProperties) {
+ return encode(content, keyProperties).getEncoded();
+ }
}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/resources/META-INF/spring.factories b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/resources/META-INF/spring.factories
index f45f3e08..9862b1d3 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/resources/META-INF/spring.factories
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -1,6 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-com.central.oauth2.common.config.SecurityPropertiesConfig,\
-com.central.oauth2.common.store.AuthDbTokenStore,\
-com.central.oauth2.common.store.AuthRedisTokenStore,\
-com.central.oauth2.common.store.AuthJwtTokenStore,\
-com.central.oauth2.common.store.ResJwtTokenStore
\ No newline at end of file
+com.central.oauth2.common.AuthClientAutoConfiguration
\ No newline at end of file
diff --git a/zlt-commons/zlt-common-core/pom.xml b/zlt-commons/zlt-common-core/pom.xml
index 998a39ca..8d0c9467 100644
--- a/zlt-commons/zlt-common-core/pom.xml
+++ b/zlt-commons/zlt-common-core/pom.xml
@@ -4,7 +4,7 @@
com.zlt
zlt-commons
- 3.5.0
+ 5.3.0
zlt-common-core
公共通用组件
@@ -24,9 +24,8 @@
spring-social-security
- org.springframework.security.oauth
- spring-security-oauth2
- true
+ org.springframework.security
+ spring-security-core
@@ -86,5 +85,10 @@
reactor-core
true
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
\ No newline at end of file
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/BannerInitializer.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/BannerInitializer.java
index d02365d1..63ff6c20 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/BannerInitializer.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/BannerInitializer.java
@@ -22,8 +22,8 @@ public void initialize(ConfigurableApplicationContext applicationContext) {
if (!(applicationContext instanceof AnnotationConfigApplicationContext)) {
LogoBanner logoBanner = new LogoBanner(BannerInitializer.class, "/zltmp/logo.txt", "Welcome to zlt", 5, 6, new Color[5], true);
CustomBanner.show(logoBanner, new Description(BannerConstant.VERSION + ":", CommonConstant.PROJECT_VERSION, 0, 1)
- , new Description("Gitee:", "https://gitee.com/zlt2000/microservices-platform", 0, 1)
- , new Description("Blog:", "https://blog.csdn.net/zlt2000", 0, 1)
+ , new Description("Github:", "https://github.com/zlt2000", 0, 1)
+ , new Description("Blog:", "https://zlt2000.gitee.io", 0, 1)
);
}
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/DefaultPasswordConfig.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/DefaultPasswordConfig.java
index 372024cc..225736b2 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/DefaultPasswordConfig.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/DefaultPasswordConfig.java
@@ -1,20 +1,22 @@
package com.central.common.config;
+import com.central.common.utils.PwdEncoderUtil;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
-/**
-* @author zlt
-* 密码工具类
-*/
+/**
+ * 密码加密配置类
+ *
+ * @author zlt
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
public class DefaultPasswordConfig {
- /**
- * 装配BCryptPasswordEncoder用户密码的匹配
- * @return
- */
@Bean
- public PasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
+ @ConditionalOnMissingBean
+ public PasswordEncoder passwordEncoder() {
+ return PwdEncoderUtil.getDelegatingPasswordEncoder("bcrypt");
}
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/DefaultWebMvcConfig.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/DefaultWebMvcConfig.java
index d2d446ee..225bf366 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/DefaultWebMvcConfig.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/DefaultWebMvcConfig.java
@@ -16,7 +16,7 @@
* @author zlt
* @date 2019/8/5
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class DefaultWebMvcConfig implements WebMvcConfigurer {
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/LoginArgResolverConfig.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/LoginArgResolverConfig.java
deleted file mode 100644
index bbffbf4f..00000000
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/config/LoginArgResolverConfig.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.central.common.config;
-
-import com.central.common.feign.UserService;
-import com.central.common.resolver.ClientArgumentResolver;
-import com.central.common.resolver.TokenArgumentResolver;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.web.method.support.HandlerMethodArgumentResolver;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-import java.util.List;
-
-/**
- * 公共配置类, 一些公共工具配置
- *
- * @author zlt
- * @date 2018/8/25
- */
-public class LoginArgResolverConfig implements WebMvcConfigurer {
- @Lazy
- @Autowired
- private UserService userService;
- /**
- * Token参数解析
- *
- * @param argumentResolvers 解析类
- */
- @Override
- public void addArgumentResolvers(List argumentResolvers) {
- //注入用户信息
- argumentResolvers.add(new TokenArgumentResolver(userService));
- //注入应用信息
- argumentResolvers.add(new ClientArgumentResolver());
- }
-}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/CommonConstant.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/CommonConstant.java
index 3c7b3238..c2d97a8b 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/CommonConstant.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/CommonConstant.java
@@ -10,7 +10,7 @@ public interface CommonConstant {
/**
* 项目版本号(banner使用)
*/
- String PROJECT_VERSION = "3.5.0";
+ String PROJECT_VERSION = "5.3.0";
/**
* token请求头名称
@@ -98,10 +98,11 @@ public interface CommonConstant {
String SIMPLE_MONTH_FORMAT = "yyyyMM";
String SIMPLE_DATE_FORMAT = "yyyyMMdd";
String SIMPLE_DATETIME_FORMAT = "yyyyMMddHHmmss";
+ String TIME_ZONE_GMT8 = "GMT+8";
String DEF_USER_PASSWORD = "123456";
- String LOCK_KEY_PREFIX = "LOCK_KEY:";
+ String LOCK_KEY_PREFIX = "LOCK_KEY";
/**
* 租户id参数
@@ -125,4 +126,9 @@ public interface CommonConstant {
* 注册中心元数据 版本号
*/
String METADATA_VERSION = "version";
+
+ /**
+ * 文件分隔符
+ */
+ String PATH_SPLIT = "/";
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/ConfigConstants.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/ConfigConstants.java
index cd8375cd..af2cadbd 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/ConfigConstants.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/ConfigConstants.java
@@ -11,4 +11,14 @@ public interface ConfigConstants {
* 是否开启自定义隔离规则
*/
String CONFIG_RIBBON_ISOLATION_ENABLED = "zlt.ribbon.isolation.enabled";
+
+ String CONFIG_LOADBALANCE_ISOLATION = "zlt.loadbalance.isolation";
+
+ String CONFIG_LOADBALANCE_ISOLATION_ENABLE = CONFIG_LOADBALANCE_ISOLATION + ".enabled";
+
+ String CONFIG_LOADBALANCE_ISOLATION_CHOOSER = CONFIG_LOADBALANCE_ISOLATION + ".chooser";
+
+ String CONFIG_LOADBALANCE_VERSION = "zlt.loadbalance.version";
+
+
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/SecurityConstants.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/SecurityConstants.java
index 788ed929..4cca9640 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/SecurityConstants.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/constant/SecurityConstants.java
@@ -4,6 +4,9 @@
* Security 权限常量
*
* @author zlt
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
public interface SecurityConstants {
/**
@@ -31,6 +34,11 @@ public interface SecurityConstants {
*/
String TENANT_HEADER = "x-tenant-header";
+ /**
+ * 账号类型信息头
+ */
+ String ACCOUNT_TYPE_HEADER = "x-account-type-header";
+
/**
* 基础角色
*/
@@ -122,10 +130,6 @@ public interface SecurityConstants {
* OAUTH模式登录处理地址
*/
String OAUTH_LOGIN_PRO_URL = "/user/login";
- /**
- * PASSWORD模式登录处理地址
- */
- String PASSWORD_LOGIN_PRO_URL = "/oauth/user/token";
/**
* 获取授权码地址
*/
@@ -135,13 +139,9 @@ public interface SecurityConstants {
*/
String LOGIN_PAGE = "/login.html";
/**
- * 默认的OPENID登录请求处理url
+ * 登录失败页面
*/
- String OPENID_TOKEN_URL = "/oauth/openId/token";
- /**
- * 手机登录URL
- */
- String MOBILE_TOKEN_URL = "/oauth/mobile/token";
+ String LOGIN_FAILURE_PAGE = LOGIN_PAGE + "?error";
/**
* 登出URL
*/
@@ -154,6 +154,10 @@ public interface SecurityConstants {
* redis中授权token对应的key
*/
String REDIS_TOKEN_AUTH = "auth:";
+ /**
+ * 值同access 过期时间+60
+ */
+ String ACCESS_BAK = "access_bak:";
/**
* redis中应用对应的token集合的key
*/
@@ -166,4 +170,23 @@ public interface SecurityConstants {
* rsa公钥
*/
String RSA_PUBLIC_KEY = "pubkey.txt";
+ /**
+ * 获取id_token的response_type
+ */
+ String ID_TOKEN = "id_token";
+
+ /**
+ * 令牌颁发者
+ */
+ String ISS = "http://zlt2000.cn";
+
+ /**
+ * 默认账号类型
+ */
+ String DEF_ACCOUNT_TYPE = "admin";
+
+ /**
+ * 账号类型参数名
+ */
+ String ACCOUNT_TYPE_PARAM_NAME = "account_type";
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/fallback/UserServiceFallbackFactory.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/fallback/UserServiceFallbackFactory.java
index cde1ff9a..1b7bbec8 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/fallback/UserServiceFallbackFactory.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/fallback/UserServiceFallbackFactory.java
@@ -3,7 +3,7 @@
import com.central.common.feign.UserService;
import com.central.common.model.LoginAppUser;
import com.central.common.model.SysUser;
-import feign.hystrix.FallbackFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
/**
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/AbstractDistributedLock.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/AbstractDistributedLock.java
deleted file mode 100644
index f2863f9c..00000000
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/AbstractDistributedLock.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.central.common.lock;
-
-/**
- * 分布式锁抽象类
- *
- * @author zlt
- * @date 2018/5/29 14:14
- */
-public abstract class AbstractDistributedLock implements DistributedLock{
-
- @Override
- public boolean lock(String key) {
- return lock(key, TIMEOUT_MILLIS, RETRY_TIMES, SLEEP_MILLIS);
- }
-
- @Override
- public boolean lock(String key, int retryTimes) {
- return lock(key, TIMEOUT_MILLIS, retryTimes, SLEEP_MILLIS);
- }
-
- @Override
- public boolean lock(String key, int retryTimes, long sleepMillis) {
- return lock(key, TIMEOUT_MILLIS, retryTimes, sleepMillis);
- }
-
- @Override
- public boolean lock(String key, long expire) {
- return lock(key, expire, RETRY_TIMES, SLEEP_MILLIS);
- }
-
- @Override
- public boolean lock(String key, long expire, int retryTimes) {
- return lock(key, expire, retryTimes, SLEEP_MILLIS);
- }
-}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/DistributedLock.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/DistributedLock.java
index b44043a5..6bdbefcd 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/DistributedLock.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/DistributedLock.java
@@ -1,93 +1,72 @@
package com.central.common.lock;
+import java.util.concurrent.TimeUnit;
+
/**
* 分布式锁顶级接口
- * 例如:
- * RETRY_TIMES=100,SLEEP_MILLIS=100
- * RETRY_TIMES * SLEEP_MILLIS = 10000 意味着如果一直获取不了锁,最长会等待10秒后抛超时异常
*
* @author zlt
* @date 2018/5/29 14:12
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
public interface DistributedLock {
-
- /**
- * 默认超时时间
- */
- long TIMEOUT_MILLIS = 5000;
-
/**
- * 重试次数
+ * 获取锁,如果获取不成功则一直等待直到lock被获取
+ * @param key 锁的key
+ * @param leaseTime 加锁的时间,超过这个时间后锁便自动解锁;
+ * 如果leaseTime为-1,则保持锁定直到显式解锁
+ * @param unit {@code leaseTime} 参数的时间单位
+ * @param isFair 是否公平锁
+ * @return 锁对象
*/
- int RETRY_TIMES = 100;
+ ZLock lock(String key, long leaseTime, TimeUnit unit, boolean isFair) throws Exception;
- /**
- * 每次重试后等待的时间
- */
- long SLEEP_MILLIS = 100;
+ default ZLock lock(String key, long leaseTime, TimeUnit unit) throws Exception {
+ return this.lock(key, leaseTime, unit, false);
+ }
+ default ZLock lock(String key, boolean isFair) throws Exception {
+ return this.lock(key, -1, null, isFair);
+ }
+ default ZLock lock(String key) throws Exception {
+ return this.lock(key, -1, null, false);
+ }
/**
- * 获取锁
- *
- * @param key key
- * @return 成功/失败
+ * 尝试获取锁,如果锁不可用则等待最多waitTime时间后放弃
+ * @param key 锁的key
+ * @param waitTime 获取锁的最大尝试时间(单位 {@code unit})
+ * @param leaseTime 加锁的时间,超过这个时间后锁便自动解锁;
+ * 如果leaseTime为-1,则保持锁定直到显式解锁
+ * @param unit {@code waitTime} 和 {@code leaseTime} 参数的时间单位
+ * @return 锁对象,如果获取锁失败则为null
*/
- boolean lock(String key);
+ ZLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws Exception;
- /**
- * 获取锁
- *
- * @param key key
- * @param retryTimes 重试次数
- * @return 成功/失败
- */
- boolean lock(String key, int retryTimes);
+ default ZLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit) throws Exception {
+ return this.tryLock(key, waitTime, leaseTime, unit, false);
+ }
+ default ZLock tryLock(String key, long waitTime, TimeUnit unit, boolean isFair) throws Exception {
+ return this.tryLock(key, waitTime, -1, unit, isFair);
+ }
+ default ZLock tryLock(String key, long waitTime, TimeUnit unit) throws Exception {
+ return this.tryLock(key, waitTime, -1, unit, false);
+ }
/**
- * 获取锁
- *
- * @param key key
- * @param retryTimes 重试次数
- * @param sleepMillis 获取锁失败的重试间隔
- * @return 成功/失败
- */
- boolean lock(String key, int retryTimes, long sleepMillis);
-
- /**
- * 获取锁
- *
- * @param key key
- * @param expire 获取锁超时时间
- * @return 成功/失败
- */
- boolean lock(String key, long expire);
-
- /**
- * 获取锁
- *
- * @param key key
- * @param expire 获取锁超时时间
- * @param retryTimes 重试次数
- * @return 成功/失败
- */
- boolean lock(String key, long expire, int retryTimes);
-
- /**
- * 获取锁
- *
- * @param key key
- * @param expire 获取锁超时时间
- * @param retryTimes 重试次数
- * @param sleepMillis 获取锁失败的重试间隔
- * @return 成功/失败
+ * 释放锁
+ * @param lock 锁对象
*/
- boolean lock(String key, long expire, int retryTimes, long sleepMillis);
+ void unlock(Object lock) throws Exception;
/**
* 释放锁
- *
- * @param key key值
- * @return 释放结果
+ * @param zLock 锁抽象对象
*/
- boolean releaseLock(String key);
+ default void unlock(ZLock zLock) throws Exception {
+ if (zLock != null) {
+ this.unlock(zLock.getLock());
+ }
+ }
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/Lock.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/Lock.java
new file mode 100644
index 00000000..28d35749
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/Lock.java
@@ -0,0 +1,39 @@
+package com.central.common.lock;
+
+import java.lang.annotation.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author zlt
+ * @date 2020/6/6
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Lock {
+ /**
+ * 锁的key
+ */
+ String key();
+ /**
+ * 获取锁的最大尝试时间(单位 {@code unit})
+ * 该值大于0则使用 locker.tryLock 方法加锁,否则使用 locker.lock 方法
+ */
+ long waitTime() default 0;
+ /**
+ * 加锁的时间(单位 {@code unit}),超过这个时间后锁便自动解锁;
+ * 如果leaseTime为-1,则保持锁定直到显式解锁
+ */
+ long leaseTime() default -1;
+ /**
+ * 参数的时间单位
+ */
+ TimeUnit unit() default TimeUnit.SECONDS;
+ /**
+ * 是否公平锁
+ */
+ boolean isFair() default false;
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/LockAspect.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/LockAspect.java
new file mode 100644
index 00000000..f160e335
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/LockAspect.java
@@ -0,0 +1,98 @@
+package com.central.common.lock;
+
+import cn.hutool.core.util.StrUtil;
+import com.central.common.exception.LockException;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.DefaultParameterNameDiscoverer;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+
+/**
+ * 分布式锁切面
+ *
+ * @author zlt
+ * @date 2020/6/6
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Slf4j
+@Aspect
+public class LockAspect {
+ @Autowired(required = false)
+ private DistributedLock locker;
+
+ /**
+ * 用于SpEL表达式解析.
+ */
+ private SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
+ /**
+ * 用于获取方法参数定义名字.
+ */
+ private DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
+
+ @Around("@within(lock) || @annotation(lock)")
+ public Object aroundLock(ProceedingJoinPoint point, Lock lock) throws Throwable {
+ if (lock == null) {
+ // 获取类上的注解
+ lock = point.getTarget().getClass().getDeclaredAnnotation(Lock.class);
+ }
+ String lockKey = lock.key();
+ if (locker == null) {
+ throw new LockException("DistributedLock is null");
+ }
+ if (StrUtil.isEmpty(lockKey)) {
+ throw new LockException("lockKey is null");
+ }
+
+ if (lockKey.contains("#")) {
+ MethodSignature methodSignature = (MethodSignature)point.getSignature();
+ //获取方法参数值
+ Object[] args = point.getArgs();
+ lockKey = getValBySpEL(lockKey, methodSignature, args);
+ }
+ ZLock lockObj = null;
+ try {
+ //加锁
+ if (lock.waitTime() > 0) {
+ lockObj = locker.tryLock(lockKey, lock.waitTime(), lock.leaseTime(), lock.unit(), lock.isFair());
+ } else {
+ lockObj = locker.lock(lockKey, lock.leaseTime(), lock.unit(), lock.isFair());
+ }
+
+ if (lockObj != null) {
+ return point.proceed();
+ } else {
+ throw new LockException("锁等待超时");
+ }
+ } finally {
+ locker.unlock(lockObj);
+ }
+ }
+
+ /**
+ * 解析spEL表达式
+ */
+ private String getValBySpEL(String spEL, MethodSignature methodSignature, Object[] args) {
+ //获取方法形参名数组
+ String[] paramNames = nameDiscoverer.getParameterNames(methodSignature.getMethod());
+ if (paramNames != null && paramNames.length > 0) {
+ Expression expression = spelExpressionParser.parseExpression(spEL);
+ // spring的表达式上下文对象
+ EvaluationContext context = new StandardEvaluationContext();
+ // 给上下文赋值
+ for(int i = 0; i < args.length; i++) {
+ context.setVariable(paramNames[i], args[i]);
+ }
+ return expression.getValue(context).toString();
+ }
+ return null;
+ }
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/ZLock.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/ZLock.java
new file mode 100644
index 00000000..ffe60769
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/lock/ZLock.java
@@ -0,0 +1,26 @@
+package com.central.common.lock;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 锁对象抽象
+ *
+ * @author zlt
+ * @date 2020/7/28
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@AllArgsConstructor
+public class ZLock implements AutoCloseable {
+ @Getter
+ private final Object lock;
+
+ private final DistributedLock locker;
+
+ @Override
+ public void close() throws Exception {
+ locker.unlock(lock);
+ }
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/LoginAppUser.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/LoginAppUser.java
index 2001764b..558b5c89 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/LoginAppUser.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/LoginAppUser.java
@@ -33,7 +33,7 @@ public class LoginAppUser extends SysUser implements SocialUserDetails {
public Collection extends GrantedAuthority> getAuthorities() {
Collection collection = new HashSet<>();
if (!CollectionUtils.isEmpty(super.getRoles())) {
- super.getRoles().parallelStream().forEach(role -> collection.add(new SimpleGrantedAuthority(role.getCode())));
+ super.getRoles().forEach(role -> collection.add(new SimpleGrantedAuthority(role.getCode())));
}
return collection;
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SuperEntity.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SuperEntity.java
index f7778346..30894a40 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SuperEntity.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SuperEntity.java
@@ -27,9 +27,4 @@ public class SuperEntity> extends Model {
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
-
- @Override
- protected Serializable pkVal() {
- return this.id;
- }
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SysRole.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SysRole.java
index 303071b4..45f050bb 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SysRole.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SysRole.java
@@ -1,5 +1,6 @@
package com.central.common.model;
+import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -15,5 +16,6 @@ public class SysRole extends SuperEntity {
private static final long serialVersionUID = 4497149010220586111L;
private String code;
private String name;
+ @TableField(exist = false)
private Long userId;
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/resolver/TokenArgumentResolver.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/resolver/TokenArgumentResolver.java
index 19a1183f..32e5ef37 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/resolver/TokenArgumentResolver.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/resolver/TokenArgumentResolver.java
@@ -23,6 +23,9 @@
*
* @author zlt
* @date 2018/12/21
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
@Slf4j
public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
@@ -61,6 +64,8 @@ public Object resolveArgument(MethodParameter methodParameter,
String userId = request.getHeader(SecurityConstants.USER_ID_HEADER);
String username = request.getHeader(SecurityConstants.USER_HEADER);
String roles = request.getHeader(SecurityConstants.ROLE_HEADER);
+ //账号类型
+ String accountType = request.getHeader(SecurityConstants.ACCOUNT_TYPE_HEADER);
if (StrUtil.isBlank(username)) {
log.warn("resolveArgument error username is empty");
return null;
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/service/ISuperService.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/service/ISuperService.java
index 95e258bb..97af475f 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/service/ISuperService.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/service/ISuperService.java
@@ -9,51 +9,46 @@
*
* @author zlt
* @date 2019/1/10
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
public interface ISuperService extends IService {
/**
* 幂等性新增记录
+ * 例子如下:
+ * String username = sysUser.getUsername();
+ * boolean result = super.saveIdempotency(sysUser, lock
+ * , LOCK_KEY_USERNAME+username
+ * , new QueryWrapper().eq("username", username));
*
* @param entity 实体对象
- * @param lock 锁实例
+ * @param locker 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @param msg 对象已存在提示信息
* @return
*/
- boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper, String msg);
+ boolean saveIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper countWrapper, String msg) throws Exception;
- /**
- * 幂等性新增记录
- *
- * @param entity 实体对象
- * @param lock 锁实例
- * @param lockKey 锁的key
- * @param countWrapper 判断是否存在的条件
- * @return
- */
- boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper);
+ boolean saveIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper countWrapper) throws Exception;
/**
* 幂等性新增或更新记录
+ * 例子如下:
+ * String username = sysUser.getUsername();
+ * boolean result = super.saveOrUpdateIdempotency(sysUser, lock
+ * , LOCK_KEY_USERNAME+username
+ * , new QueryWrapper().eq("username", username));
*
* @param entity 实体对象
- * @param lock 锁实例
+ * @param locker 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @param msg 对象已存在提示信息
* @return
*/
- boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper, String msg);
+ boolean saveOrUpdateIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper countWrapper, String msg) throws Exception;
- /**
- * 幂等性新增或更新记录
- *
- * @param entity 实体对象
- * @param lock 锁实例
- * @param lockKey 锁的key
- * @param countWrapper 判断是否存在的条件
- * @return
- */
- boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper);
+ boolean saveOrUpdateIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper countWrapper) throws Exception;
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/service/impl/SuperServiceImpl.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/service/impl/SuperServiceImpl.java
index 0eab2a52..8c678084 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/service/impl/SuperServiceImpl.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/service/impl/SuperServiceImpl.java
@@ -12,47 +12,37 @@
import com.central.common.exception.IdempotencyException;
import com.central.common.exception.LockException;
import com.central.common.lock.DistributedLock;
+import com.central.common.lock.ZLock;
import com.central.common.service.ISuperService;
import java.io.Serializable;
import java.util.Objects;
+import java.util.concurrent.TimeUnit;
/**
* service实现父类
*
* @author zlt
* @date 2019/1/10
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
public class SuperServiceImpl, T> extends ServiceImpl implements ISuperService {
- /**
- * 幂等性新增记录
- * 例子如下:
- * String username = sysUser.getUsername();
- * boolean result = super.saveIdempotency(sysUser, lock
- * , LOCK_KEY_USERNAME+username
- * , new QueryWrapper().eq("username", username));
- *
- * @param entity 实体对象
- * @param lock 锁实例
- * @param lockKey 锁的key
- * @param countWrapper 判断是否存在的条件
- * @param msg 对象已存在提示信息
- * @return
- */
@Override
- public boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper, String msg) {
- if (lock == null) {
+ public boolean saveIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper countWrapper, String msg) throws Exception {
+ if (locker == null) {
throw new LockException("DistributedLock is null");
}
if (StrUtil.isEmpty(lockKey)) {
throw new LockException("lockKey is null");
}
- try {
- //加锁
- boolean isLock = lock.lock(lockKey);
- if (isLock) {
+ try (
+ ZLock lock = locker.tryLock(lockKey, 10, 60, TimeUnit.SECONDS);
+ ) {
+ if (lock != null) {
//判断记录是否已存在
- int count = super.count(countWrapper);
+ long count = super.count(countWrapper);
if (count == 0) {
return super.save(entity);
} else {
@@ -64,47 +54,21 @@ public boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, W
} else {
throw new LockException("锁等待超时");
}
- } finally {
- lock.releaseLock(lockKey);
}
}
- /**
- * 幂等性新增记录
- *
- * @param entity 实体对象
- * @param lock 锁实例
- * @param lockKey 锁的key
- * @param countWrapper 判断是否存在的条件
- * @return
- */
@Override
- public boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper) {
+ public boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper) throws Exception {
return saveIdempotency(entity, lock, lockKey, countWrapper, null);
}
- /**
- * 幂等性新增或更新记录
- * 例子如下:
- * String username = sysUser.getUsername();
- * boolean result = super.saveOrUpdateIdempotency(sysUser, lock
- * , LOCK_KEY_USERNAME+username
- * , new QueryWrapper().eq("username", username));
- *
- * @param entity 实体对象
- * @param lock 锁实例
- * @param lockKey 锁的key
- * @param countWrapper 判断是否存在的条件
- * @param msg 对象已存在提示信息
- * @return
- */
@Override
- public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper, String msg) {
+ public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper, String msg) throws Exception {
if (null != entity) {
Class> cls = entity.getClass();
TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
if (null != tableInfo && StrUtil.isNotEmpty(tableInfo.getKeyProperty())) {
- Object idVal = ReflectionKit.getMethodValue(cls, entity, tableInfo.getKeyProperty());
+ Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty());
if (StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal))) {
if (StrUtil.isEmpty(msg)) {
msg = "已存在";
@@ -120,22 +84,8 @@ public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lo
return false;
}
- /**
- * 幂等性新增或更新记录
- * 例子如下:
- * String username = sysUser.getUsername();
- * boolean result = super.saveOrUpdateIdempotency(sysUser, lock
- * , LOCK_KEY_USERNAME+username
- * , new QueryWrapper().eq("username", username));
- *
- * @param entity 实体对象
- * @param lock 锁实例
- * @param lockKey 锁的key
- * @param countWrapper 判断是否存在的条件
- * @return
- */
@Override
- public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper) {
+ public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper) throws Exception {
return this.saveOrUpdateIdempotency(entity, lock, lockKey, countWrapper, null);
}
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/JsonUtil.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/JsonUtil.java
new file mode 100644
index 00000000..575dd56d
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/JsonUtil.java
@@ -0,0 +1,209 @@
+package com.central.common.utils;
+
+import com.central.common.constant.CommonConstant;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.json.JsonReadFeature;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.*;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+/**
+ * 基于 Jackson 的 json 工具类
+ *
+ * @author zlt
+ * @date 2020/10/8
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+public class JsonUtil {
+ private final static ObjectMapper MAPPER = new ObjectMapper();
+
+ static {
+ // 忽略在json字符串中存在,但是在java对象中不存在对应属性的情况
+ MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ // 忽略空Bean转json的错误
+ MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
+ // 允许不带引号的字段名称
+ MAPPER.configure(JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES.mappedFeature(), true);
+ // 允许单引号
+ MAPPER.configure(JsonReadFeature.ALLOW_SINGLE_QUOTES.mappedFeature(), true);
+ // allow int startWith 0
+ MAPPER.configure(JsonReadFeature.ALLOW_LEADING_ZEROS_FOR_NUMBERS.mappedFeature(), true);
+ // 允许字符串存在转义字符:\r \n \t
+ MAPPER.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
+ // 排除空值字段
+ MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ // 使用驼峰式
+ MAPPER.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CAMEL_CASE);
+ // 使用bean名称
+ MAPPER.enable(MapperFeature.USE_STD_BEAN_NAMING);
+ // 所有日期格式都统一为固定格式
+ MAPPER.setDateFormat(new SimpleDateFormat(CommonConstant.DATETIME_FORMAT));
+ MAPPER.setTimeZone(TimeZone.getTimeZone(CommonConstant.TIME_ZONE_GMT8));
+ }
+
+ /**
+ * 对象转换为json字符串
+ * @param o 要转换的对象
+ */
+ public static String toJSONString(Object o) {
+ return toJSONString(o, false);
+ }
+
+ /**
+ * 对象转换为json字符串
+ * @param o 要转换的对象
+ * @param format 是否格式化json
+ */
+ public static String toJSONString(Object o, boolean format) {
+ try {
+ if (o == null) {
+ return "";
+ }
+ if (o instanceof Number) {
+ return o.toString();
+ }
+ if (o instanceof String) {
+ return (String)o;
+ }
+ if (format) {
+ return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(o);
+ }
+ return MAPPER.writeValueAsString(o);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 字符串转换为指定对象
+ * @param json json字符串
+ * @param cls 目标对象
+ */
+ public static T toObject(JsonNode json, Class cls) {
+ if(json == null || cls == null){
+ return null;
+ }
+ return MAPPER.convertValue(json, cls);
+ }
+
+ /**
+ * 字符串转换为指定对象,并增加泛型转义
+ * 例如:List test = toObject(jsonStr, List.class, Integer.class);
+ * @param json json字符串
+ * @param parametrized 目标对象
+ * @param parameterClasses 泛型对象
+ */
+ public static T toObject(String json, Class> parametrized, Class>... parameterClasses) {
+ if(StringUtils.isBlank(json) || parametrized == null){
+ return null;
+ }
+ try {
+ JavaType javaType = MAPPER.getTypeFactory().constructParametricType(parametrized, parameterClasses);
+ return MAPPER.readValue(json, javaType);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 字符串转换为指定对象
+ * @param json json字符串
+ * @param typeReference 目标对象类型
+ */
+ public static T toObject(String json, TypeReference typeReference) {
+ if(StringUtils.isBlank(json) || typeReference == null){
+ return null;
+ }
+ try {
+ return MAPPER.readValue(json, typeReference);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 字符串转换为指定对象
+ * @param json json字符串
+ * @param cls 目标对象
+ */
+ public static T toObject(String json, Class cls) {
+ if(StringUtils.isBlank(json) || cls == null){
+ return null;
+ }
+ try {
+ return MAPPER.readValue(json, cls);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 字符串转换为JsonNode对象
+ * @param json json字符串
+ */
+ public static JsonNode parse(String json) {
+ if (StringUtils.isBlank(json)) {
+ return null;
+ }
+ try {
+ return MAPPER.readTree(json);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 对象转换为map对象
+ * @param o 要转换的对象
+ */
+ public static Map toMap(Object o) {
+ if (o == null) {
+ return null;
+ }
+ if (o instanceof String) {
+ return toObject((String)o, Map.class);
+ }
+ return MAPPER.convertValue(o, Map.class);
+ }
+
+ /**
+ * json字符串转换为list对象
+ * @param json json字符串
+ */
+ public static List toList(String json) {
+ if (StringUtils.isBlank(json)) {
+ return null;
+ }
+ try {
+ return MAPPER.readValue(json, List.class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * json字符串转换为list对象,并指定元素类型
+ * @param json json字符串
+ * @param cls list的元素类型
+ */
+ public static List toList(String json, Class cls) {
+ if (StringUtils.isBlank(json)) {
+ return null;
+ }
+ try {
+ JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, cls);
+ return MAPPER.readValue(json, javaType);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/PwdEncoderUtil.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/PwdEncoderUtil.java
new file mode 100644
index 00000000..dfe0b18c
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/PwdEncoderUtil.java
@@ -0,0 +1,45 @@
+package com.central.common.utils;
+
+import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
+import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
+import org.springframework.util.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * PasswordEncoder实现工具类
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/5/7
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+public class PwdEncoderUtil {
+ public static PasswordEncoder getDelegatingPasswordEncoder(String encodingId) {
+ Map encoders = new HashMap<>();
+ encoders.put("bcrypt", new BCryptPasswordEncoder());
+ encoders.put("ldap", new org.springframework.security.crypto.password.LdapShaPasswordEncoder());
+ encoders.put("MD4", new org.springframework.security.crypto.password.Md4PasswordEncoder());
+ encoders.put("MD5", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5"));
+ encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance());
+ encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
+ encoders.put("scrypt", new SCryptPasswordEncoder());
+ encoders.put("SHA-1", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-1"));
+ encoders.put("SHA-256", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-256"));
+ encoders.put("sha256", new org.springframework.security.crypto.password.StandardPasswordEncoder());
+ encoders.put("argon2", new Argon2PasswordEncoder());
+
+ Assert.isTrue(encoders.containsKey(encodingId), encodingId + " is not found in idToPasswordEncoder");
+
+ DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(encodingId, encoders);
+ delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(encoders.get(encodingId));
+ return delegatingPasswordEncoder;
+ }
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/ResponseUtil.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/ResponseUtil.java
index f489366c..2da8db68 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/ResponseUtil.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/ResponseUtil.java
@@ -1,21 +1,12 @@
package com.central.common.utils;
-import com.alibaba.fastjson.JSONObject;
import com.central.common.model.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
-import org.springframework.core.io.buffer.DataBuffer;
-import org.springframework.core.io.buffer.DataBufferFactory;
-import org.springframework.core.io.buffer.DataBufferUtils;
-import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
-import org.springframework.http.server.reactive.ServerHttpResponse;
-import org.springframework.web.server.ServerWebExchange;
-import reactor.core.publisher.Mono;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Writer;
-import java.nio.charset.Charset;
/**
* @author zlt
@@ -63,7 +54,7 @@ public static void responseFailed(ObjectMapper objectMapper, HttpServletResponse
}
private static void responseWrite(ObjectMapper objectMapper, HttpServletResponse response, Result result) throws IOException {
- response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
+ response.setContentType(MediaType.APPLICATION_JSON_VALUE);
try (
Writer writer = response.getWriter()
) {
@@ -71,38 +62,4 @@ private static void responseWrite(ObjectMapper objectMapper, HttpServletResponse
writer.flush();
}
}
-
- /**
- * webflux的response返回json对象
- */
- public static Mono responseWriter(ServerWebExchange exchange, int httpStatus, String msg) {
- Result result = Result.of(null, httpStatus, msg);
- return responseWrite(exchange, httpStatus, result);
- }
-
- public static Mono responseFailed(ServerWebExchange exchange, String msg) {
- Result result = Result.failed(msg);
- return responseWrite(exchange, HttpStatus.INTERNAL_SERVER_ERROR.value(), result);
- }
-
- public static Mono responseFailed(ServerWebExchange exchange, int httpStatus, String msg) {
- Result result = Result.failed(msg);
- return responseWrite(exchange, httpStatus, result);
- }
-
- public static Mono responseWrite(ServerWebExchange exchange, int httpStatus, Result result) {
- if (httpStatus == 0) {
- httpStatus = HttpStatus.INTERNAL_SERVER_ERROR.value();
- }
- ServerHttpResponse response = exchange.getResponse();
- response.getHeaders().setAccessControlAllowCredentials(true);
- response.getHeaders().setAccessControlAllowOrigin("*");
- response.setStatusCode(HttpStatus.valueOf(httpStatus));
- response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
- DataBufferFactory dataBufferFactory = response.bufferFactory();
- DataBuffer buffer = dataBufferFactory.wrap(JSONObject.toJSONString(result).getBytes(Charset.defaultCharset()));
- return response.writeWith(Mono.just(buffer)).doOnError((error) -> {
- DataBufferUtils.release(buffer);
- });
- }
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/Sequence.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/Sequence.java
index e40f2250..efb246e4 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/Sequence.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/Sequence.java
@@ -177,8 +177,8 @@ public synchronized long nextId() {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
- // 不同毫秒内,序列号置为 1 - 3 随机数
- sequence = ThreadLocalRandom.current().nextLong(1, 3);
+ // 不同毫秒内,序列号置为 1 - 100 随机数
+ sequence = ThreadLocalRandom.current().nextLong(1, 101);
}
lastTimestamp = timestamp;
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/WebfluxResponseUtil.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/WebfluxResponseUtil.java
new file mode 100644
index 00000000..14d7dc9a
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/WebfluxResponseUtil.java
@@ -0,0 +1,56 @@
+package com.central.common.utils;
+
+import com.central.common.model.Result;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.core.io.buffer.DataBufferFactory;
+import org.springframework.core.io.buffer.DataBufferUtils;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.nio.charset.Charset;
+
+/**
+ * @author zlt
+ * @date 2020/5/5
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+public class WebfluxResponseUtil {
+ /**
+ * webflux的response返回json对象
+ */
+ public static Mono responseWriter(ServerWebExchange exchange, int httpStatus, String msg) {
+ Result result = Result.of(null, httpStatus, msg);
+ return responseWrite(exchange, httpStatus, result);
+ }
+
+ public static Mono responseFailed(ServerWebExchange exchange, String msg) {
+ Result result = Result.failed(msg);
+ return responseWrite(exchange, HttpStatus.INTERNAL_SERVER_ERROR.value(), result);
+ }
+
+ public static Mono responseFailed(ServerWebExchange exchange, int httpStatus, String msg) {
+ Result result = Result.failed(msg);
+ return responseWrite(exchange, httpStatus, result);
+ }
+
+ public static Mono responseWrite(ServerWebExchange exchange, int httpStatus, Result result) {
+ if (httpStatus == 0) {
+ httpStatus = HttpStatus.INTERNAL_SERVER_ERROR.value();
+ }
+ ServerHttpResponse response = exchange.getResponse();
+ response.getHeaders().setAccessControlAllowCredentials(true);
+ response.getHeaders().setAccessControlAllowOrigin("*");
+ response.setStatusCode(HttpStatus.valueOf(httpStatus));
+ response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+ DataBufferFactory dataBufferFactory = response.bufferFactory();
+ DataBuffer buffer = dataBufferFactory.wrap(JsonUtil.toJSONString(result).getBytes(Charset.defaultCharset()));
+ return response.writeWith(Mono.just(buffer)).doOnError((error) -> {
+ DataBufferUtils.release(buffer);
+ });
+ }
+}
diff --git a/zlt-commons/zlt-common-core/src/main/resources/META-INF/spring.factories b/zlt-commons/zlt-common-core/src/main/resources/META-INF/spring.factories
index 247a1118..c56b4c97 100644
--- a/zlt-commons/zlt-common-core/src/main/resources/META-INF/spring.factories
+++ b/zlt-commons/zlt-common-core/src/main/resources/META-INF/spring.factories
@@ -2,4 +2,5 @@ org.springframework.context.ApplicationContextInitializer=\
com.central.common.config.BannerInitializer
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-com.central.common.feign.fallback.UserServiceFallbackFactory
\ No newline at end of file
+com.central.common.feign.fallback.UserServiceFallbackFactory,\
+com.central.common.lock.LockAspect
\ No newline at end of file
diff --git a/zlt-commons/zlt-common-spring-boot-starter/pom.xml b/zlt-commons/zlt-common-spring-boot-starter/pom.xml
index 9c0225b3..f948cf19 100644
--- a/zlt-commons/zlt-common-spring-boot-starter/pom.xml
+++ b/zlt-commons/zlt-common-spring-boot-starter/pom.xml
@@ -4,7 +4,7 @@
com.zlt
zlt-commons
- 3.5.0
+ 5.3.0
zlt-common-spring-boot-starter
公共通用组件
diff --git a/zlt-commons/zlt-common-spring-boot-starter/src/main/resources/META-INF/spring.factories b/zlt-commons/zlt-common-spring-boot-starter/src/main/resources/META-INF/spring.factories
index a277125f..baf1f730 100644
--- a/zlt-commons/zlt-common-spring-boot-starter/src/main/resources/META-INF/spring.factories
+++ b/zlt-commons/zlt-common-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -1,3 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-com.central.common.filter.TenantFilter,\
-com.central.common.filter.TraceFilter
\ No newline at end of file
+com.central.common.filter.TenantFilter
\ No newline at end of file
diff --git a/zlt-commons/zlt-db-spring-boot-starter/pom.xml b/zlt-commons/zlt-db-spring-boot-starter/pom.xml
index 69c4e936..cc8201b0 100644
--- a/zlt-commons/zlt-db-spring-boot-starter/pom.xml
+++ b/zlt-commons/zlt-db-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
com.zlt
zlt-commons
- 3.5.0
+ 5.3.0
4.0.0
jar
diff --git a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/DateMetaObjectHandler.java b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/DateMetaObjectHandler.java
index 5c258020..cf86429e 100644
--- a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/DateMetaObjectHandler.java
+++ b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/DateMetaObjectHandler.java
@@ -12,7 +12,7 @@
* @author zlt
* @date 2018/12/11
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class DateMetaObjectHandler implements MetaObjectHandler {
diff --git a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/MybatisPlusAutoConfigure.java b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/MybatisPlusAutoConfigure.java
index 05635297..2b1e855e 100644
--- a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/MybatisPlusAutoConfigure.java
+++ b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/MybatisPlusAutoConfigure.java
@@ -1,12 +1,12 @@
package com.central.db.config;
-import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
-import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
-import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
-import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.central.common.properties.TenantProperties;
+import com.central.db.interceptor.CustomTenantInterceptor;
import com.central.db.properties.MybatisPlusAutoFillProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -20,16 +20,13 @@
* @author zlt
* @date 2020/4/5
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@EnableConfigurationProperties(MybatisPlusAutoFillProperties.class)
public class MybatisPlusAutoConfigure {
@Autowired
- private TenantHandler tenantHandler;
-
- @Autowired
- private ISqlParserFilter sqlParserFilter;
+ private TenantLineHandler tenantLineHandler;
@Autowired
private TenantProperties tenantProperties;
@@ -41,17 +38,17 @@ public class MybatisPlusAutoConfigure {
* 分页插件,自动识别数据库类型
*/
@Bean
- public PaginationInterceptor paginationInterceptor() {
- PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
+ public MybatisPlusInterceptor paginationInterceptor() {
+ MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
+ mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
boolean enableTenant = tenantProperties.getEnable();
//是否开启多租户隔离
if (enableTenant) {
- TenantSqlParser tenantSqlParser = new TenantSqlParser()
- .setTenantHandler(tenantHandler);
- paginationInterceptor.setSqlParserList(CollUtil.toList(tenantSqlParser));
- paginationInterceptor.setSqlParserFilter(sqlParserFilter);
+ CustomTenantInterceptor tenantInterceptor = new CustomTenantInterceptor(
+ tenantLineHandler, tenantProperties.getIgnoreSqls());
+ mpInterceptor.addInnerInterceptor(tenantInterceptor);
}
- return paginationInterceptor;
+ return mpInterceptor;
}
@Bean
diff --git a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/TenantAutoConfigure.java b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/TenantAutoConfigure.java
index 40f38d6e..8778dd6d 100644
--- a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/TenantAutoConfigure.java
+++ b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/TenantAutoConfigure.java
@@ -1,14 +1,11 @@
package com.central.db.config;
-import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
-import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
-import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
+import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.central.common.context.TenantContextHolder;
import com.central.common.properties.TenantProperties;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
-import org.apache.ibatis.mapping.MappedStatement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@@ -25,13 +22,13 @@ public class TenantAutoConfigure {
private TenantProperties tenantProperties;
@Bean
- public TenantHandler tenantHandler() {
- return new TenantHandler() {
+ public TenantLineHandler tenantLineHandler() {
+ return new TenantLineHandler() {
/**
* 获取租户id
*/
@Override
- public Expression getTenantId(boolean where) {
+ public Expression getTenantId() {
String tenant = TenantContextHolder.getTenant();
if (tenant != null) {
return new StringValue(TenantContextHolder.getTenant());
@@ -39,37 +36,16 @@ public Expression getTenantId(boolean where) {
return new NullValue();
}
- /**
- * 获取租户列名
- */
- @Override
- public String getTenantIdColumn() {
- return "tenant_id";
- }
-
/**
* 过滤不需要根据租户隔离的表
* @param tableName 表名
*/
@Override
- public boolean doTableFilter(String tableName) {
+ public boolean ignoreTable(String tableName) {
return tenantProperties.getIgnoreTables().stream().anyMatch(
(e) -> e.equalsIgnoreCase(tableName)
);
}
};
}
-
- /**
- * 过滤不需要根据租户隔离的MappedStatement
- */
- @Bean
- public ISqlParserFilter sqlParserFilter() {
- return metaObject -> {
- MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
- return tenantProperties.getIgnoreSqls().stream().anyMatch(
- (e) -> e.equalsIgnoreCase(ms.getId())
- );
- };
- }
}
diff --git a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/interceptor/CustomTenantInterceptor.java b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/interceptor/CustomTenantInterceptor.java
new file mode 100644
index 00000000..f2083e7f
--- /dev/null
+++ b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/interceptor/CustomTenantInterceptor.java
@@ -0,0 +1,44 @@
+package com.central.db.interceptor;
+
+import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
+import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * MyBatis-plus租户拦截器
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2022/5/6
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+public class CustomTenantInterceptor extends TenantLineInnerInterceptor {
+ private List ignoreSqls;
+
+ public CustomTenantInterceptor(TenantLineHandler tenantLineHandler, List ignoreSqls) {
+ super(tenantLineHandler);
+ this.ignoreSqls = ignoreSqls;
+ }
+
+ @Override
+ public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds
+ , ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
+ if (isIgnoreMappedStatement(ms.getId())) {
+ return;
+ }
+ super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);
+ }
+
+ private boolean isIgnoreMappedStatement(String msId) {
+ return ignoreSqls.stream().anyMatch((e) -> e.equalsIgnoreCase(msId));
+ }
+}
diff --git a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/properties/MybatisPlusAutoFillProperties.java b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/properties/MybatisPlusAutoFillProperties.java
index fe50bdd7..44b88f0f 100644
--- a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/properties/MybatisPlusAutoFillProperties.java
+++ b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/properties/MybatisPlusAutoFillProperties.java
@@ -11,7 +11,7 @@
* @author zlt
* @date 2020/4/5
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Setter
diff --git a/zlt-commons/zlt-elasticsearch-spring-boot-starter/pom.xml b/zlt-commons/zlt-elasticsearch-spring-boot-starter/pom.xml
index 4377c535..4d2bce09 100644
--- a/zlt-commons/zlt-elasticsearch-spring-boot-starter/pom.xml
+++ b/zlt-commons/zlt-elasticsearch-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
com.zlt
zlt-commons
- 3.5.0
+ 5.3.0
4.0.0
jar
diff --git a/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/config/RestAutoConfigure.java b/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/config/RestAutoConfigure.java
index f6fc6695..40711835 100644
--- a/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/config/RestAutoConfigure.java
+++ b/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/config/RestAutoConfigure.java
@@ -8,8 +8,8 @@
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientBuilderCustomizer;
-import org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientProperties;
+import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientProperties;
+import org.springframework.boot.autoconfigure.elasticsearch.RestClientBuilderCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
@@ -21,14 +21,14 @@
* @author zlt
* @date 2020/3/28
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@EnableConfigurationProperties(RestClientPoolProperties.class)
public class RestAutoConfigure {
@Bean
public RestClientBuilderCustomizer restClientBuilderCustomizer(RestClientPoolProperties poolProperties
- , RestClientProperties restProperties) {
+ , ElasticsearchRestClientProperties restProperties) {
return (builder) -> {
setRequestConfig(builder, poolProperties);
@@ -51,7 +51,7 @@ private void setRequestConfig(RestClientBuilder builder, RestClientPoolPropertie
/**
* 异步httpclient连接数配置
*/
- private void setHttpClientConfig(RestClientBuilder builder, RestClientPoolProperties poolProperties, RestClientProperties restProperties){
+ private void setHttpClientConfig(RestClientBuilder builder, RestClientPoolProperties poolProperties, ElasticsearchRestClientProperties restProperties){
builder.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(poolProperties.getMaxConnectNum())
.setMaxConnPerRoute(poolProperties.getMaxConnectPerRoute());
diff --git a/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/properties/RestClientPoolProperties.java b/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/properties/RestClientPoolProperties.java
index 0c9344a6..16b9d232 100644
--- a/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/properties/RestClientPoolProperties.java
+++ b/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/properties/RestClientPoolProperties.java
@@ -11,7 +11,7 @@
* @author zlt
* @date 2020/3/28
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Setter
diff --git a/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/utils/SearchBuilder.java b/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/utils/SearchBuilder.java
index 05defd88..ba2521a3 100644
--- a/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/utils/SearchBuilder.java
+++ b/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/utils/SearchBuilder.java
@@ -3,9 +3,10 @@
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
import com.central.common.model.PageResult;
+import com.central.common.utils.JsonUtil;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.beanutils.PropertyUtils;
@@ -21,8 +22,7 @@
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
-import org.springframework.data.elasticsearch.ElasticsearchException;
-import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
+import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
@@ -37,7 +37,7 @@
* @author zlt
* @date 2020/3/28
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Setter
@@ -51,6 +51,10 @@ public class SearchBuilder {
* 高亮后缀
*/
private static final String HIGHLIGHTER_POST_TAGS = "";
+ /**
+ * 排序顺序
+ */
+ private static final String SORT_ORDER_ASC = "ASC";
private SearchRequest searchRequest;
private SearchSourceBuilder searchBuilder;
@@ -64,26 +68,24 @@ private SearchBuilder(SearchRequest searchRequest, SearchSourceBuilder searchBui
/**
* 生成SearchBuilder实例
- * @param elasticsearchTemplate
+ * @param client
* @param indexName
*/
- public static SearchBuilder builder(ElasticsearchRestTemplate elasticsearchTemplate, String indexName) {
+ public static SearchBuilder builder(RestHighLevelClient client, String indexName) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.source(searchSourceBuilder);
- RestHighLevelClient client = elasticsearchTemplate.getClient();
return new SearchBuilder(searchRequest, searchSourceBuilder, client);
}
/**
* 生成SearchBuilder实例
- * @param elasticsearchTemplate
+ * @param client
*/
- public static SearchBuilder builder(ElasticsearchRestTemplate elasticsearchTemplate) {
+ public static SearchBuilder builder(RestHighLevelClient client) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest searchRequest = new SearchRequest();
searchRequest.source(searchSourceBuilder);
- RestHighLevelClient client = elasticsearchTemplate.getClient();
return new SearchBuilder(searchRequest, searchSourceBuilder, client);
}
@@ -119,9 +121,24 @@ public SearchBuilder setStringQuery(String queryStr) {
* @param limit 每页显示数
*/
public SearchBuilder setPage(Integer page, Integer limit) {
+ setPage(page, limit, false);
+ return this;
+ }
+
+ /**
+ * 设置分页
+ * @param page 当前页数
+ * @param limit 每页显示数
+ * @param trackTotalHits 分页总数是否显示所有条数,默认只显示10000
+ */
+ public SearchBuilder setPage(Integer page, Integer limit, boolean trackTotalHits) {
if (page != null && limit != null) {
searchBuilder.from((page - 1) * limit)
.size(limit);
+ if (trackTotalHits) {
+ searchBuilder.trackTotalHits(trackTotalHits);
+ }
+
}
return this;
}
@@ -131,9 +148,15 @@ public SearchBuilder setPage(Integer page, Integer limit) {
* @param field 排序字段
* @param order 顺序方向
*/
- public SearchBuilder addSort(String field, SortOrder order) {
+ public SearchBuilder addSort(String field, String order) {
if (StrUtil.isNotEmpty(field) && order != null) {
- searchBuilder.sort(field, order);
+ SortOrder so;
+ if (SORT_ORDER_ASC.equals(order)) {
+ so = SortOrder.ASC;
+ } else {
+ so = SortOrder.DESC;
+ }
+ searchBuilder.sort(field, so);
}
return this;
}
@@ -185,16 +208,16 @@ public SearchResponse get() throws IOException {
}
/**
- * 返回列表结果 List
+ * 返回列表结果 List
*/
- public List getList() throws IOException {
+ public List getList() throws IOException {
return getList(this.get().getHits());
}
/**
* 返回分页结果 PageResult
*/
- public PageResult getPage() throws IOException {
+ public PageResult getPage() throws IOException {
return this.getPage(null, null);
}
@@ -203,30 +226,31 @@ public PageResult getPage() throws IOException {
* @param page 当前页数
* @param limit 每页显示
*/
- public PageResult getPage(Integer page, Integer limit) throws IOException {
+ public PageResult getPage(Integer page, Integer limit) throws IOException {
this.setPage(page, limit);
SearchResponse response = this.get();
SearchHits searchHits = response.getHits();
- long totalCnt = searchHits.getTotalHits();
- List list = getList(searchHits);
- return PageResult.builder().data(list).code(0).count(totalCnt).build();
+ long totalCnt = searchHits.getTotalHits().value;
+ List list = getList(searchHits);
+ return PageResult.builder().data(list).code(0).count(totalCnt).build();
}
/**
* 返回JSON列表数据
*/
- private List getList(SearchHits searchHits) {
- List list = new ArrayList<>();
+ private List getList(SearchHits searchHits) {
+ List list = new ArrayList<>();
if (searchHits != null) {
searchHits.forEach(item -> {
- JSONObject jsonObject = JSON.parseObject(item.getSourceAsString());
- jsonObject.put("id", item.getId());
+ JsonNode jsonNode = JsonUtil.parse(item.getSourceAsString());
+ ObjectNode objectNode = (ObjectNode)jsonNode;
+ objectNode.put("id", item.getId());
Map highlightFields = item.getHighlightFields();
if (highlightFields != null) {
- populateHighLightedFields(jsonObject, highlightFields);
+ populateHighLightedFields(objectNode, highlightFields);
}
- list.add(jsonObject);
+ list.add(objectNode);
});
}
return list;
@@ -242,10 +266,14 @@ private void populateHighLightedFields(T result, Map
try {
String name = field.getName();
if (!name.endsWith(".keyword")) {
- PropertyUtils.setProperty(result, field.getName(), concat(field.fragments()));
+ if (result instanceof ObjectNode) {
+ ((ObjectNode)result).put(field.getName(), concat(field.fragments()));
+ } else {
+ PropertyUtils.setProperty(result, field.getName(), concat(field.fragments()));
+ }
}
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
- throw new ElasticsearchException("failed to set highlighted value for field: " + field.getName()
+ throw new UncategorizedElasticsearchException("failed to set highlighted value for field: " + field.getName()
+ " with value: " + Arrays.toString(field.getFragments()), e);
}
}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/pom.xml b/zlt-commons/zlt-loadbalancer-spring-boot-starter/pom.xml
similarity index 85%
rename from zlt-commons/zlt-ribbon-spring-boot-starter/pom.xml
rename to zlt-commons/zlt-loadbalancer-spring-boot-starter/pom.xml
index ecfb929b..8336ea38 100644
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/pom.xml
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/pom.xml
@@ -1,48 +1,48 @@
-
-
-
- com.zlt
- zlt-commons
- 3.5.0
-
- 4.0.0
- jar
- zlt-ribbon-spring-boot-starter
- 远程通信通用组件
-
-
- com.zlt
- zlt-common-core
-
-
- org.springframework.cloud
- spring-cloud-starter-openfeign
-
-
- org.springframework.cloud
- spring-cloud-starter-netflix-ribbon
-
-
- com.alibaba.cloud
- spring-cloud-starter-alibaba-nacos-discovery
- true
-
-
- org.apache.httpcomponents
- httpclient
-
-
- javax.servlet
- javax.servlet-api
- true
-
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
-
+
+
+
+ com.zlt
+ zlt-commons
+ 5.3.0
+
+ 4.0.0
+ jar
+ zlt-loadbalancer-spring-boot-starter
+ 负载均衡通用组件
+
+
+ com.zlt
+ zlt-common-core
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+ org.springframework.cloud
+ spring-cloud-starter-loadbalancer
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+ true
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+ javax.servlet
+ javax.servlet-api
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/RestTemplateAutoConfigure.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/RestTemplateAutoConfigure.java
similarity index 87%
rename from zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/RestTemplateAutoConfigure.java
rename to zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/RestTemplateAutoConfigure.java
index c96fb859..b5fe3ef3 100644
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/RestTemplateAutoConfigure.java
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/RestTemplateAutoConfigure.java
@@ -1,77 +1,79 @@
-package com.central.common.ribbon;
-
-import com.central.common.ribbon.config.RestTemplateProperties;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.config.Registry;
-import org.apache.http.config.RegistryBuilder;
-import org.apache.http.conn.socket.ConnectionSocketFactory;
-import org.apache.http.conn.socket.PlainConnectionSocketFactory;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.client.loadbalancer.LoadBalanced;
-import org.springframework.context.annotation.Bean;
-import org.springframework.http.client.ClientHttpRequestFactory;
-import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
-import org.springframework.web.client.RestTemplate;
-
-/**
- * @author zlt
- * @date 2018/11/17
- */
-@EnableConfigurationProperties(RestTemplateProperties.class)
-public class RestTemplateAutoConfigure {
- @Autowired
- private RestTemplateProperties restTemplateProperties;
-
- @LoadBalanced
- @Bean
- public RestTemplate restTemplate() {
- RestTemplate restTemplate = new RestTemplate();
- restTemplate.setRequestFactory(httpRequestFactory());
- return restTemplate;
- }
-
- /**
- * httpclient 实现的ClientHttpRequestFactory
- */
- @Bean
- public ClientHttpRequestFactory httpRequestFactory() {
- return new HttpComponentsClientHttpRequestFactory(httpClient());
- }
-
- /**
- * 使用连接池的 httpclient
- */
- @Bean
- public HttpClient httpClient() {
- Registry registry = RegistryBuilder.create()
- .register("http", PlainConnectionSocketFactory.getSocketFactory())
- .register("https", SSLConnectionSocketFactory.getSocketFactory())
- .build();
- PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
- // 最大链接数
- connectionManager.setMaxTotal(restTemplateProperties.getMaxTotal());
- // 同路由并发数20
- connectionManager.setDefaultMaxPerRoute(restTemplateProperties.getMaxPerRoute());
-
- RequestConfig requestConfig = RequestConfig.custom()
- // 读超时
- .setSocketTimeout(restTemplateProperties.getReadTimeout())
- // 链接超时
- .setConnectTimeout(restTemplateProperties.getConnectTimeout())
- // 链接不够用的等待时间
- .setConnectionRequestTimeout(restTemplateProperties.getReadTimeout())
- .build();
-
- return HttpClientBuilder.create()
- .setDefaultRequestConfig(requestConfig)
- .setConnectionManager(connectionManager)
- .setRetryHandler(new DefaultHttpRequestRetryHandler(3, true))
- .build();
- }
-}
+package com.central.common.lb;
+
+import com.central.common.lb.config.RestTemplateProperties;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author zlt
+ * @date 2018/11/17
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@EnableConfigurationProperties(RestTemplateProperties.class)
+public class RestTemplateAutoConfigure {
+ @Autowired
+ private RestTemplateProperties restTemplateProperties;
+
+ @Bean
+ public RestTemplate restTemplate(ClientHttpRequestFactory httpRequestFactory) {
+ RestTemplate restTemplate = new RestTemplate();
+ restTemplate.setRequestFactory(httpRequestFactory);
+ return restTemplate;
+ }
+
+ /**
+ * httpclient 实现的ClientHttpRequestFactory
+ */
+ @Bean
+ public ClientHttpRequestFactory httpRequestFactory(HttpClient httpClient) {
+ return new HttpComponentsClientHttpRequestFactory(httpClient);
+ }
+
+ /**
+ * 使用连接池的 httpclient
+ */
+ @Bean
+ public HttpClient httpClient() {
+ Registry registry = RegistryBuilder.create()
+ .register("http", PlainConnectionSocketFactory.getSocketFactory())
+ .register("https", SSLConnectionSocketFactory.getSocketFactory())
+ .build();
+ PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
+ // 最大链接数
+ connectionManager.setMaxTotal(restTemplateProperties.getMaxTotal());
+ // 同路由并发数20
+ connectionManager.setDefaultMaxPerRoute(restTemplateProperties.getMaxPerRoute());
+
+ RequestConfig requestConfig = RequestConfig.custom()
+ // 读超时
+ .setSocketTimeout(restTemplateProperties.getReadTimeout())
+ // 链接超时
+ .setConnectTimeout(restTemplateProperties.getConnectTimeout())
+ // 链接不够用的等待时间
+ .setConnectionRequestTimeout(restTemplateProperties.getReadTimeout())
+ .build();
+
+ return HttpClientBuilder.create()
+ .setDefaultRequestConfig(requestConfig)
+ .setConnectionManager(connectionManager)
+ .setRetryHandler(new DefaultHttpRequestRetryHandler(3, true))
+ .build();
+ }
+}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/annotation/EnableBaseFeignInterceptor.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/annotation/EnableBaseFeignInterceptor.java
similarity index 77%
rename from zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/annotation/EnableBaseFeignInterceptor.java
rename to zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/annotation/EnableBaseFeignInterceptor.java
index 6dc5fd3f..a0a9a817 100644
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/annotation/EnableBaseFeignInterceptor.java
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/annotation/EnableBaseFeignInterceptor.java
@@ -1,6 +1,6 @@
-package com.central.common.ribbon.annotation;
+package com.central.common.lb.annotation;
-import com.central.common.ribbon.config.FeignInterceptorConfig;
+import com.central.common.lb.config.FeignInterceptorConfig;
import org.springframework.context.annotation.Import;
import java.lang.annotation.ElementType;
@@ -14,7 +14,7 @@
* @author zlt
* @date 2019/10/26
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Target(ElementType.TYPE)
@@ -22,4 +22,4 @@
@Import(FeignInterceptorConfig.class)
public @interface EnableBaseFeignInterceptor {
-}
+}
\ No newline at end of file
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/annotation/EnableFeignInterceptor.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/annotation/EnableFeignInterceptor.java
similarity index 74%
rename from zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/annotation/EnableFeignInterceptor.java
rename to zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/annotation/EnableFeignInterceptor.java
index 5f97ac6b..9bd4c02e 100644
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/annotation/EnableFeignInterceptor.java
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/annotation/EnableFeignInterceptor.java
@@ -1,7 +1,7 @@
-package com.central.common.ribbon.annotation;
+package com.central.common.lb.annotation;
-import com.central.common.ribbon.config.FeignHttpInterceptorConfig;
-import com.central.common.ribbon.config.FeignInterceptorConfig;
+import com.central.common.lb.config.FeignHttpInterceptorConfig;
+import com.central.common.lb.config.FeignInterceptorConfig;
import org.springframework.context.annotation.Import;
import java.lang.annotation.ElementType;
@@ -14,9 +14,11 @@
*
* @author zlt
*/
+
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import({FeignInterceptorConfig.class, FeignHttpInterceptorConfig.class})
public @interface EnableFeignInterceptor {
}
+
diff --git a/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/chooser/IRuleChooser.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/chooser/IRuleChooser.java
new file mode 100644
index 00000000..356d2c7d
--- /dev/null
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/chooser/IRuleChooser.java
@@ -0,0 +1,14 @@
+package com.central.common.lb.chooser;
+
+import org.springframework.cloud.client.ServiceInstance;
+
+import java.util.List;
+
+/**
+ * service选择器类
+ *
+ * @author jarvis create by 2022/3/13
+ */
+public interface IRuleChooser {
+ ServiceInstance choose(List instances);
+}
diff --git a/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/chooser/RandomRuleChooser.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/chooser/RandomRuleChooser.java
new file mode 100644
index 00000000..aec82573
--- /dev/null
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/chooser/RandomRuleChooser.java
@@ -0,0 +1,27 @@
+package com.central.common.lb.chooser;
+
+import com.alibaba.nacos.common.utils.CollectionUtils;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.cloud.client.ServiceInstance;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * 随机的选择器
+ *
+ * @author jarvis create by 2022/3/13
+ */
+@Log4j2
+public class RandomRuleChooser implements IRuleChooser {
+ @Override
+ public ServiceInstance choose(List instances) {
+ if(CollectionUtils.isNotEmpty(instances)){
+ int randomValue = ThreadLocalRandom.current().nextInt(instances.size());
+ ServiceInstance serviceInstance = instances.get(randomValue);
+ log.info("选择了ip为{}, 端口为:{}的服务", serviceInstance.getHost(), serviceInstance.getPort());
+ return serviceInstance;
+ }
+ return null;
+ }
+}
diff --git a/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/chooser/RoundRuleChooser.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/chooser/RoundRuleChooser.java
new file mode 100644
index 00000000..2817f0a9
--- /dev/null
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/chooser/RoundRuleChooser.java
@@ -0,0 +1,33 @@
+package com.central.common.lb.chooser;
+
+import com.alibaba.nacos.common.utils.CollectionUtils;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.cloud.client.ServiceInstance;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 轮询选择器
+ *
+ * @author jarvis create by 2022/3/13
+ */
+@Log4j2
+public class RoundRuleChooser implements IRuleChooser{
+
+ private AtomicInteger position;
+
+ public RoundRuleChooser() {
+ this.position = new AtomicInteger(1000);
+ }
+
+ @Override
+ public ServiceInstance choose(List instances) {
+ if(CollectionUtils.isNotEmpty(instances)){
+ ServiceInstance serviceInstance = instances.get(Math.abs(position.incrementAndGet() % instances.size()));
+ log.info("选择了ip为{}, 端口为:{}的服务", serviceInstance.getHost(), serviceInstance.getPort());
+ return serviceInstance;
+ }
+ return null;
+ }
+}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/config/FeignHttpInterceptorConfig.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/FeignHttpInterceptorConfig.java
similarity index 90%
rename from zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/config/FeignHttpInterceptorConfig.java
rename to zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/FeignHttpInterceptorConfig.java
index d85ece2e..4e0e006a 100644
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/config/FeignHttpInterceptorConfig.java
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/FeignHttpInterceptorConfig.java
@@ -1,8 +1,11 @@
-package com.central.common.ribbon.config;
+package com.central.common.lb.config;
import com.central.common.constant.CommonConstant;
import com.central.common.constant.SecurityConstants;
+import com.central.common.lb.utils.QueryUtils;
import feign.RequestInterceptor;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@@ -12,6 +15,7 @@
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
+import java.util.Map;
/**
* feign拦截器,只包含http相关数据
@@ -19,7 +23,7 @@
* @author zlt
* @date 2019/10/26
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class FeignHttpInterceptorConfig {
@@ -37,6 +41,7 @@ public void initialize() {
* 使用feign client访问别的微服务时,将上游传过来的access_token、username、roles等信息放入header传递给下一个服务
*/
@Bean
+ @ConditionalOnClass(HttpServletRequest.class)
public RequestInterceptor httpFeignInterceptor() {
return template -> {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
@@ -77,7 +82,7 @@ private String extractHeaderToken(HttpServletRequest request) {
Enumeration headers = request.getHeaders(CommonConstant.TOKEN_HEADER);
while (headers.hasMoreElements()) {
String value = headers.nextElement();
- if ((value.toLowerCase().startsWith(CommonConstant.BEARER_TYPE))) {
+ if ((value.toLowerCase().startsWith(CommonConstant.BEARER_TYPE.toLowerCase()))) {
String authHeaderValue = value.substring(CommonConstant.BEARER_TYPE.length()).trim();
int commaIndex = authHeaderValue.indexOf(',');
if (commaIndex > 0) {
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/config/FeignInterceptorConfig.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/FeignInterceptorConfig.java
similarity index 64%
rename from zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/config/FeignInterceptorConfig.java
rename to zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/FeignInterceptorConfig.java
index 3ae3c0b6..59da835e 100644
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/config/FeignInterceptorConfig.java
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/FeignInterceptorConfig.java
@@ -1,21 +1,22 @@
-package com.central.common.ribbon.config;
+package com.central.common.lb.config;
import cn.hutool.core.util.StrUtil;
-import com.central.common.constant.CommonConstant;
import com.central.common.constant.SecurityConstants;
import com.central.common.context.TenantContextHolder;
import feign.RequestInterceptor;
-import org.slf4j.MDC;
import org.springframework.context.annotation.Bean;
/**
* feign拦截器,只包含基础数据
*
* @author zlt
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
public class FeignInterceptorConfig {
/**
- * 使用feign client访问别的微服务时,将上游传过来的client、traceid等信息放入header传递给下一个服务
+ * 使用feign client访问别的微服务时,将上游传过来的client等信息放入header传递给下一个服务
*/
@Bean
public RequestInterceptor baseFeignInterceptor() {
@@ -25,12 +26,6 @@ public RequestInterceptor baseFeignInterceptor() {
if (StrUtil.isNotEmpty(tenant)) {
template.header(SecurityConstants.TENANT_HEADER, tenant);
}
-
- //传递日志traceId
- String traceId = MDC.get(CommonConstant.LOG_TRACE_ID);
- if (StrUtil.isNotEmpty(traceId)) {
- template.header(CommonConstant.TRACE_ID_HEADER, traceId);
- }
};
}
}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/config/RestTemplateProperties.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/RestTemplateProperties.java
similarity index 84%
rename from zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/config/RestTemplateProperties.java
rename to zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/RestTemplateProperties.java
index bbd13882..b0dd15cb 100644
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/config/RestTemplateProperties.java
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/RestTemplateProperties.java
@@ -1,33 +1,36 @@
-package com.central.common.ribbon.config;
-
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * RestTemplate 配置
- *
- * @author zlt
- * @date 2017/11/17
- */
-@Setter
-@Getter
-@ConfigurationProperties(prefix = "zlt.rest-template")
-public class RestTemplateProperties {
- /**
- * 最大链接数
- */
- private int maxTotal = 200;
- /**
- * 同路由最大并发数
- */
- private int maxPerRoute = 50;
- /**
- * 读取超时时间 ms
- */
- private int readTimeout = 35000;
- /**
- * 链接超时时间 ms
- */
- private int connectTimeout = 10000;
-}
+package com.central.common.lb.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * RestTemplate 配置
+ *
+ * @author zlt
+ * @date 2017/11/17
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Setter
+@Getter
+@ConfigurationProperties(prefix = "zlt.rest-template")
+public class RestTemplateProperties {
+ /**
+ * 最大链接数
+ */
+ private int maxTotal = 200;
+ /**
+ * 同路由最大并发数
+ */
+ private int maxPerRoute = 50;
+ /**
+ * 读取超时时间 ms
+ */
+ private int readTimeout = 35000;
+ /**
+ * 链接超时时间 ms
+ */
+ private int connectTimeout = 10000;
+}
diff --git a/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/VerionIsolationAutoConfig.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/VerionIsolationAutoConfig.java
new file mode 100644
index 00000000..2ecd5166
--- /dev/null
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/VerionIsolationAutoConfig.java
@@ -0,0 +1,17 @@
+package com.central.common.lb.config;
+
+import com.central.common.constant.ConfigConstants;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
+import org.springframework.context.annotation.Import;
+
+/**
+ *
+ *
+ * @author jarvis create by 2022/4/10
+ */
+@LoadBalancerClients(defaultConfiguration = VersionLoadBalancerConfig.class)
+@ConditionalOnProperty(prefix = ConfigConstants.CONFIG_LOADBALANCE_ISOLATION, name = "enabled", havingValue = "true", matchIfMissing = false)
+@Import({VersionRegisterBeanPostProcessor.class})
+public class VerionIsolationAutoConfig {
+}
diff --git a/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/VersionLoadBalancerConfig.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/VersionLoadBalancerConfig.java
new file mode 100644
index 00000000..e34964e7
--- /dev/null
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/VersionLoadBalancerConfig.java
@@ -0,0 +1,68 @@
+package com.central.common.lb.config;
+
+import com.central.common.constant.ConfigConstants;
+import com.central.common.lb.chooser.IRuleChooser;
+import com.central.common.lb.chooser.RoundRuleChooser;
+import com.central.common.lb.loadbalancer.VersionLoadBalancer;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
+import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
+import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.env.Environment;
+import org.springframework.util.ClassUtils;
+
+/**
+ * 版本控制的路由选择类配置
+ *
+ * @author jarvis create by 2022/3/9
+ */
+@Log4j2
+public class VersionLoadBalancerConfig{
+
+ private IRuleChooser defaultRuleChooser = null;
+
+ @Bean
+ @ConditionalOnMissingBean(IRuleChooser.class)
+ @ConditionalOnProperty(prefix = ConfigConstants.CONFIG_LOADBALANCE_ISOLATION, value = "chooser")
+ public IRuleChooser customRuleChooser(Environment environment, ApplicationContext context){
+
+ IRuleChooser chooser = new RoundRuleChooser();
+ if (environment.containsProperty(ConfigConstants.CONFIG_LOADBALANCE_ISOLATION_CHOOSER)) {
+ String chooserRuleClassString = environment.getProperty(ConfigConstants.CONFIG_LOADBALANCE_ISOLATION_CHOOSER);
+ if(StringUtils.isNotBlank(chooserRuleClassString)){
+ try {
+ Class> ruleClass = ClassUtils.forName(chooserRuleClassString, context.getClassLoader());
+ chooser = (IRuleChooser) ruleClass.newInstance();
+ } catch (ClassNotFoundException e) {
+ log.error("没有找到定义的选择器,将使用内置的选择器", e);
+ } catch (InstantiationException e) {
+ log.error("没法创建定义的选择器,将使用内置的选择器", e);
+ } catch (IllegalAccessException e) {
+ log.error("没法创建定义的选择器,将使用内置的选择器", e);
+ }
+ }
+ }
+ return chooser;
+ }
+
+ @Bean
+ @ConditionalOnMissingBean(value = IRuleChooser.class)
+ public IRuleChooser defaultRuleChooser(){
+ return new RoundRuleChooser();
+ }
+
+
+ @Bean
+ @ConditionalOnProperty(prefix = ConfigConstants.CONFIG_LOADBALANCE_ISOLATION, name = "enabled", havingValue = "true", matchIfMissing = false)
+ public ReactorServiceInstanceLoadBalancer versionServiceLoadBalancer(Environment environment
+ , LoadBalancerClientFactory loadBalancerClientFactory, IRuleChooser ruleChooser){
+ String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
+ return new VersionLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class)
+ , name, ruleChooser);
+ }
+}
diff --git a/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/VersionRegisterBeanPostProcessor.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/VersionRegisterBeanPostProcessor.java
new file mode 100644
index 00000000..7f5a3d1f
--- /dev/null
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/config/VersionRegisterBeanPostProcessor.java
@@ -0,0 +1,27 @@
+package com.central.common.lb.config;
+
+import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
+import com.alibaba.nacos.common.utils.StringUtils;
+import com.central.common.constant.CommonConstant;
+import com.central.common.constant.ConfigConstants;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+
+/**
+ * 将版本注册到注册中心的组件
+ *
+ * @author jarvis create by 2022/3/20
+ */
+public class VersionRegisterBeanPostProcessor implements BeanPostProcessor {
+ @Value("${"+ ConfigConstants.CONFIG_LOADBALANCE_VERSION+":}")
+ private String version;
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ if(bean instanceof NacosDiscoveryProperties && StringUtils.isNotBlank(version)){
+ NacosDiscoveryProperties nacosDiscoveryProperties = (NacosDiscoveryProperties) bean;
+ nacosDiscoveryProperties.getMetadata().putIfAbsent(CommonConstant.METADATA_VERSION, version);
+ }
+ return bean;
+ }
+}
diff --git a/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/loadbalancer/VersionLoadBalancer.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/loadbalancer/VersionLoadBalancer.java
new file mode 100644
index 00000000..6b8c4acd
--- /dev/null
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/loadbalancer/VersionLoadBalancer.java
@@ -0,0 +1,100 @@
+package com.central.common.lb.loadbalancer;
+
+import com.central.common.constant.CommonConstant;
+import com.central.common.lb.chooser.IRuleChooser;
+import com.central.common.lb.utils.QueryUtils;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.loadbalancer.*;
+import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
+import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
+import reactor.core.publisher.Mono;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 自定义版本路由选择
+ *
+ * @author jarvis create by 2022/3/9
+ */
+@Log4j2
+public class VersionLoadBalancer implements ReactorServiceInstanceLoadBalancer {
+
+ private final static String KEY_DEFAULT = "default";
+
+ private ObjectProvider serviceInstanceListSuppliers;
+
+ private String serviceId;
+
+ private IRuleChooser ruleChooser;
+
+ public VersionLoadBalancer(ObjectProvider serviceInstanceListSuppliers, String serviceId, IRuleChooser ruleChooser) {
+ this.serviceInstanceListSuppliers = serviceInstanceListSuppliers;
+ this.serviceId = serviceId;
+ this.ruleChooser = ruleChooser;
+ }
+
+ @Override
+ public Mono> choose(Request request) {
+ // 从request中获取版本,兼容webflux方式
+ RequestData requestData = ((RequestDataContext) (request.getContext())).getClientRequest();
+ String version = getVersionFromRequestData(requestData);
+ log.debug("选择的版本号为:{}", version);
+ return serviceInstanceListSuppliers.getIfAvailable().get(request).next().map(instanceList->{
+ return getInstanceResponse(instanceList, version);
+ });
+ }
+
+ private String getVersionFromRequestData(RequestData requestData){
+ Map queryMap = QueryUtils.getQueryMap(requestData.getUrl());
+ if(MapUtils.isNotEmpty(queryMap)&& queryMap.containsKey(CommonConstant.Z_L_T_VERSION)&& StringUtils.isNotBlank(queryMap.get(CommonConstant.Z_L_T_VERSION))){
+ return queryMap.get(CommonConstant.Z_L_T_VERSION);
+ }else if(requestData.getHeaders().containsKey(CommonConstant.Z_L_T_VERSION)){
+ return requestData.getHeaders().get(CommonConstant.Z_L_T_VERSION).get(0);
+ }
+ return null;
+ }
+ /**
+ * 1. 先获取到拦截的版本,如果不为空的话就将service列表过滤,寻找metadata中哪个服务是配置的版本,
+ * 如果版本为空则不需要进行过滤直接提交给service选择器进行选择
+ * 2. 如果没有找到版本对应的实例,则找所有版本为空或者版本号为default的实例
+ * 3.将instance列表提交到选择器根据对应的策略返回一个instance
+ * @param instances
+ * @return
+ */
+ private Response getInstanceResponse(Listinstances, String version){
+ List filteredServiceIstanceList = instances;
+ if(StringUtils.isNotBlank(version)){
+ if(CollectionUtils.isNotEmpty(instances)){
+ filteredServiceIstanceList = instances.stream()
+ .filter(item->item.getMetadata().containsKey(CommonConstant.METADATA_VERSION)&&
+ version.equals(item.getMetadata().get(CommonConstant.METADATA_VERSION)))
+ .collect(Collectors.toList());
+ }
+ }
+ // 如果没有找到对应的版本实例时,选择版本号为空的或这版本为default的实例
+ if(CollectionUtils.isEmpty(filteredServiceIstanceList)){
+ filteredServiceIstanceList = instances.stream()
+ .filter(item->!item.getMetadata().containsKey(CommonConstant.METADATA_VERSION)||
+ StringUtils.isBlank(item.getMetadata().get(CommonConstant.METADATA_VERSION))
+ || "default".equals(item.getMetadata().get(CommonConstant.METADATA_VERSION)))
+ .collect(Collectors.toList());
+ }
+ // 经过两轮过滤后如果能找到的话就选择,不然返回空
+ if(CollectionUtils.isNotEmpty(filteredServiceIstanceList)){
+ ServiceInstance serviceInstance = this.ruleChooser.choose(filteredServiceIstanceList);
+ if(!Objects.isNull(serviceInstance)){
+ log.debug("使用serviceId为:{}服务, 选择version为:{}, 地址:{}:{},", serviceId, version
+ , serviceInstance.getHost(), serviceInstance.getPort());
+ return new DefaultResponse(serviceInstance);
+ }
+ }
+ // 返回空的返回体
+ return new EmptyResponse();
+ }
+}
diff --git a/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/utils/QueryUtils.java b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/utils/QueryUtils.java
new file mode 100644
index 00000000..2321d5bf
--- /dev/null
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/java/com/central/common/lb/utils/QueryUtils.java
@@ -0,0 +1,42 @@
+package com.central.common.lb.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 解析request的query参数工具
+ *
+ * @author jarvis create by 2022/5/8
+ */
+public class QueryUtils {
+ /**
+ * 通过query字符串得到参数的map
+ * @param queryString ?后的字符
+ * @return
+ */
+ public static Map getQueryMap(String queryString){
+ if(StringUtils.isNotBlank(queryString)){
+ return Arrays.stream(queryString.split("&")).map(item -> item.split("="))
+ .collect(Collectors.toMap(key -> key[0], value -> value.length > 1 && StringUtils.isNotBlank(value[1]) ? value[1] : ""));
+ }
+ return Collections.emptyMap();
+ }
+
+ /**
+ * 通过url获取参数map
+ * @param uri
+ * @return
+ */
+ public static Map getQueryMap(URI uri){
+ if(Objects.nonNull(uri)){
+ return getQueryMap(uri.getQuery());
+ }
+ return Collections.emptyMap();
+ }
+}
diff --git a/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/resources/META-INF/spring.factories b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 00000000..6154b24d
--- /dev/null
+++ b/zlt-commons/zlt-loadbalancer-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,3 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+com.central.common.lb.RestTemplateAutoConfigure,\
+com.central.common.lb.config.VerionIsolationAutoConfig
\ No newline at end of file
diff --git a/zlt-commons/zlt-log-spring-boot-starter/pom.xml b/zlt-commons/zlt-log-spring-boot-starter/pom.xml
index 031c20f5..6ba3e818 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/pom.xml
+++ b/zlt-commons/zlt-log-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
com.zlt
zlt-commons
- 3.5.0
+ 5.3.0
4.0.0
jar
@@ -42,6 +42,11 @@
org.springframework.boot
spring-boot-starter-aop
+
+ cn.hutool
+ hutool-all
+
+
org.springframework
spring-web
@@ -57,5 +62,15 @@
spring-boot-starter-jdbc
true
+
+ org.apache.dubbo
+ dubbo
+ true
+
+
+ io.github.openfeign
+ feign-core
+ true
+
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/config/LogAutoConfigure.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/LogAutoConfigure.java
similarity index 88%
rename from zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/config/LogAutoConfigure.java
rename to zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/LogAutoConfigure.java
index 6559c6f4..92ae7a80 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/config/LogAutoConfigure.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/LogAutoConfigure.java
@@ -1,4 +1,4 @@
-package com.central.log.config;
+package com.central.log;
import com.central.log.properties.AuditLogProperties;
import com.central.log.properties.LogDbProperties;
@@ -6,6 +6,7 @@
import com.zaxxer.hikari.HikariConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
@@ -14,6 +15,7 @@
* @author zlt
* @date 2019/8/13
*/
+@ComponentScan
@EnableConfigurationProperties({TraceProperties.class, AuditLogProperties.class})
public class LogAutoConfigure {
/**
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/annotation/AuditLog.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/annotation/AuditLog.java
index b0681557..cde75670 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/annotation/AuditLog.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/annotation/AuditLog.java
@@ -6,7 +6,7 @@
* @author zlt
* @date 2020/2/3
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Target({ElementType.METHOD, ElementType.TYPE})
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/aspect/AuditLogAspect.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/aspect/AuditLogAspect.java
index a4cd4686..a94fd8a6 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/aspect/AuditLogAspect.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/aspect/AuditLogAspect.java
@@ -16,6 +16,7 @@
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@@ -28,11 +29,12 @@
* @author zlt
* @date 2020/2/3
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
@Aspect
+@Component
@ConditionalOnClass({HttpServletRequest.class, RequestContextHolder.class})
public class AuditLogAspect {
@Value("${spring.application.name}")
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/model/Audit.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/model/Audit.java
index 622cc55a..6cdc07ee 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/model/Audit.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/model/Audit.java
@@ -11,7 +11,7 @@
* @author zlt
* @date 2020/2/3
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Setter
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/monitor/PointUtil.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/monitor/PointUtil.java
index 804a10c1..d7a38fa6 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/monitor/PointUtil.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/monitor/PointUtil.java
@@ -1,18 +1,41 @@
package com.central.log.monitor;
+import cn.hutool.core.util.ReflectUtil;
+import lombok.Getter;
+import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.ObjectUtils;
+
+import java.lang.reflect.Field;
+import java.util.Iterator;
+import java.util.Map;
/**
* 日志埋点工具类
*
* @author zlt
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
@Slf4j
public class PointUtil {
private static final String MSG_PATTERN = "{}|{}|{}";
+ private static final String PROPERTIES_SPLIT = "&";
+ private static final String PROPERTIES_VALUE_SPLIT = "=";
+
+ private final PointEntry pointEntry;
private PointUtil() {
- throw new IllegalStateException("Utility class");
+ pointEntry = new PointEntry();
+ }
+
+ @Setter
+ @Getter
+ private class PointEntry {
+ String id;
+ String type;
+ Object properties;
}
/**
@@ -31,4 +54,66 @@ public static void info(String id, String type, String message) {
public static void debug(String id, String type, String message) {
log.debug(MSG_PATTERN, id, type, message);
}
+
+ public static PointUtil builder() {
+ return new PointUtil();
+ }
+
+ /**
+ * @param businessId 业务id/对象id
+ */
+ public PointUtil id(Object businessId) {
+ this.pointEntry.setId(String.valueOf(businessId));
+ return this;
+ }
+
+ /**
+ * @param type 类型
+ */
+ public PointUtil type(String type) {
+ this.pointEntry.setType(type);
+ return this;
+ }
+
+ /**
+ * @param properties 对象属性
+ */
+ public PointUtil properties(Object properties) {
+ this.pointEntry.setProperties(properties);
+ return this;
+ }
+
+ private String getPropertiesStr() {
+ Object properties = this.pointEntry.getProperties();
+ StringBuilder result = new StringBuilder();
+ if (!ObjectUtils.isEmpty(properties)) {
+ //解析map
+ if (properties instanceof Map) {
+ Map proMap = (Map)properties;
+ Iterator ite = proMap.entrySet().iterator();
+ while (ite.hasNext()) {
+ Map.Entry entry = ite.next();
+ if (result.length() > 0) {
+ result.append(PROPERTIES_SPLIT);
+ }
+ result.append(entry.getKey()).append(PROPERTIES_VALUE_SPLIT).append(entry.getValue());
+ }
+ } else {//解析对象
+ Field[] allFields = ReflectUtil.getFields(properties.getClass());
+ for (Field field : allFields) {
+ String fieldName = field.getName();
+ Object fieldValue = ReflectUtil.getFieldValue(properties, field);
+ if (result.length() > 0) {
+ result.append(PROPERTIES_SPLIT);
+ }
+ result.append(fieldName).append(PROPERTIES_VALUE_SPLIT).append(fieldValue);
+ }
+ }
+ }
+ return result.toString();
+ }
+
+ public void build() {
+ PointUtil.debug(this.pointEntry.getId(), this.pointEntry.getType(), this.getPropertiesStr());
+ }
}
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/properties/AuditLogProperties.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/properties/AuditLogProperties.java
index af73dd17..3f6713a8 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/properties/AuditLogProperties.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/properties/AuditLogProperties.java
@@ -11,7 +11,7 @@
* @author zlt
* @date 2020/2/3
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Setter
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/properties/LogDbProperties.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/properties/LogDbProperties.java
index 511dbb78..518fc72f 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/properties/LogDbProperties.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/properties/LogDbProperties.java
@@ -12,7 +12,7 @@
* @author zlt
* @date 2020/2/8
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Setter
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/IAuditService.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/IAuditService.java
index fdefd1ef..9e0c11b7 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/IAuditService.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/IAuditService.java
@@ -8,7 +8,7 @@
* @author zlt
* @date 2020/2/3
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public interface IAuditService {
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/impl/DbAuditServiceImpl.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/impl/DbAuditServiceImpl.java
index 444c02d3..1cae063c 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/impl/DbAuditServiceImpl.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/impl/DbAuditServiceImpl.java
@@ -12,6 +12,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
@@ -22,10 +23,11 @@
* @author zlt
* @date 2020/2/8
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
+@Service
@ConditionalOnProperty(name = "zlt.audit-log.log-type", havingValue = "db")
@ConditionalOnClass(JdbcTemplate.class)
public class DbAuditServiceImpl implements IAuditService {
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/impl/LoggerAuditServiceImpl.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/impl/LoggerAuditServiceImpl.java
index 5feb5d59..facfd34e 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/impl/LoggerAuditServiceImpl.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/service/impl/LoggerAuditServiceImpl.java
@@ -4,6 +4,7 @@
import com.central.log.service.IAuditService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
import java.time.format.DateTimeFormatter;
@@ -13,10 +14,11 @@
* @author zlt
* @date 2020/2/3
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
+@Service
@ConditionalOnProperty(name = "zlt.audit-log.log-type", havingValue = "logger", matchIfMissing = true)
public class LoggerAuditServiceImpl implements IAuditService {
private static final String MSG_PATTERN = "{}|{}|{}|{}|{}|{}|{}|{}";
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/DubboTraceFilter.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/DubboTraceFilter.java
new file mode 100644
index 00000000..1cd42cdf
--- /dev/null
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/DubboTraceFilter.java
@@ -0,0 +1,49 @@
+package com.central.log.trace;
+
+import cn.hutool.core.util.StrUtil;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.rpc.*;
+
+/**
+ * dubbo过滤器,传递traceId
+ *
+ * @author zlt
+ * @date 2021/1/30
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}, order = MDCTraceUtils.FILTER_ORDER)
+public class DubboTraceFilter implements Filter {
+ /**
+ * 服务消费者:传递traceId给下游服务
+ * 服务提供者:获取traceId并赋值给MDC
+ */
+ @Override
+ public Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {
+ boolean isProviderSide = RpcContext.getContext().isProviderSide();
+ if (isProviderSide) { //服务提供者逻辑
+ String traceId = invocation.getAttachment(MDCTraceUtils.KEY_TRACE_ID);
+ String spanId = invocation.getAttachment(MDCTraceUtils.KEY_SPAN_ID);
+ if (StrUtil.isEmpty(traceId)) {
+ MDCTraceUtils.addTrace();
+ } else {
+ MDCTraceUtils.putTrace(traceId, spanId);
+ }
+ } else { //服务消费者逻辑
+ String traceId = MDCTraceUtils.getTraceId();
+ if (StrUtil.isNotEmpty(traceId)) {
+ invocation.setAttachment(MDCTraceUtils.KEY_TRACE_ID, traceId);
+ invocation.setAttachment(MDCTraceUtils.KEY_SPAN_ID, MDCTraceUtils.getNextSpanId());
+ }
+ }
+ try {
+ return invoker.invoke(invocation);
+ } finally {
+ if (isProviderSide) {
+ MDCTraceUtils.removeTrace();
+ }
+ }
+ }
+}
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/FeignTraceConfig.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/FeignTraceConfig.java
new file mode 100644
index 00000000..d5a0d1e4
--- /dev/null
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/FeignTraceConfig.java
@@ -0,0 +1,40 @@
+package com.central.log.trace;
+
+import cn.hutool.core.util.StrUtil;
+import com.central.log.properties.TraceProperties;
+import feign.RequestInterceptor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.Resource;
+
+/**
+ * feign拦截器,传递traceId
+ *
+ * @author zlt
+ * @date 2021/1/28
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Configuration
+@ConditionalOnClass(value = {RequestInterceptor.class})
+public class FeignTraceConfig {
+ @Resource
+ private TraceProperties traceProperties;
+
+ @Bean
+ public RequestInterceptor feignTraceInterceptor() {
+ return template -> {
+ if (traceProperties.getEnable()) {
+ //传递日志traceId
+ String traceId = MDCTraceUtils.getTraceId();
+ if (StrUtil.isNotEmpty(traceId)) {
+ template.header(MDCTraceUtils.TRACE_ID_HEADER, traceId);
+ template.header(MDCTraceUtils.SPAN_ID_HEADER, MDCTraceUtils.getNextSpanId());
+ }
+ }
+ };
+ }
+}
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/MDCTraceUtils.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/MDCTraceUtils.java
new file mode 100644
index 00000000..d9bf610f
--- /dev/null
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/MDCTraceUtils.java
@@ -0,0 +1,100 @@
+package com.central.log.trace;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.ttl.TransmittableThreadLocal;
+import org.slf4j.MDC;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 日志追踪工具类
+ *
+ * @author zlt
+ * @date 2020/10/14
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+public class MDCTraceUtils {
+ /**
+ * 追踪id的名称
+ */
+ public static final String KEY_TRACE_ID = "traceId";
+ /**
+ * 块id的名称
+ */
+ public static final String KEY_SPAN_ID = "spanId";
+
+ /**
+ * 日志链路追踪id信息头
+ */
+ public static final String TRACE_ID_HEADER = "x-traceId-header";
+ /**
+ * 日志链路块id信息头
+ */
+ public static final String SPAN_ID_HEADER = "x-spanId-header";
+
+ /**
+ * filter的优先级,值越低越优先
+ */
+ public static final int FILTER_ORDER = -1;
+
+ private static final TransmittableThreadLocal spanNumber = new TransmittableThreadLocal<>();
+
+ /**
+ * 创建traceId并赋值MDC
+ */
+ public static void addTrace() {
+ String traceId = createTraceId();
+ MDC.put(KEY_TRACE_ID, traceId);
+ MDC.put(KEY_SPAN_ID, "0");
+ initSpanNumber();
+ }
+
+ /**
+ * 赋值MDC
+ */
+ public static void putTrace(String traceId, String spanId) {
+ MDC.put(KEY_TRACE_ID, traceId);
+ MDC.put(KEY_SPAN_ID, spanId);
+ initSpanNumber();
+ }
+
+ /**
+ * 获取MDC中的traceId值
+ */
+ public static String getTraceId() {
+ return MDC.get(KEY_TRACE_ID);
+ }
+ /**
+ * 获取MDC中的spanId值
+ */
+ public static String getSpanId() {
+ return MDC.get(KEY_SPAN_ID);
+ }
+
+ /**
+ * 清除MDC的值
+ */
+ public static void removeTrace() {
+ MDC.remove(KEY_TRACE_ID);
+ MDC.remove(KEY_SPAN_ID);
+ spanNumber.remove();
+ }
+
+ /**
+ * 创建traceId
+ */
+ public static String createTraceId() {
+ return IdUtil.getSnowflake().nextIdStr();
+ }
+
+ public static String getNextSpanId() {
+ return StrUtil.format("{}.{}", getSpanId(), spanNumber.get().incrementAndGet());
+ }
+
+ private static void initSpanNumber() {
+ spanNumber.set(new AtomicInteger(0));
+ }
+}
diff --git a/zlt-commons/zlt-common-spring-boot-starter/src/main/java/com/central/common/filter/TraceFilter.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/WebTraceFilter.java
similarity index 54%
rename from zlt-commons/zlt-common-spring-boot-starter/src/main/java/com/central/common/filter/TraceFilter.java
rename to zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/WebTraceFilter.java
index d07fe343..c7415f3e 100644
--- a/zlt-commons/zlt-common-spring-boot-starter/src/main/java/com/central/common/filter/TraceFilter.java
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/WebTraceFilter.java
@@ -1,14 +1,13 @@
-package com.central.common.filter;
+package com.central.log.trace;
import cn.hutool.core.util.StrUtil;
-import com.central.common.constant.CommonConstant;
import com.central.log.properties.TraceProperties;
-import org.slf4j.MDC;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
-import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -16,13 +15,18 @@
import java.io.IOException;
/**
- * 日志链路追踪过滤器
+ * web过滤器,生成日志链路追踪id,并赋值MDC
*
* @author zlt
- * @date 2019/9/15
+ * @date 2020/10/14
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
-@ConditionalOnClass(Filter.class)
-public class TraceFilter extends OncePerRequestFilter {
+@Component
+@ConditionalOnClass(value = {HttpServletRequest.class, OncePerRequestFilter.class})
+@Order(value = MDCTraceUtils.FILTER_ORDER)
+public class WebTraceFilter extends OncePerRequestFilter {
@Resource
private TraceProperties traceProperties;
@@ -35,14 +39,16 @@ protected boolean shouldNotFilter(HttpServletRequest request) {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
try {
- String traceId = request.getHeader(CommonConstant.TRACE_ID_HEADER);
- if (StrUtil.isNotEmpty(traceId)) {
- MDC.put(CommonConstant.LOG_TRACE_ID, traceId);
+ String traceId = request.getHeader(MDCTraceUtils.TRACE_ID_HEADER);
+ String spanId = request.getHeader(MDCTraceUtils.SPAN_ID_HEADER);
+ if (StrUtil.isEmpty(traceId)) {
+ MDCTraceUtils.addTrace();
+ } else {
+ MDCTraceUtils.putTrace(traceId, spanId);
}
-
filterChain.doFilter(request, response);
} finally {
- MDC.clear();
+ MDCTraceUtils.removeTrace();
}
}
}
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter b/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter
new file mode 100644
index 00000000..4414eb1b
--- /dev/null
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter
@@ -0,0 +1 @@
+logTrace=com.central.log.trace.DubboTraceFilter
\ No newline at end of file
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/META-INF/spring.factories b/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/META-INF/spring.factories
index 9fbeb78f..afcf8d5a 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/META-INF/spring.factories
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -2,7 +2,4 @@ org.springframework.context.ApplicationContextInitializer=\
com.central.log.config.TtlMDCAdapterInitializer
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-com.central.log.config.LogAutoConfigure,\
-com.central.log.service.impl.LoggerAuditServiceImpl,\
-com.central.log.service.impl.DbAuditServiceImpl,\
-com.central.log.aspect.AuditLogAspect
+com.central.log.LogAutoConfigure
\ No newline at end of file
diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/logback-spring.xml b/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/logback-spring.xml
index d4eec0b6..3fe98f07 100644
--- a/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/logback-spring.xml
+++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/resources/logback-spring.xml
@@ -18,8 +18,8 @@
-
+ value="[${APP_NAME}:${ServerIP}:${ServerPort}] %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}){magenta} %clr([%X{traceId}-%X{spanId}]){yellow} %clr([%thread]){orange} %clr(%-40.40logger{39}){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
+
diff --git a/zlt-commons/zlt-oss-spring-boot-starter/pom.xml b/zlt-commons/zlt-oss-spring-boot-starter/pom.xml
new file mode 100644
index 00000000..207c7709
--- /dev/null
+++ b/zlt-commons/zlt-oss-spring-boot-starter/pom.xml
@@ -0,0 +1,38 @@
+
+
+
+ com.zlt
+ zlt-commons
+ 5.3.0
+
+ 4.0.0
+ jar
+ zlt-oss-spring-boot-starter
+ 对象存储通用组件
+
+
+
+ com.github.tobato
+ fastdfs-client
+ true
+
+
+
+ com.amazonaws
+ aws-java-sdk-s3
+ true
+
+
+ org.springframework
+ spring-web
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
diff --git a/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/config/OssAutoConfigure.java b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/config/OssAutoConfigure.java
new file mode 100644
index 00000000..725bc196
--- /dev/null
+++ b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/config/OssAutoConfigure.java
@@ -0,0 +1,20 @@
+package com.central.oss.config;
+
+import com.central.oss.properties.FileServerProperties;
+import com.central.oss.template.FdfsTemplate;
+import com.central.oss.template.S3Template;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Import;
+
+/**
+ * @author zlt
+ * @date 2021/2/13
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@EnableConfigurationProperties(FileServerProperties.class)
+@Import({FdfsTemplate.class, S3Template.class})
+public class OssAutoConfigure {
+
+}
diff --git a/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/model/ObjectInfo.java b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/model/ObjectInfo.java
new file mode 100644
index 00000000..15883a23
--- /dev/null
+++ b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/model/ObjectInfo.java
@@ -0,0 +1,24 @@
+package com.central.oss.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author zlt
+ * @date 2021/2/11
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Setter
+@Getter
+public class ObjectInfo {
+ /**
+ * 对象查看路径
+ */
+ private String objectUrl;
+ /**
+ * 对象保存路径
+ */
+ private String objectPath;
+}
diff --git a/zlt-business/file-center/src/main/java/com/central/file/properties/FdfsProperties.java b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/properties/FdfsProperties.java
similarity index 55%
rename from zlt-business/file-center/src/main/java/com/central/file/properties/FdfsProperties.java
rename to zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/properties/FdfsProperties.java
index f2a3c172..94a27ce1 100644
--- a/zlt-business/file-center/src/main/java/com/central/file/properties/FdfsProperties.java
+++ b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/properties/FdfsProperties.java
@@ -1,10 +1,16 @@
-package com.central.file.properties;
+package com.central.oss.properties;
import lombok.Getter;
import lombok.Setter;
/**
+ * fastdfs配置
+ *
* @author zlt
+ * @date 2021/2/11
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
@Setter
@Getter
diff --git a/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/properties/FileServerProperties.java b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/properties/FileServerProperties.java
new file mode 100644
index 00000000..ac5a786d
--- /dev/null
+++ b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/properties/FileServerProperties.java
@@ -0,0 +1,38 @@
+package com.central.oss.properties;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * @author zlt
+ * @date 2021/2/11
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Setter
+@Getter
+@ConfigurationProperties(prefix = FileServerProperties.PREFIX)
+public class FileServerProperties {
+ public static final String PREFIX = "zlt.file-server";
+ public static final String TYPE_FDFS = "fastdfs";
+ public static final String TYPE_S3 = "s3";
+
+ /**
+ * 为以下2个值,指定不同的自动化配置
+ * s3:aws s3协议的存储(七牛oss、阿里云oss、minio等)
+ * fastdfs:本地部署的fastDFS
+ */
+ private String type;
+
+ /**
+ * aws s3配置
+ */
+ S3Properties s3 = new S3Properties();
+
+ /**
+ * fastDFS配置
+ */
+ FdfsProperties fdfs = new FdfsProperties();
+}
diff --git a/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/properties/S3Properties.java b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/properties/S3Properties.java
new file mode 100644
index 00000000..6cf0f25d
--- /dev/null
+++ b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/properties/S3Properties.java
@@ -0,0 +1,42 @@
+package com.central.oss.properties;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * aws s3协议配置
+ *
+ * @author zlt
+ * @date 2021/2/11
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Setter
+@Getter
+public class S3Properties {
+ /**
+ * 用户名
+ */
+ private String accessKey;
+ /**
+ * 密码
+ */
+ private String accessKeySecret;
+ /**
+ * 访问端点
+ */
+ private String endpoint;
+ /**
+ * bucket名称
+ */
+ private String bucketName;
+ /**
+ * 区域
+ */
+ private String region;
+ /**
+ * path-style
+ */
+ private Boolean pathStyleAccessEnabled = true;
+}
diff --git a/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/service/IOssService.java b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/service/IOssService.java
new file mode 100644
index 00000000..c4fe6a58
--- /dev/null
+++ b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/service/IOssService.java
@@ -0,0 +1,42 @@
+package com.central.oss.service;
+
+import com.central.oss.model.ObjectInfo;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @author zlt
+ * @date 2021/2/9
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+public interface IOssService {
+ /**
+ * 上传对象
+ * @param objectName 对象名
+ * @param is 对象流
+ */
+ ObjectInfo upload(String objectName, InputStream is);
+
+ /**
+ * 上传对象
+ * @param file 对象
+ */
+ ObjectInfo upload(MultipartFile file);
+
+ /**
+ * 删除对象
+ * @param objectKey 对象标识
+ */
+ void delete(String objectKey);
+
+ /**
+ * 查看文件
+ * @param objectPath 对象路径
+ * @param os 输出流
+ */
+ void view(String objectPath, OutputStream os);
+}
diff --git a/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/template/FdfsTemplate.java b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/template/FdfsTemplate.java
new file mode 100644
index 00000000..8390a563
--- /dev/null
+++ b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/template/FdfsTemplate.java
@@ -0,0 +1,83 @@
+package com.central.oss.template;
+
+import com.central.oss.model.ObjectInfo;
+import com.central.oss.properties.FileServerProperties;
+import com.github.tobato.fastdfs.domain.fdfs.StorePath;
+import com.github.tobato.fastdfs.domain.proto.storage.DownloadCallback;
+import com.github.tobato.fastdfs.service.FastFileStorageClient;
+import lombok.SneakyThrows;
+import org.apache.commons.io.FilenameUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.util.StringUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.InputStream;
+
+/**
+ * FastDFS配置
+ *
+ * @author zlt
+ * @date 2021/2/11
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@ConditionalOnClass(FastFileStorageClient.class)
+@ConditionalOnProperty(prefix = FileServerProperties.PREFIX, name = "type", havingValue = FileServerProperties.TYPE_FDFS)
+public class FdfsTemplate {
+ @Resource
+ private FileServerProperties fileProperties;
+
+ @Resource
+ private FastFileStorageClient storageClient;
+
+ @SneakyThrows
+ public ObjectInfo upload(String objectName, InputStream is) {
+ return upload(objectName, is, is.available());
+ }
+
+ @SneakyThrows
+ public ObjectInfo upload(MultipartFile file) {
+ return upload(file.getOriginalFilename(), file.getInputStream(), file.getSize());
+ }
+
+ /**
+ * 上传对象
+ * @param objectName 对象名
+ * @param is 对象流
+ * @param size 大小
+ */
+ private ObjectInfo upload(String objectName, InputStream is, long size) {
+ StorePath storePath = storageClient.uploadFile(is, size, FilenameUtils.getExtension(objectName), null);
+ ObjectInfo obj = new ObjectInfo();
+ obj.setObjectPath(storePath.getFullPath());
+ obj.setObjectUrl("http://" + fileProperties.getFdfs().getWebUrl() + "/" + storePath.getFullPath());
+ return obj;
+ }
+
+ /**
+ * 删除对象
+ * @param objectPath 对象路径
+ */
+ public void delete(String objectPath) {
+ if (!StringUtils.isEmpty(objectPath)) {
+ StorePath storePath = StorePath.parseFromUrl(objectPath);
+ storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
+ }
+ }
+
+ /**
+ * 下载对象
+ * @param objectPath 对象路径
+ * @param callback 回调
+ */
+ public T download(String objectPath, DownloadCallback callback) {
+ if (!StringUtils.isEmpty(objectPath)) {
+ StorePath storePath = StorePath.parseFromUrl(objectPath);
+ return storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), callback);
+ }
+ return null;
+ }
+}
diff --git a/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/template/S3Template.java b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/template/S3Template.java
new file mode 100644
index 00000000..eebf5433
--- /dev/null
+++ b/zlt-commons/zlt-oss-spring-boot-starter/src/main/java/com/central/oss/template/S3Template.java
@@ -0,0 +1,147 @@
+package com.central.oss.template;
+
+import com.amazonaws.ClientConfiguration;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3Client;
+import com.amazonaws.services.s3.model.ObjectMetadata;
+import com.amazonaws.services.s3.model.PutObjectRequest;
+import com.amazonaws.services.s3.model.S3Object;
+import com.amazonaws.services.s3.model.S3ObjectInputStream;
+import com.amazonaws.util.IOUtils;
+import com.central.oss.model.ObjectInfo;
+import com.central.oss.properties.FileServerProperties;
+import lombok.SneakyThrows;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.Calendar;
+
+/**
+ * aws s3配置
+ *
+ * @author zlt
+ * @date 2021/2/11
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@ConditionalOnClass(AmazonS3.class)
+@ConditionalOnProperty(prefix = FileServerProperties.PREFIX, name = "type", havingValue = FileServerProperties.TYPE_S3)
+public class S3Template implements InitializingBean {
+ private static final String DEF_CONTEXT_TYPE = "application/octet-stream";
+ private static final String PATH_SPLIT = "/";
+
+ @Autowired
+ private FileServerProperties fileProperties;
+
+ private AmazonS3 amazonS3;
+
+ @Override
+ public void afterPropertiesSet() {
+ ClientConfiguration config = new ClientConfiguration();
+ AwsClientBuilder.EndpointConfiguration endpoint = new AwsClientBuilder.EndpointConfiguration(fileProperties.getS3().getEndpoint(), fileProperties.getS3().getRegion());
+ AWSCredentials credentials = new BasicAWSCredentials(fileProperties.getS3().getAccessKey(), fileProperties.getS3().getAccessKeySecret());
+ AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(credentials);
+ this.amazonS3 = AmazonS3Client.builder()
+ .withEndpointConfiguration(endpoint)
+ .withClientConfiguration(config)
+ .withCredentials(awsCredentialsProvider)
+ .withPathStyleAccessEnabled(fileProperties.getS3().getPathStyleAccessEnabled())
+ .disableChunkedEncoding()
+ .build();
+ }
+
+ @SneakyThrows
+ public ObjectInfo upload(String fileName, InputStream is) {
+ return upload(fileProperties.getS3().getBucketName(), fileName, is, is.available(), DEF_CONTEXT_TYPE);
+ }
+
+ @SneakyThrows
+ public ObjectInfo upload(MultipartFile file) {
+ return upload(fileProperties.getS3().getBucketName(), file.getOriginalFilename(), file.getInputStream()
+ , ((Long)file.getSize()).intValue(), file.getContentType());
+ }
+
+ @SneakyThrows
+ public ObjectInfo upload(String bucketName, String fileName, InputStream is) {
+ return upload(bucketName, fileName, is, is.available(), DEF_CONTEXT_TYPE);
+ }
+
+ /**
+ * 上传对象
+ * @param bucketName bucket名称
+ * @param objectName 对象名
+ * @param is 对象流
+ * @param size 大小
+ * @param contentType 类型
+ */
+ private ObjectInfo upload(String bucketName, String objectName, InputStream is, int size, String contentType) {
+ ObjectMetadata objectMetadata = new ObjectMetadata();
+ objectMetadata.setContentLength(size);
+ objectMetadata.setContentType(contentType);
+ PutObjectRequest putObjectRequest = new PutObjectRequest(
+ bucketName, objectName, is, objectMetadata);
+ putObjectRequest.getRequestClientOptions().setReadLimit(size + 1);
+ amazonS3.putObject(putObjectRequest);
+
+ ObjectInfo obj = new ObjectInfo();
+ obj.setObjectPath(bucketName + PATH_SPLIT + objectName);
+ obj.setObjectUrl(fileProperties.getS3().getEndpoint() + PATH_SPLIT + obj.getObjectPath());
+ return obj;
+ }
+
+ public void delete(String objectName) {
+ delete(fileProperties.getS3().getBucketName(), objectName);
+ }
+
+ public void delete(String bucketName, String objectName) {
+ amazonS3.deleteObject(bucketName, objectName);
+ }
+
+ /**
+ * 获取预览地址
+ * @param bucketName bucket名称
+ * @param objectName 对象名
+ * @param expires 有效时间(分钟),最大7天有效
+ * @return
+ */
+ public String getViewUrl(String bucketName, String objectName, int expires) {
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.MINUTE, expires);
+ URL url = amazonS3.generatePresignedUrl(bucketName, objectName, cal.getTime());
+ return url.toString();
+ }
+
+ public void out(String objectName, OutputStream os) {
+ out(fileProperties.getS3().getBucketName(), objectName, os);
+ }
+
+ /**
+ * 输出对象
+ * @param bucketName bucket名称
+ * @param objectName 对象名
+ * @param os 输出流
+ */
+ @SneakyThrows
+ public void out(String bucketName, String objectName, OutputStream os) {
+ S3Object s3Object = amazonS3.getObject(bucketName, objectName);
+ try (
+ S3ObjectInputStream s3is = s3Object.getObjectContent();
+ ) {
+ IOUtils.copy(s3is, os);
+ }
+ }
+}
diff --git a/zlt-commons/zlt-oss-spring-boot-starter/src/main/resources/META-INF/spring.factories b/zlt-commons/zlt-oss-spring-boot-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 00000000..43d799a7
--- /dev/null
+++ b/zlt-commons/zlt-oss-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+com.central.oss.config.OssAutoConfigure
\ No newline at end of file
diff --git a/zlt-commons/zlt-redis-spring-boot-starter/pom.xml b/zlt-commons/zlt-redis-spring-boot-starter/pom.xml
index fd525214..29fa499f 100644
--- a/zlt-commons/zlt-redis-spring-boot-starter/pom.xml
+++ b/zlt-commons/zlt-redis-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
com.zlt
zlt-commons
- 3.5.0
+ 5.3.0
4.0.0
jar
@@ -16,19 +16,10 @@
com.zlt
zlt-common-core
+
- org.springframework.boot
- spring-boot-starter-data-redis
-
-
- io.lettuce
- lettuce-core
-
-
-
-
- io.lettuce
- lettuce-core
+ org.redisson
+ redisson-spring-boot-starter
diff --git a/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/RedisAutoConfigure.java b/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/RedisAutoConfigure.java
index 3bc5e5b8..6f25cec7 100644
--- a/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/RedisAutoConfigure.java
+++ b/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/RedisAutoConfigure.java
@@ -1,11 +1,8 @@
package com.central.common.redis;
import com.central.common.redis.properties.CacheManagerProperties;
-import com.central.common.redis.template.RedisRepository;
-import com.central.common.redis.util.RedisObjectSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.interceptor.KeyGenerator;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
@@ -27,6 +24,9 @@
*
* @author zlt
* @date 2018/11/6 11:02
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
@EnableConfigurationProperties({RedisProperties.class, CacheManagerProperties.class})
@EnableCaching
@@ -34,35 +34,45 @@ public class RedisAutoConfigure {
@Autowired
private CacheManagerProperties cacheManagerProperties;
+ @Bean
+ public RedisSerializer redisKeySerializer() {
+ return RedisSerializer.string();
+ }
+
+ @Bean
+ public RedisSerializer redisValueSerializer() {
+ return RedisSerializer.json();
+ }
+
/**
* RedisTemplate配置
* @param factory
*/
@Bean
- public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
+ public RedisTemplate redisTemplate(RedisConnectionFactory factory
+ , RedisSerializer redisKeySerializer, RedisSerializer redisValueSerializer) {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
- RedisSerializer stringSerializer = new StringRedisSerializer();
- RedisSerializer redisObjectSerializer = new RedisObjectSerializer();
- redisTemplate.setKeySerializer(stringSerializer);
- redisTemplate.setHashKeySerializer(stringSerializer);
- redisTemplate.setValueSerializer(redisObjectSerializer);
+ redisTemplate.setDefaultSerializer(redisValueSerializer);
+ redisTemplate.setKeySerializer(redisKeySerializer);
+ redisTemplate.setHashKeySerializer(redisKeySerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean(name = "cacheManager")
@Primary
- public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
- RedisCacheConfiguration difConf = getDefConf().entryTtl(Duration.ofHours(1));
+ public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory
+ , RedisSerializer redisKeySerializer, RedisSerializer redisValueSerializer) {
+ RedisCacheConfiguration difConf = getDefConf(redisKeySerializer, redisValueSerializer).entryTtl(Duration.ofHours(1));
//自定义的缓存过期时间配置
int configSize = cacheManagerProperties.getConfigs() == null ? 0 : cacheManagerProperties.getConfigs().size();
Map redisCacheConfigurationMap = new HashMap<>(configSize);
if (configSize > 0) {
cacheManagerProperties.getConfigs().forEach(e -> {
- RedisCacheConfiguration conf = getDefConf().entryTtl(Duration.ofSeconds(e.getSecond()));
+ RedisCacheConfiguration conf = getDefConf(redisKeySerializer, redisValueSerializer).entryTtl(Duration.ofSeconds(e.getSecond()));
redisCacheConfigurationMap.put(e.getKey(), conf);
});
}
@@ -86,11 +96,11 @@ public KeyGenerator keyGenerator() {
};
}
- private RedisCacheConfiguration getDefConf() {
+ private RedisCacheConfiguration getDefConf(RedisSerializer redisKeySerializer, RedisSerializer redisValueSerializer) {
return RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues()
.computePrefixWith(cacheName -> "cache".concat(":").concat(cacheName).concat(":"))
- .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
- .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new RedisObjectSerializer()));
+ .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisKeySerializer))
+ .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisValueSerializer));
}
}
diff --git a/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/lock/RedisDistributedLock.java b/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/lock/RedisDistributedLock.java
index a4abd189..9b305e4c 100644
--- a/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/lock/RedisDistributedLock.java
+++ b/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/lock/RedisDistributedLock.java
@@ -1,14 +1,13 @@
package com.central.common.redis.lock;
-import com.central.common.lock.AbstractDistributedLock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
-import org.springframework.stereotype.Component;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@@ -18,9 +17,16 @@
*
* @author zlt
* @date 2018/5/29 14:16
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ *
+ * @deprecated 建议使用Redisson的实现方式 {@link RedissonDistributedLock}
*/
@Slf4j
-public class RedisDistributedLock extends AbstractDistributedLock {
+@ConditionalOnClass(RedisTemplate.class)
+@Deprecated
+public class RedisDistributedLock {
@Autowired
private RedisTemplate redisTemplate;
@@ -45,7 +51,15 @@ public RedisDistributedLock(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
- @Override
+ /**
+ * 获取锁
+ *
+ * @param key 锁的key
+ * @param expire 获取锁超时时间
+ * @param retryTimes 重试次数
+ * @param sleepMillis 获取锁失败的重试间隔
+ * @return 成功/失败
+ */
public boolean lock(String key, long expire, int retryTimes, long sleepMillis) {
boolean result = setRedis(key, expire);
// 如果获取锁失败,按照传入的重试次数进行重试
@@ -79,7 +93,11 @@ private boolean setRedis(final String key, final long expire) {
return false;
}
- @Override
+ /**
+ * 释放锁
+ * @param key 锁的key
+ * @return 成功/失败
+ */
public boolean releaseLock(String key) {
// 释放锁的时候,有可能因为持锁之后方法执行时间大于锁的有效期,此时有可能已经被另外一个线程持有锁,所以不能直接删除
try {
diff --git a/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/lock/RedissonDistributedLock.java b/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/lock/RedissonDistributedLock.java
new file mode 100644
index 00000000..fef19243
--- /dev/null
+++ b/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/lock/RedissonDistributedLock.java
@@ -0,0 +1,73 @@
+package com.central.common.redis.lock;
+
+import com.central.common.constant.CommonConstant;
+import com.central.common.exception.LockException;
+import com.central.common.lock.DistributedLock;
+import com.central.common.lock.ZLock;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * redisson分布式锁实现,基本锁功能的抽象实现
+ * 本接口能满足绝大部分的需求,高级的锁功能,请自行扩展或直接使用原生api
+ * https://gitbook.cn/gitchat/activity/5f02746f34b17609e14c7d5a
+ *
+ * @author zlt
+ * @date 2020/5/5
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@ConditionalOnClass(RedissonClient.class)
+@ConditionalOnProperty(prefix = "zlt.lock", name = "lockerType", havingValue = "REDIS", matchIfMissing = true)
+public class RedissonDistributedLock implements DistributedLock {
+ @Autowired
+ private RedissonClient redisson;
+
+ private ZLock getLock(String key, boolean isFair) {
+ RLock lock;
+ if (isFair) {
+ lock = redisson.getFairLock(CommonConstant.LOCK_KEY_PREFIX + ":" + key);
+ } else {
+ lock = redisson.getLock(CommonConstant.LOCK_KEY_PREFIX + ":" + key);
+ }
+ return new ZLock(lock, this);
+ }
+
+ @Override
+ public ZLock lock(String key, long leaseTime, TimeUnit unit, boolean isFair) {
+ ZLock zLock = getLock(key, isFair);
+ RLock lock = (RLock)zLock.getLock();
+ lock.lock(leaseTime, unit);
+ return zLock;
+ }
+
+ @Override
+ public ZLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws InterruptedException {
+ ZLock zLock = getLock(key, isFair);
+ RLock lock = (RLock)zLock.getLock();
+ if (lock.tryLock(waitTime, leaseTime, unit)) {
+ return zLock;
+ }
+ return null;
+ }
+
+ @Override
+ public void unlock(Object lock) {
+ if (lock != null) {
+ if (lock instanceof RLock) {
+ RLock rLock = (RLock)lock;
+ if (rLock.isLocked()) {
+ rLock.unlock();
+ }
+ } else {
+ throw new LockException("requires RLock type");
+ }
+ }
+ }
+}
diff --git a/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/template/RedisRepository.java b/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/template/RedisRepository.java
index abdcf2e9..7c80302f 100644
--- a/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/template/RedisRepository.java
+++ b/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/template/RedisRepository.java
@@ -1,505 +1,498 @@
-package com.central.common.redis.template;
-
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.springframework.data.redis.connection.RedisClusterNode;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.connection.RedisServerCommands;
-import org.springframework.data.redis.core.HashOperations;
-import org.springframework.data.redis.core.ListOperations;
-import org.springframework.data.redis.core.RedisCallback;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
-import org.springframework.data.redis.serializer.RedisSerializer;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-
-/**
- * Redis Repository
- * redis 基本操作 可扩展,基本够用了
- *
- * @author zlt
- */
-@Slf4j
-public class RedisRepository {
- /**
- * 默认编码
- */
- private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
-
- /**
- * key序列化
- */
- private static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer();
-
- /**
- * value 序列化
- */
- private static final JdkSerializationRedisSerializer OBJECT_SERIALIZER = new JdkSerializationRedisSerializer();
-
- /**
- * Spring Redis Template
- */
- private RedisTemplate redisTemplate;
-
- public RedisRepository(RedisTemplate redisTemplate) {
- this.redisTemplate = redisTemplate;
- this.redisTemplate.setKeySerializer(STRING_SERIALIZER);
- this.redisTemplate.setValueSerializer(OBJECT_SERIALIZER);
- }
-
- /**
- * 获取链接工厂
- */
- public RedisConnectionFactory getConnectionFactory() {
- return this.redisTemplate.getConnectionFactory();
- }
-
- /**
- * 获取 RedisTemplate对象
- */
- public RedisTemplate getRedisTemplate() {
- return redisTemplate;
- }
-
- /**
- * 清空DB
- *
- * @param node redis 节点
- */
- public void flushDB(RedisClusterNode node) {
- this.redisTemplate.opsForCluster().flushDb(node);
- }
-
- /**
- * 添加到带有 过期时间的 缓存
- *
- * @param key redis主键
- * @param value 值
- * @param time 过期时间(单位秒)
- */
- public void setExpire(final byte[] key, final byte[] value, final long time) {
- redisTemplate.execute((RedisCallback) connection -> {
- connection.setEx(key, time, value);
- log.debug("[redisTemplate redis]放入 缓存 url:{} ========缓存时间为{}秒", key, time);
- return 1L;
- });
- }
-
- /**
- * 添加到带有 过期时间的 缓存
- *
- * @param key redis主键
- * @param value 值
- * @param time 过期时间(单位秒)
- */
- public void setExpire(final String key, final Object value, final long time) {
- redisTemplate.execute((RedisCallback) connection -> {
- RedisSerializer serializer = getRedisSerializer();
- byte[] keys = serializer.serialize(key);
- byte[] values = OBJECT_SERIALIZER.serialize(value);
- connection.setEx(keys, time, values);
- return 1L;
- });
- }
-
- /**
- * 一次性添加数组到 过期时间的 缓存,不用多次连接,节省开销
- *
- * @param keys redis主键数组
- * @param values 值数组
- * @param time 过期时间(单位秒)
- */
- public void setExpire(final String[] keys, final Object[] values, final long time) {
- redisTemplate.execute((RedisCallback) connection -> {
- RedisSerializer serializer = getRedisSerializer();
- for (int i = 0; i < keys.length; i++) {
- byte[] bKeys = serializer.serialize(keys[i]);
- byte[] bValues = OBJECT_SERIALIZER.serialize(values[i]);
- connection.setEx(bKeys, time, bValues);
- }
- return 1L;
- });
- }
-
-
- /**
- * 一次性添加数组到 过期时间的 缓存,不用多次连接,节省开销
- *
- * @param keys the keys
- * @param values the values
- */
- public void set(final String[] keys, final Object[] values) {
- redisTemplate.execute((RedisCallback) connection -> {
- RedisSerializer serializer = getRedisSerializer();
- for (int i = 0; i < keys.length; i++) {
- byte[] bKeys = serializer.serialize(keys[i]);
- byte[] bValues = OBJECT_SERIALIZER.serialize(values[i]);
- connection.set(bKeys, bValues);
- }
- return 1L;
- });
- }
-
-
- /**
- * 添加到缓存
- *
- * @param key the key
- * @param value the value
- */
- public void set(final String key, final Object value) {
- redisTemplate.execute((RedisCallback) connection -> {
- RedisSerializer serializer = getRedisSerializer();
- byte[] keys = serializer.serialize(key);
- byte[] values = OBJECT_SERIALIZER.serialize(value);
- connection.set(keys, values);
- log.debug("[redisTemplate redis]放入 缓存 url:{}", key);
- return 1L;
- });
- }
-
- /**
- * 查询在这个时间段内即将过期的key
- *
- * @param key the key
- * @param time the time
- * @return the list
- */
- public List willExpire(final String key, final long time) {
- final List keysList = new ArrayList<>();
- redisTemplate.execute((RedisCallback>) connection -> {
- Set keys = redisTemplate.keys(key + "*");
- for (String key1 : keys) {
- Long ttl = connection.ttl(key1.getBytes(DEFAULT_CHARSET));
- if (0 <= ttl && ttl <= 2 * time) {
- keysList.add(key1);
- }
- }
- return keysList;
- });
- return keysList;
- }
-
-
- /**
- * 查询在以keyPatten的所有 key
- *
- * @param keyPatten the key patten
- * @return the set
- */
- public Set keys(final String keyPatten) {
- return redisTemplate.execute((RedisCallback>) connection -> redisTemplate.keys(keyPatten + "*"));
- }
-
- /**
- * 根据key获取对象
- *
- * @param key the key
- * @return the byte [ ]
- */
- public byte[] get(final byte[] key) {
- byte[] result = redisTemplate.execute((RedisCallback) connection -> connection.get(key));
- log.debug("[redisTemplate redis]取出 缓存 url:{} ", key);
- return result;
- }
-
- /**
- * 根据key获取对象
- *
- * @param key the key
- * @return the string
- */
- public Object get(final String key) {
- Object resultStr = redisTemplate.execute((RedisCallback) connection -> {
- RedisSerializer serializer = getRedisSerializer();
- byte[] keys = serializer.serialize(key);
- byte[] values = connection.get(keys);
- return OBJECT_SERIALIZER.deserialize(values);
- });
- log.debug("[redisTemplate redis]取出 缓存 url:{} ", key);
- return resultStr;
- }
-
-
- /**
- * 根据key获取对象
- *
- * @param keyPatten the key patten
- * @return the keys values
- */
- public Map getKeysValues(final String keyPatten) {
- log.debug("[redisTemplate redis] getValues() patten={} ", keyPatten);
- return redisTemplate.execute((RedisCallback>) connection -> {
- RedisSerializer serializer = getRedisSerializer();
- Map maps = new HashMap<>(16);
- Set keys = redisTemplate.keys(keyPatten + "*");
- if (CollectionUtils.isNotEmpty(keys)) {
- for (String key : keys) {
- byte[] bKeys = serializer.serialize(key);
- byte[] bValues = connection.get(bKeys);
- Object value = OBJECT_SERIALIZER.deserialize(bValues);
- maps.put(key, value);
- }
- }
- return maps;
- });
- }
-
- /**
- * Ops for hash hash operations.
- *
- * @return the hash operations
- */
- public HashOperations opsForHash() {
- return redisTemplate.opsForHash();
- }
-
- /**
- * 对HashMap操作
- *
- * @param key the key
- * @param hashKey the hash key
- * @param hashValue the hash value
- */
- public void putHashValue(String key, String hashKey, Object hashValue) {
- log.debug("[redisTemplate redis] putHashValue() key={},hashKey={},hashValue={} ", key, hashKey, hashValue);
- opsForHash().put(key, hashKey, hashValue);
- }
-
- /**
- * 获取单个field对应的值
- *
- * @param key the key
- * @param hashKey the hash key
- * @return the hash values
- */
- public Object getHashValues(String key, String hashKey) {
- log.debug("[redisTemplate redis] getHashValues() key={},hashKey={}", key, hashKey);
- return opsForHash().get(key, hashKey);
- }
-
- /**
- * 根据key值删除
- *
- * @param key the key
- * @param hashKeys the hash keys
- */
- public void delHashValues(String key, Object... hashKeys) {
- log.debug("[redisTemplate redis] delHashValues() key={}", key);
- opsForHash().delete(key, hashKeys);
- }
-
- /**
- * key只匹配map
- *
- * @param key the key
- * @return the hash value
- */
- public Map getHashValue(String key) {
- log.debug("[redisTemplate redis] getHashValue() key={}", key);
- return opsForHash().entries(key);
- }
-
- /**
- * 批量添加
- *
- * @param key the key
- * @param map the map
- */
- public void putHashValues(String key, Map map) {
- opsForHash().putAll(key, map);
- }
-
- /**
- * 集合数量
- *
- * @return the long
- */
- public long dbSize() {
- return redisTemplate.execute(RedisServerCommands::dbSize);
- }
-
- /**
- * 清空redis存储的数据
- *
- * @return the string
- */
- public String flushDB() {
- return redisTemplate.execute((RedisCallback) connection -> {
- connection.flushDb();
- return "ok";
- });
- }
-
- /**
- * 判断某个主键是否存在
- *
- * @param key the key
- * @return the boolean
- */
- public boolean exists(final String key) {
- return redisTemplate.execute((RedisCallback) connection -> connection.exists(key.getBytes(DEFAULT_CHARSET)));
- }
-
-
- /**
- * 删除key
- *
- * @param keys the keys
- * @return the long
- */
- public long del(final String... keys) {
- return redisTemplate.execute((RedisCallback) connection -> {
- long result = 0;
- for (String key : keys) {
- result = connection.del(key.getBytes(DEFAULT_CHARSET));
- }
- return result;
- });
- }
-
- /**
- * 获取 RedisSerializer
- *
- * @return the redis serializer
- */
- protected RedisSerializer getRedisSerializer() {
- return redisTemplate.getStringSerializer();
- }
-
- /**
- * 对某个主键对应的值加一,value值必须是全数字的字符串
- *
- * @param key the key
- * @return the long
- */
- public long incr(final String key) {
- return redisTemplate.execute((RedisCallback) connection -> {
- RedisSerializer redisSerializer = getRedisSerializer();
- return connection.incr(redisSerializer.serialize(key));
- });
- }
-
- /**
- * redis List 引擎
- *
- * @return the list operations
- */
- public ListOperations opsForList() {
- return redisTemplate.opsForList();
- }
-
- /**
- * redis List数据结构 : 将一个或多个值 value 插入到列表 key 的表头
- *
- * @param key the key
- * @param value the value
- * @return the long
- */
- public Long leftPush(String key, Object value) {
- return opsForList().leftPush(key, value);
- }
-
- /**
- * redis List数据结构 : 移除并返回列表 key 的头元素
- *
- * @param key the key
- * @return the string
- */
- public Object leftPop(String key) {
- return opsForList().leftPop(key);
- }
-
- /**
- * redis List数据结构 :将一个或多个值 value 插入到列表 key 的表尾(最右边)。
- *
- * @param key the key
- * @param value the value
- * @return the long
- */
- public Long in(String key, Object value) {
- return opsForList().rightPush(key, value);
- }
-
- /**
- * redis List数据结构 : 移除并返回列表 key 的末尾元素
- *
- * @param key the key
- * @return the string
- */
- public Object rightPop(String key) {
- return opsForList().rightPop(key);
- }
-
-
- /**
- * redis List数据结构 : 返回列表 key 的长度 ; 如果 key 不存在,则 key 被解释为一个空列表,返回 0 ; 如果 key 不是列表类型,返回一个错误。
- *
- * @param key the key
- * @return the long
- */
- public Long length(String key) {
- return opsForList().size(key);
- }
-
-
- /**
- * redis List数据结构 : 根据参数 i 的值,移除列表中与参数 value 相等的元素
- *
- * @param key the key
- * @param i the
- * @param value the value
- */
- public void remove(String key, long i, Object value) {
- opsForList().remove(key, i, value);
- }
-
- /**
- * redis List数据结构 : 将列表 key 下标为 index 的元素的值设置为 value
- *
- * @param key the key
- * @param index the index
- * @param value the value
- */
- public void set(String key, long index, Object value) {
- opsForList().set(key, index, value);
- }
-
- /**
- * redis List数据结构 : 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 end 指定。
- *
- * @param key the key
- * @param start the start
- * @param end the end
- * @return the list
- */
- public List getList(String key, int start, int end) {
- return opsForList().range(key, start, end);
- }
-
- /**
- * redis List数据结构 : 批量存储
- *
- * @param key the key
- * @param list the list
- * @return the long
- */
- public Long leftPushAll(String key, List list) {
- return opsForList().leftPushAll(key, list);
- }
-
- /**
- * redis List数据结构 : 将值 value 插入到列表 key 当中,位于值 index 之前或之后,默认之后。
- *
- * @param key the key
- * @param index the index
- * @param value the value
- */
- public void insert(String key, long index, Object value) {
- opsForList().set(key, index, value);
- }
-}
+package com.central.common.redis.template;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.dao.DataAccessException;
+import org.springframework.data.redis.connection.RedisClusterNode;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.RedisServerCommands;
+import org.springframework.data.redis.core.*;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.SerializationUtils;
+import org.springframework.util.Assert;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Redis Repository
+ * redis 基本操作 可扩展,基本够用了
+ *
+ * @author zlt
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Slf4j
+public class RedisRepository {
+ /**
+ * Spring Redis Template
+ */
+ private RedisTemplate redisTemplate;
+
+ public RedisRepository(RedisTemplate redisTemplate) {
+ this.redisTemplate = redisTemplate;
+ }
+
+ /**
+ * 获取链接工厂
+ */
+ public RedisConnectionFactory getConnectionFactory() {
+ return this.redisTemplate.getConnectionFactory();
+ }
+
+ /**
+ * 获取 RedisTemplate对象
+ */
+ public RedisTemplate getRedisTemplate() {
+ return redisTemplate;
+ }
+
+ /**
+ * 清空DB
+ *
+ * @param node redis 节点
+ */
+ public void flushDB(RedisClusterNode node) {
+ this.redisTemplate.opsForCluster().flushDb(node);
+ }
+
+ /**
+ * 添加到带有 过期时间的 缓存
+ *
+ * @param key redis主键
+ * @param value 值
+ * @param time 过期时间(单位秒)
+ */
+ public void setExpire(final byte[] key, final byte[] value, final long time) {
+ redisTemplate.execute((RedisCallback) connection -> {
+ connection.setEx(key, time, value);
+ return 1L;
+ });
+ }
+
+ /**
+ * 添加到带有 过期时间的 缓存
+ *
+ * @param key redis主键
+ * @param value 值
+ * @param time 过期时间
+ * @param timeUnit 过期时间单位
+ */
+ public void setExpire(final String key, final Object value, final long time, final TimeUnit timeUnit) {
+ redisTemplate.opsForValue().set(key, value, time, timeUnit);
+ }
+ public void setExpire(final String key, final Object value, final long time) {
+ this.setExpire(key, value, time, TimeUnit.SECONDS);
+ }
+ public void setExpire(final String key, final Object value, final long time, final TimeUnit timeUnit, RedisSerializer valueSerializer) {
+ byte[] rawKey = rawKey(key);
+ byte[] rawValue = rawValue(value, valueSerializer);
+
+ redisTemplate.execute(new RedisCallback() {
+ @Override
+ public Object doInRedis(RedisConnection connection) throws DataAccessException {
+ potentiallyUsePsetEx(connection);
+ return null;
+ }
+ public void potentiallyUsePsetEx(RedisConnection connection) {
+ if (!TimeUnit.MILLISECONDS.equals(timeUnit) || !failsafeInvokePsetEx(connection)) {
+ connection.setEx(rawKey, TimeoutUtils.toSeconds(time, timeUnit), rawValue);
+ }
+ }
+ private boolean failsafeInvokePsetEx(RedisConnection connection) {
+ boolean failed = false;
+ try {
+ connection.pSetEx(rawKey, time, rawValue);
+ } catch (UnsupportedOperationException e) {
+ failed = true;
+ }
+ return !failed;
+ }
+ }, true);
+ }
+
+ /**
+ * 一次性添加数组到 过期时间的 缓存,不用多次连接,节省开销
+ *
+ * @param keys redis主键数组
+ * @param values 值数组
+ * @param time 过期时间(单位秒)
+ */
+ public void setExpire(final String[] keys, final Object[] values, final long time) {
+ for (int i = 0; i < keys.length; i++) {
+ redisTemplate.opsForValue().set(keys[i], values[i], time, TimeUnit.SECONDS);
+ }
+ }
+
+
+ /**
+ * 一次性添加数组到 过期时间的 缓存,不用多次连接,节省开销
+ *
+ * @param keys the keys
+ * @param values the values
+ */
+ public void set(final String[] keys, final Object[] values) {
+ for (int i = 0; i < keys.length; i++) {
+ redisTemplate.opsForValue().set(keys[i], values[i]);
+ }
+ }
+
+
+ /**
+ * 添加到缓存
+ *
+ * @param key the key
+ * @param value the value
+ */
+ public void set(final String key, final Object value) {
+ redisTemplate.opsForValue().set(key, value);
+ }
+
+ /**
+ * 查询在以keyPatten的所有 key
+ *
+ * @param keyPatten the key patten
+ * @return the set
+ */
+ public Set keys(final String keyPatten) {
+ return redisTemplate.keys(keyPatten + "*");
+ }
+
+ /**
+ * 根据key获取对象
+ *
+ * @param key the key
+ * @return the byte [ ]
+ */
+ public byte[] get(final byte[] key) {
+ return redisTemplate.execute((RedisCallback) connection -> connection.get(key));
+ }
+
+ /**
+ * 根据key获取对象
+ *
+ * @param key the key
+ * @return the string
+ */
+ public Object get(final String key) {
+ return redisTemplate.opsForValue().get(key);
+ }
+
+ /**
+ *获取原来key键对应的值并重新赋新值。
+ * @param key
+ * @param value
+ * @return
+ */
+ public String getAndSet(final String key,String value) {
+ String result = null;
+ if (StringUtils.isEmpty(key)){
+ log.error("非法入参");
+ return null;
+ }
+ try {
+ Object object =redisTemplate.opsForValue().getAndSet(key, value);
+ if (object !=null){
+ result = object.toString();
+ }
+ }catch (Exception e){
+ log.error("redisTemplate操作异常",e);
+ }
+ return result;
+ }
+ /**
+ * 根据key获取对象
+ *
+ * @param key the key
+ * @param valueSerializer 序列化
+ * @return the string
+ */
+ public Object get(final String key, RedisSerializer valueSerializer) {
+ byte[] rawKey = rawKey(key);
+ return redisTemplate.execute(connection -> deserializeValue(connection.get(rawKey), valueSerializer), true);
+ }
+
+
+ /**
+ * Ops for hash hash operations.
+ *
+ * @return the hash operations
+ */
+ public HashOperations opsForHash() {
+ return redisTemplate.opsForHash();
+ }
+
+ /**
+ * 对HashMap操作
+ *
+ * @param key the key
+ * @param hashKey the hash key
+ * @param hashValue the hash value
+ */
+ public void putHashValue(String key, String hashKey, Object hashValue) {
+ opsForHash().put(key, hashKey, hashValue);
+ }
+
+ /**
+ * 获取单个field对应的值
+ *
+ * @param key the key
+ * @param hashKey the hash key
+ * @return the hash values
+ */
+ public Object getHashValues(String key, String hashKey) {
+ return opsForHash().get(key, hashKey);
+ }
+
+ /**
+ * 根据key值删除
+ *
+ * @param key the key
+ * @param hashKeys the hash keys
+ */
+ public void delHashValues(String key, Object... hashKeys) {
+ opsForHash().delete(key, hashKeys);
+ }
+
+ /**
+ * key只匹配map
+ *
+ * @param key the key
+ * @return the hash value
+ */
+ public Map getHashValue(String key) {
+ return opsForHash().entries(key);
+ }
+
+ /**
+ * 批量添加
+ *
+ * @param key the key
+ * @param map the map
+ */
+ public void putHashValues(String key, Map map) {
+ opsForHash().putAll(key, map);
+ }
+
+ /**
+ * 集合数量
+ *
+ * @return the long
+ */
+ public long dbSize() {
+ return redisTemplate.execute(RedisServerCommands::dbSize);
+ }
+
+ /**
+ * 清空redis存储的数据
+ *
+ * @return the string
+ */
+ public String flushDB() {
+ return redisTemplate.execute((RedisCallback) connection -> {
+ connection.flushDb();
+ return "ok";
+ });
+ }
+
+ /**
+ * 判断某个主键是否存在
+ *
+ * @param key the key
+ * @return the boolean
+ */
+ public boolean exists(final String key) {
+ return redisTemplate.hasKey(key);
+ }
+
+
+ /**
+ * 删除key
+ *
+ * @param keys the keys
+ * @return the long
+ */
+ public boolean del(final String... keys) {
+ boolean result = false;
+ for (String key : keys) {
+ result = redisTemplate.delete(key);
+ }
+ return result;
+ }
+
+ /**
+ * 对某个主键对应的值加一,value值必须是全数字的字符串
+ *
+ * @param key the key
+ * @return the long
+ */
+ public long incr(final String key) {
+ return redisTemplate.opsForValue().increment(key);
+ }
+
+ /**
+ * redis List 引擎
+ *
+ * @return the list operations
+ */
+ public ListOperations opsForList() {
+ return redisTemplate.opsForList();
+ }
+
+ /**
+ * redis List数据结构 : 将一个或多个值 value 插入到列表 key 的表头
+ *
+ * @param key the key
+ * @param value the value
+ * @return the long
+ */
+ public Long leftPush(String key, Object value) {
+ return opsForList().leftPush(key, value);
+ }
+
+ /**
+ * redis List数据结构 : 移除并返回列表 key 的头元素
+ *
+ * @param key the key
+ * @return the string
+ */
+ public Object leftPop(String key) {
+ return opsForList().leftPop(key);
+ }
+
+ /**
+ * redis List数据结构 :将一个或多个值 value 插入到列表 key 的表尾(最右边)。
+ *
+ * @param key the key
+ * @param value the value
+ * @return the long
+ */
+ public Long in(String key, Object value) {
+ return opsForList().rightPush(key, value);
+ }
+
+ /**
+ * redis List数据结构 : 移除并返回列表 key 的末尾元素
+ *
+ * @param key the key
+ * @return the string
+ */
+ public Object rightPop(String key) {
+ return opsForList().rightPop(key);
+ }
+
+
+ /**
+ * redis List数据结构 : 返回列表 key 的长度 ; 如果 key 不存在,则 key 被解释为一个空列表,返回 0 ; 如果 key 不是列表类型,返回一个错误。
+ *
+ * @param key the key
+ * @return the long
+ */
+ public Long length(String key) {
+ return opsForList().size(key);
+ }
+
+
+ /**
+ * redis List数据结构 : 根据参数 i 的值,移除列表中与参数 value 相等的元素
+ *
+ * @param key the key
+ * @param i the
+ * @param value the value
+ */
+ public void remove(String key, long i, Object value) {
+ opsForList().remove(key, i, value);
+ }
+
+ /**
+ * redis List数据结构 : 将列表 key 下标为 index 的元素的值设置为 value
+ *
+ * @param key the key
+ * @param index the index
+ * @param value the value
+ */
+ public void set(String key, long index, Object value) {
+ opsForList().set(key, index, value);
+ }
+
+ /**
+ * redis List数据结构 : 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 end 指定。
+ *
+ * @param key the key
+ * @param start the start
+ * @param end the end
+ * @return the list
+ */
+ public List getList(String key, int start, int end) {
+ return opsForList().range(key, start, end);
+ }
+
+ /**
+ * redis List数据结构 : 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 end 指定。
+ *
+ * @param key the key
+ * @param start the start
+ * @param end the end
+ * @param valueSerializer 序列化
+ * @return the list
+ */
+ public List getList(String key, int start, int end, RedisSerializer valueSerializer) {
+ byte[] rawKey = rawKey(key);
+ return redisTemplate.execute(connection -> deserializeValues(connection.lRange(rawKey, start, end), valueSerializer), true);
+ }
+
+ /**
+ * redis List数据结构 : 批量存储
+ *
+ * @param key the key
+ * @param list the list
+ * @return the long
+ */
+ public Long leftPushAll(String key, List list) {
+ return opsForList().leftPushAll(key, list);
+ }
+
+ /**
+ * redis List数据结构 : 将值 value 插入到列表 key 当中,位于值 index 之前或之后,默认之后。
+ *
+ * @param key the key
+ * @param index the index
+ * @param value the value
+ */
+ public void insert(String key, long index, Object value) {
+ opsForList().set(key, index, value);
+ }
+
+ private byte[] rawKey(Object key) {
+ Assert.notNull(key, "non null key required");
+
+ if (key instanceof byte[]) {
+ return (byte[]) key;
+ }
+ RedisSerializer redisSerializer = (RedisSerializer)redisTemplate.getKeySerializer();
+ return redisSerializer.serialize(key);
+ }
+ private byte[] rawValue(Object value, RedisSerializer valueSerializer) {
+ if (value instanceof byte[]) {
+ return (byte[]) value;
+ }
+
+ return valueSerializer.serialize(value);
+ }
+
+ private List deserializeValues(List rawValues, RedisSerializer valueSerializer) {
+ if (valueSerializer == null) {
+ return rawValues;
+ }
+ return SerializationUtils.deserialize(rawValues, valueSerializer);
+ }
+
+ private Object deserializeValue(byte[] value, RedisSerializer valueSerializer) {
+ if (valueSerializer == null) {
+ return value;
+ }
+ return valueSerializer.deserialize(value);
+ }
+}
diff --git a/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/util/RedisObjectSerializer.java b/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/util/RedisObjectSerializer.java
deleted file mode 100644
index 3fe888cc..00000000
--- a/zlt-commons/zlt-redis-spring-boot-starter/src/main/java/com/central/common/redis/util/RedisObjectSerializer.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.central.common.redis.util;
-
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.core.serializer.support.DeserializingConverter;
-import org.springframework.core.serializer.support.SerializingConverter;
-import org.springframework.data.redis.serializer.RedisSerializer;
-import org.springframework.data.redis.serializer.SerializationException;
-
-/**
- * 此时定义的序列化操作表示可以序列化所有类的对象,当然,这个对象所在的类一定要实现序列化接口
- *
- * @author zlt
- */
-public class RedisObjectSerializer implements RedisSerializer {
- // 做一个空数组,不是null
- private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
- // 为了方便进行对象与字节数组的转换,所以应该首先准备出两个转换器
- private Converter serializingConverter = new SerializingConverter();
- private Converter deserializingConverter = new DeserializingConverter();
-
- @Override
- public byte[] serialize(Object obj) {
- // 这个时候没有要序列化的对象出现,所以返回的字节数组应该就是一个空数组
- if (obj == null) {
- return EMPTY_BYTE_ARRAY;
- }
- // 将对象变为字节数组
- return this.serializingConverter.convert(obj);
- }
-
- @Override
- public Object deserialize(byte[] data) {
- // 此时没有对象的内容信息
- if (data == null || data.length == 0) {
- return null;
- }
- return this.deserializingConverter.convert(data);
- }
-
-}
\ No newline at end of file
diff --git a/zlt-commons/zlt-redis-spring-boot-starter/src/main/resources/META-INF/spring.factories b/zlt-commons/zlt-redis-spring-boot-starter/src/main/resources/META-INF/spring.factories
index 924601e9..c0dc55ef 100644
--- a/zlt-commons/zlt-redis-spring-boot-starter/src/main/resources/META-INF/spring.factories
+++ b/zlt-commons/zlt-redis-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -1,4 +1,4 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.central.common.redis.RedisAutoConfigure,\
-com.central.common.redis.lock.RedisDistributedLock,\
+com.central.common.redis.lock.RedissonDistributedLock,\
com.central.common.redis.template.RedisRepository
\ No newline at end of file
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/FeignAutoConfigure.java b/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/FeignAutoConfigure.java
deleted file mode 100644
index afa6bbbd..00000000
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/FeignAutoConfigure.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.central.common.ribbon;
-
-import feign.Logger;
-import org.springframework.context.annotation.Bean;
-
-/**
- * Feign统一配置
- *
- * @author zlt
- * @date 2018/9/18 14:04
- */
-public class FeignAutoConfigure {
-
- /**
- * Feign 日志级别
- */
- @Bean
- Logger.Level feignLoggerLevel() {
- return Logger.Level.FULL;
- }
-}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/LbIsolationAutoConfigure.java b/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/LbIsolationAutoConfigure.java
deleted file mode 100644
index b6943875..00000000
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/LbIsolationAutoConfigure.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.central.common.ribbon;
-
-import com.alibaba.cloud.nacos.ribbon.NacosServer;
-import com.central.common.constant.ConfigConstants;
-import com.central.common.ribbon.rule.VersionIsolationRule;
-import com.netflix.loadbalancer.IRule;
-import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
-import org.springframework.context.annotation.Bean;
-
-/**
- * 自定义负载均衡配置
- *
- * @author zlt
- * @date 2019/9/3
- *
- * Blog: https://blog.csdn.net/zlt2000
- * Github: https://github.com/zlt2000
- */
-@ConditionalOnProperty(value = ConfigConstants.CONFIG_RIBBON_ISOLATION_ENABLED, havingValue = "true")
-@AutoConfigureBefore(RibbonClientConfiguration.class)
-public class LbIsolationAutoConfigure {
- @Bean
- @ConditionalOnClass(NacosServer.class)
- @ConditionalOnMissingBean
- public IRule versionIsolationRule() {
- return new VersionIsolationRule();
- }
-}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/RibbonAutoConfigure.java b/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/RibbonAutoConfigure.java
deleted file mode 100644
index df4983c8..00000000
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/RibbonAutoConfigure.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.central.common.ribbon;
-
-import com.central.common.ribbon.config.RestTemplateProperties;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.netflix.ribbon.DefaultPropertiesFactory;
-import org.springframework.context.annotation.Bean;
-
-/**
- * Ribbon扩展配置类
- *
- * @author zlt
- * @date 2018/11/17 9:24
- */
-@EnableConfigurationProperties(RestTemplateProperties.class)
-public class RibbonAutoConfigure {
- @Bean
- public DefaultPropertiesFactory defaultPropertiesFactory() {
- return new DefaultPropertiesFactory();
- }
-}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/filter/LbIsolationFilter.java b/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/filter/LbIsolationFilter.java
deleted file mode 100644
index 22c5e4ff..00000000
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/filter/LbIsolationFilter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.central.common.ribbon.filter;
-
-import cn.hutool.core.util.StrUtil;
-import com.central.common.constant.CommonConstant;
-import com.central.common.constant.ConfigConstants;
-import com.central.common.context.LbIsolationContextHolder;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * 负载均衡隔离规则过滤器
- *
- * @author zlt
- * @date 2019/9/15
- */
-@ConditionalOnClass(Filter.class)
-public class LbIsolationFilter extends OncePerRequestFilter {
- @Value("${" + ConfigConstants.CONFIG_RIBBON_ISOLATION_ENABLED + ":false}")
- private boolean enableIsolation;
-
- @Override
- protected boolean shouldNotFilter(HttpServletRequest request) {
- return !enableIsolation;
- }
-
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
- FilterChain filterChain) throws IOException, ServletException {
- try {
- String version = request.getHeader(CommonConstant.Z_L_T_VERSION);
- if(StrUtil.isNotEmpty(version)){
- LbIsolationContextHolder.setVersion(version);
- }
-
- filterChain.doFilter(request, response);
- } finally {
- LbIsolationContextHolder.clear();
- }
- }
-}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/rule/VersionIsolationRule.java b/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/rule/VersionIsolationRule.java
deleted file mode 100644
index 5f2e4fdb..00000000
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/com/central/common/ribbon/rule/VersionIsolationRule.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.central.common.ribbon.rule;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.RandomUtil;
-import cn.hutool.core.util.StrUtil;
-import com.alibaba.cloud.nacos.ribbon.NacosServer;
-import com.central.common.constant.CommonConstant;
-import com.central.common.context.LbIsolationContextHolder;
-import com.netflix.loadbalancer.*;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * 根据实例版本号隔离规则
- * 详细用法:https://mp.weixin.qq.com/s/9XQ-SIbYsov3KBx9TGFN0g
- *
- * 实例获取规则顺序如下(不满足则走下一个规则):
- * 1. 相同版本号的实例
- * 2. 无版本号的实例
- * 3. 所有实例中轮询
- *
- * @author zlt
- * @date 2019/9/3
- *
- * Blog: https://blog.csdn.net/zlt2000
- * Github: https://github.com/zlt2000
- */
-public class VersionIsolationRule extends RoundRobinRule {
- private final static String KEY_DEFAULT = "default";
- /**
- * 优先根据版本号取实例
- */
- @Override
- public Server choose(ILoadBalancer lb, Object key) {
- if (lb == null) {
- return null;
- }
- String version;
- if (key != null && !KEY_DEFAULT.equals(key)) {
- version = key.toString();
- } else {
- version = LbIsolationContextHolder.getVersion();
- }
-
- List targetList = null;
- List upList = lb.getReachableServers();
- if (StrUtil.isNotEmpty(version)) {
- //取指定版本号的实例
- targetList = upList.stream().filter(
- server -> version.equals(
- ((NacosServer) server).getMetadata().get(CommonConstant.METADATA_VERSION)
- )
- ).collect(Collectors.toList());
- }
-
- if (CollUtil.isEmpty(targetList)) {
- //只取无版本号的实例
- targetList = upList.stream().filter(
- server -> {
- String metadataVersion = ((NacosServer) server).getMetadata().get(CommonConstant.METADATA_VERSION);
- return StrUtil.isEmpty(metadataVersion);
- }
- ).collect(Collectors.toList());
- }
-
- if (CollUtil.isNotEmpty(targetList)) {
- return getServer(targetList);
- }
- return super.choose(lb, key);
- }
-
- /**
- * 随机取一个实例
- */
- private Server getServer(List upList) {
- int nextInt = RandomUtil.randomInt(upList.size());
- return upList.get(nextInt);
- }
-}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultPropertiesFactory.java b/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultPropertiesFactory.java
deleted file mode 100644
index 8dd490a1..00000000
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultPropertiesFactory.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.springframework.cloud.netflix.ribbon;
-
-import com.netflix.loadbalancer.*;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.env.Environment;
-import org.springframework.util.StringUtils;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.springframework.cloud.netflix.ribbon.SpringClientFactory.NAMESPACE;
-
-/**
- * 扩展 spring cloud ribbon的PropertiesFactory
- * 使其能够支持 配置全局的ribbon.NFLoadBalancerRuleClassName=package.YourRule
- * 然后各个微服务还可以根据自身情况做个性化定制。如:SERVICE_ID.ribbon.NFLoadBalancerRuleClassName=package.YourRule
- *
- * @author zlt
- * @date 2018/11/17 9:29
- */
-public class DefaultPropertiesFactory extends PropertiesFactory {
-
- @Autowired
- private Environment environment;
-
- private Map classToProperty = new HashMap<>(5);
-
- public DefaultPropertiesFactory() {
- super();
- classToProperty.put(ILoadBalancer.class, "NFLoadBalancerClassName");
- classToProperty.put(IPing.class, "NFLoadBalancerPingClassName");
- classToProperty.put(IRule.class, "NFLoadBalancerRuleClassName");
- classToProperty.put(ServerList.class, "NIWSServerListClassName");
- classToProperty.put(ServerListFilter.class, "NIWSServerListFilterClassName");
- }
-
- /**
- * 重写 支持 ribbon.NFLoadBalancerRuleClassName=package.YourRule 全局配置的方式
- */
- @Override
- public String getClassName(Class clazz, String name) {
- String className = super.getClassName(clazz, name);
- // 读取全局配置
- if(!StringUtils.hasText(className) && this.classToProperty.containsKey(clazz)){
- String classNameProperty = this.classToProperty.get(clazz);
- className = environment.getProperty(NAMESPACE + "." + classNameProperty);
- }
- return className;
- }
-}
diff --git a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/resources/META-INF/spring.factories b/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 16f3fb91..00000000
--- a/zlt-commons/zlt-ribbon-spring-boot-starter/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,6 +0,0 @@
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-com.central.common.ribbon.RibbonAutoConfigure,\
-com.central.common.ribbon.FeignAutoConfigure,\
-com.central.common.ribbon.RestTemplateAutoConfigure,\
-com.central.common.ribbon.filter.LbIsolationFilter,\
-com.central.common.ribbon.LbIsolationAutoConfigure
diff --git a/zlt-commons/zlt-sentinel-spring-boot-starter/pom.xml b/zlt-commons/zlt-sentinel-spring-boot-starter/pom.xml
index 34b849d1..2370b915 100644
--- a/zlt-commons/zlt-sentinel-spring-boot-starter/pom.xml
+++ b/zlt-commons/zlt-sentinel-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
com.zlt
zlt-commons
- 3.5.0
+ 5.3.0
4.0.0
jar
@@ -40,5 +40,11 @@
spring-boot-configuration-processor
true
+
+
+ org.springframework
+ spring-webflux
+ true
+
diff --git a/zlt-commons/zlt-sentinel-spring-boot-starter/src/main/java/com/central/sentinel/config/SentinelAutoConfigure.java b/zlt-commons/zlt-sentinel-spring-boot-starter/src/main/java/com/central/sentinel/config/SentinelAutoConfigure.java
index 1ff5bc5e..864d8535 100644
--- a/zlt-commons/zlt-sentinel-spring-boot-starter/src/main/java/com/central/sentinel/config/SentinelAutoConfigure.java
+++ b/zlt-commons/zlt-sentinel-spring-boot-starter/src/main/java/com/central/sentinel/config/SentinelAutoConfigure.java
@@ -1,34 +1,58 @@
package com.central.sentinel.config;
import cn.hutool.json.JSONUtil;
-import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
-import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
-import com.alibaba.csp.sentinel.slots.block.BlockException;
+import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.BlockRequestHandler;
+import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.central.common.model.Result;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.server.ServerResponse;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
/**
* Sentinel配置类
*
* @author zlt
* @date 2019/1/22
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
public class SentinelAutoConfigure {
- public SentinelAutoConfigure() {
- WebCallbackManager.setUrlBlockHandler(new CustomUrlBlockHandler());
+ /**
+ * 限流、熔断统一处理类
+ */
+ @Configuration
+ @ConditionalOnClass(HttpServletRequest.class)
+ public static class WebmvcHandler {
+ @Bean
+ public BlockExceptionHandler webmvcBlockExceptionHandler() {
+ return (request, response, e) -> {
+ response.setStatus(429);
+ Result result = Result.failed(e.getMessage());
+ response.getWriter().print(JSONUtil.toJsonStr(result));
+ };
+ }
}
+
/**
* 限流、熔断统一处理类
*/
- public class CustomUrlBlockHandler implements UrlBlockHandler {
- @Override
- public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {
- Result result = Result.failed("flow-limiting");
- httpServletResponse.getWriter().print(JSONUtil.toJsonStr(result));
+ @Configuration
+ @ConditionalOnClass(ServerResponse.class)
+ public static class WebfluxHandler {
+ @Bean
+ public BlockRequestHandler webfluxBlockExceptionHandler() {
+ return (exchange, t) ->
+ ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
+ .contentType(MediaType.APPLICATION_JSON)
+ .body(BodyInserters.fromValue(Result.failed(t.getMessage())));
}
}
}
diff --git a/zlt-commons/zlt-swagger2-spring-boot-starter/pom.xml b/zlt-commons/zlt-swagger2-spring-boot-starter/pom.xml
index 8136ed25..b699bc74 100644
--- a/zlt-commons/zlt-swagger2-spring-boot-starter/pom.xml
+++ b/zlt-commons/zlt-swagger2-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
com.zlt
zlt-commons
- 3.5.0
+ 5.3.0
4.0.0
jar
@@ -17,12 +17,8 @@
spring-boot-starter
- io.springfox
- springfox-swagger-ui
-
-
- io.springfox
- springfox-swagger2
+ com.github.xiaoymin
+ knife4j-micro-spring-boot-starter
org.springframework.boot
diff --git a/zlt-commons/zlt-swagger2-spring-boot-starter/src/main/java/com/central/common/swagger2/Swagger2Configuration.java b/zlt-commons/zlt-swagger2-spring-boot-starter/src/main/java/com/central/common/swagger2/Swagger2Configuration.java
deleted file mode 100644
index 2903d4c4..00000000
--- a/zlt-commons/zlt-swagger2-spring-boot-starter/src/main/java/com/central/common/swagger2/Swagger2Configuration.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.central.common.swagger2;
-
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Import;
-import springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration;
-
-/**
- *
- * @author zlt
- * @date 2018/11/18 9:20
- */
-@ConditionalOnProperty(name = "zlt.swagger.enabled", matchIfMissing = true)
-@Import({
- Swagger2DocumentationConfiguration.class
-})
-public class Swagger2Configuration {
-}
diff --git a/zlt-commons/zlt-swagger2-spring-boot-starter/src/main/java/com/central/common/swagger2/SwaggerAutoConfiguration.java b/zlt-commons/zlt-swagger2-spring-boot-starter/src/main/java/com/central/common/swagger2/SwaggerAutoConfiguration.java
index 09e20d36..0919f96d 100644
--- a/zlt-commons/zlt-swagger2-spring-boot-starter/src/main/java/com/central/common/swagger2/SwaggerAutoConfiguration.java
+++ b/zlt-commons/zlt-swagger2-spring-boot-starter/src/main/java/com/central/common/swagger2/SwaggerAutoConfiguration.java
@@ -1,16 +1,18 @@
package com.central.common.swagger2;
+import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
+import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
@@ -25,6 +27,7 @@
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.LinkedList;
@@ -36,10 +39,14 @@
/**
* @author zlt
* @date 2018/11/18 9:22
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
*/
-@Import( {
- Swagger2Configuration.class
-})
+@Configuration
+@EnableSwagger2
+@EnableKnife4j
+@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerAutoConfiguration implements BeanFactoryAware {
private static final String AUTH_KEY = "Authorization";
diff --git a/zlt-commons/zlt-zookeeper-spring-boot-starter/pom.xml b/zlt-commons/zlt-zookeeper-spring-boot-starter/pom.xml
new file mode 100644
index 00000000..601b894a
--- /dev/null
+++ b/zlt-commons/zlt-zookeeper-spring-boot-starter/pom.xml
@@ -0,0 +1,31 @@
+
+
+
+ com.zlt
+ zlt-commons
+ 5.3.0
+
+ 4.0.0
+ jar
+ zlt-zookeeper-spring-boot-starter
+ zookeeper通用组件
+
+
+ com.zlt
+ zlt-common-core
+
+
+
+ org.apache.curator
+ curator-recipes
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
diff --git a/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/ZookeeperAutoConfiguration.java b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/ZookeeperAutoConfiguration.java
new file mode 100644
index 00000000..9744726a
--- /dev/null
+++ b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/ZookeeperAutoConfiguration.java
@@ -0,0 +1,40 @@
+package com.central.common.zookeeper;
+
+import com.central.common.zookeeper.properties.ZookeeperProperty;
+import org.apache.curator.RetryPolicy;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.ExponentialBackoffRetry;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * zookeeper 配置类
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/4/3
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@EnableConfigurationProperties(ZookeeperProperty.class)
+@ComponentScan
+public class ZookeeperAutoConfiguration {
+ /**
+ * 初始化连接
+ */
+ @Bean(initMethod = "start", destroyMethod = "close")
+ @ConditionalOnMissingBean
+ public CuratorFramework curatorFramework(ZookeeperProperty property) {
+ RetryPolicy retryPolicy = new ExponentialBackoffRetry(property.getBaseSleepTime(), property.getMaxRetries());
+ return CuratorFrameworkFactory.builder()
+ .connectString(property.getConnectString())
+ .connectionTimeoutMs(property.getConnectionTimeout())
+ .sessionTimeoutMs(property.getSessionTimeout())
+ .retryPolicy(retryPolicy)
+ .build();
+ }
+}
diff --git a/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/lock/ZookeeperDistributedLock.java b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/lock/ZookeeperDistributedLock.java
new file mode 100644
index 00000000..28d24808
--- /dev/null
+++ b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/lock/ZookeeperDistributedLock.java
@@ -0,0 +1,71 @@
+package com.central.common.zookeeper.lock;
+
+import com.central.common.constant.CommonConstant;
+import com.central.common.exception.LockException;
+import com.central.common.lock.DistributedLock;
+import com.central.common.lock.ZLock;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.recipes.locks.InterProcessMutex;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * zookeeper分布式锁实现
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/4/3
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Component
+@ConditionalOnProperty(prefix = "zlt.lock", name = "lockerType", havingValue = "ZK")
+public class ZookeeperDistributedLock implements DistributedLock {
+ @Resource
+ private CuratorFramework client;
+
+ private ZLock getLock(String key) {
+ InterProcessMutex lock = new InterProcessMutex(client, getPath(key));
+ return new ZLock(lock, this);
+ }
+
+ @Override
+ public ZLock lock(String key, long leaseTime, TimeUnit unit, boolean isFair) throws Exception {
+ ZLock zLock = this.getLock(key);
+ InterProcessMutex ipm = (InterProcessMutex)zLock.getLock();
+ ipm.acquire();
+ return zLock;
+ }
+
+ @Override
+ public ZLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws Exception {
+ ZLock zLock = this.getLock(key);
+ InterProcessMutex ipm = (InterProcessMutex)zLock.getLock();
+ if (ipm.acquire(waitTime, unit)) {
+ return zLock;
+ }
+ return null;
+ }
+
+ @Override
+ public void unlock(Object lock) throws Exception {
+ if (lock != null) {
+ if (lock instanceof InterProcessMutex) {
+ InterProcessMutex ipm = (InterProcessMutex)lock;
+ if (ipm.isAcquiredInThisProcess()) {
+ ipm.release();
+ }
+ } else {
+ throw new LockException("requires InterProcessMutex type");
+ }
+ }
+ }
+
+ private String getPath(String key) {
+ return CommonConstant.PATH_SPLIT + CommonConstant.LOCK_KEY_PREFIX + CommonConstant.PATH_SPLIT + key;
+ }
+}
diff --git a/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/properties/ZookeeperProperty.java b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/properties/ZookeeperProperty.java
new file mode 100644
index 00000000..7ed7d167
--- /dev/null
+++ b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/properties/ZookeeperProperty.java
@@ -0,0 +1,45 @@
+package com.central.common.zookeeper.properties;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * zookeeper配置
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/4/3
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Setter
+@Getter
+@ConfigurationProperties(prefix = "zlt.zookeeper")
+public class ZookeeperProperty {
+ /**
+ * zk连接集群,多个用逗号隔开
+ */
+ private String connectString;
+
+ /**
+ * 会话超时时间(毫秒)
+ */
+ private int sessionTimeout = 15000;
+
+ /**
+ * 连接超时时间(毫秒)
+ */
+ private int connectionTimeout = 15000;
+
+ /**
+ * 初始重试等待时间(毫秒)
+ */
+ private int baseSleepTime = 2000;
+
+ /**
+ * 重试最大次数
+ */
+ private int maxRetries = 10;
+}
diff --git a/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/template/ZookeeperTemplate.java b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/template/ZookeeperTemplate.java
new file mode 100644
index 00000000..397e5323
--- /dev/null
+++ b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/java/com/central/common/zookeeper/template/ZookeeperTemplate.java
@@ -0,0 +1,231 @@
+package com.central.common.zookeeper.template;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.central.common.constant.CommonConstant;
+import lombok.SneakyThrows;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.recipes.cache.*;
+import org.apache.zookeeper.CreateMode;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+
+import java.util.List;
+
+/**
+ * zookeeper模板类
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/4/10
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Component
+public class ZookeeperTemplate {
+ private final CuratorFramework client;
+
+ public ZookeeperTemplate(CuratorFramework client) {
+ this.client = client;
+ }
+
+ /**
+ * 创建空节点,默认持久节点
+ *
+ * @param path 节点路径
+ * @param node 节点名称
+ * @return 完整路径
+ */
+ @SneakyThrows
+ public String createNode(String path, String node) {
+ return createNode(path, node, CreateMode.PERSISTENT);
+ }
+
+ /**
+ * 创建带类型的空节点
+ * @param path 节点路径
+ * @param node 节点名称
+ * @param createMode 类型
+ * @return 完整路径
+ */
+ @SneakyThrows
+ public String createNode(String path, String node, CreateMode createMode) {
+ path = buildPath(path, node);
+ client.create()
+ .orSetData()
+ .creatingParentsIfNeeded()
+ .withMode(createMode)
+ .forPath(path);
+ return path;
+ }
+
+
+ /**
+ * 创建节点,默认持久节点
+ * @param path 节点路径
+ * @param node 节点名称
+ * @param value 节点值
+ * @return 完整路径
+ */
+ @SneakyThrows
+ public String createNode(String path, String node, String value) {
+ return createNode(path, node, value, CreateMode.PERSISTENT);
+ }
+
+ /**
+ * 创建节点,默认持久节点
+ * @param path 节点路径
+ * @param node 节点名称
+ * @param value 节点值
+ * @param createMode 节点类型
+ * @return 完整路径
+ */
+ @SneakyThrows
+ public String createNode(String path, String node, String value, CreateMode createMode) {
+ Assert.isTrue(StrUtil.isNotEmpty(value), "zookeeper节点值不能为空!");
+
+ path = buildPath(path, node);
+ client.create()
+ .orSetData()
+ .creatingParentsIfNeeded()
+ .withMode(createMode)
+ .forPath(path, value.getBytes());
+ return path;
+ }
+
+ /**
+ * 获取节点数据
+ * @param path 路径
+ * @param node 节点名称
+ * @return 节点值
+ */
+ @SneakyThrows
+ public String get(String path, String node) {
+ path = buildPath(path, node);
+ byte[] bytes = client.getData().forPath(path);
+ if (bytes.length > 0) {
+ return new String(bytes);
+ }
+ return null;
+ }
+
+ /**
+ * 更新节点数据
+ * @param path 节点路径
+ * @param node 节点名称
+ * @param value 更新值
+ * @return 完整路径
+ */
+ @SneakyThrows
+ public String update(String path, String node, String value) {
+ Assert.isTrue(StrUtil.isNotEmpty(value), "zookeeper节点值不能为空!");
+
+ path = buildPath(path, node);
+ client.setData().forPath(path, value.getBytes());
+ return path;
+ }
+
+ /**
+ * 删除节点,并且递归删除子节点
+ * @param path 路径
+ * @param node 节点名称
+ */
+ @SneakyThrows
+ public void delete(String path, String node) {
+ path = buildPath(path, node);
+ client.delete().quietly().deletingChildrenIfNeeded().forPath(path);
+ }
+
+ /**
+ * 获取子节点
+ * @param path 节点路径
+ * @return 子节点集合
+ */
+ @SneakyThrows
+ public List getChildren(String path) {
+ if(StrUtil.isEmpty(path)) {
+ return null;
+ }
+
+ if (!path.startsWith(CommonConstant.PATH_SPLIT)) {
+ path = CommonConstant.PATH_SPLIT + path;
+ }
+ return client.getChildren().forPath(path);
+ }
+
+ /**
+ * 判断节点是否存在
+ * @param path 路径
+ * @param node 节点名称
+ * @return 结果
+ */
+ public boolean exists(String path, String node) {
+ List list = getChildren(path);
+ return CollUtil.isNotEmpty(list) && list.contains(node);
+ }
+
+ /**
+ * 对一个节点进行监听,监听事件包括指定的路径节点的增、删、改的操作
+ * @param path 节点路径
+ * @param listener 回调方法
+ */
+ public void watchNode(String path, NodeCacheListener listener) {
+ CuratorCacheListener curatorCacheListener = CuratorCacheListener.builder()
+ .forNodeCache(listener)
+ .build();
+ CuratorCache curatorCache = CuratorCache.builder(client, path).build();
+ curatorCache.listenable().addListener(curatorCacheListener);
+ curatorCache.start();
+ }
+
+
+ /**
+ * 对指定的路径节点的一级子目录进行监听,不对该节点的操作进行监听,对其子目录的节点进行增、删、改的操作监听
+ * @param path 节点路径
+ * @param listener 回调方法
+ */
+ public void watchChildren(String path, PathChildrenCacheListener listener) {
+ CuratorCacheListener curatorCacheListener = CuratorCacheListener.builder()
+ .forPathChildrenCache(path, client, listener)
+ .build();
+ CuratorCache curatorCache = CuratorCache.builder(client, path).build();
+ curatorCache.listenable().addListener(curatorCacheListener);
+ curatorCache.start();
+ }
+
+ /**
+ * 将指定的路径节点作为根节点(祖先节点),对其所有的子节点操作进行监听,呈现树形目录的监听
+ * @param path 节点路径
+ * @param maxDepth 回调方法
+ * @param listener 监听
+ */
+ public void watchTree(String path, int maxDepth, TreeCacheListener listener) {
+ CuratorCacheListener curatorCacheListener = CuratorCacheListener.builder()
+ .forTreeCache(client, listener)
+ .build();
+ CuratorCache curatorCache = CuratorCache.builder(client, path).build();
+ curatorCache.listenable().addListener(curatorCacheListener);
+ curatorCache.start();
+ }
+
+ /**
+ * 转换路径
+ * @param path 路径
+ * @param node 节点名
+ */
+ private String buildPath(String path, String node) {
+ Assert.isTrue(StrUtil.isNotEmpty(path) && StrUtil.isNotEmpty(node)
+ , "zookeeper路径或者节点名称不能为空!");
+
+ if (!path.startsWith(CommonConstant.PATH_SPLIT)) {
+ path = CommonConstant.PATH_SPLIT + path;
+ }
+
+ if (CommonConstant.PATH_SPLIT.equals(path)) {
+ return path + node;
+ } else {
+ return path + CommonConstant.PATH_SPLIT + node;
+ }
+ }
+}
diff --git a/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/resources/META-INF/spring.factories b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 00000000..96f338c0
--- /dev/null
+++ b/zlt-commons/zlt-zookeeper-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+com.central.common.zookeeper.ZookeeperAutoConfiguration
\ No newline at end of file
diff --git a/zlt-config/pom.xml b/zlt-config/pom.xml
index 13e37947..bd4ed8a4 100644
--- a/zlt-config/pom.xml
+++ b/zlt-config/pom.xml
@@ -5,7 +5,7 @@
com.zlt
central-platform
- 3.5.0
+ 5.3.0
4.0.0
jar
diff --git a/zlt-config/src/main/resources/application-dev.properties b/zlt-config/src/main/resources/application-dev.properties
index a8c21924..43d5ef6f 100644
--- a/zlt-config/src/main/resources/application-dev.properties
+++ b/zlt-config/src/main/resources/application-dev.properties
@@ -21,6 +21,12 @@ zlt.sentinel.dashboard=192.168.28.130:6999
zlt.fdfs.web-url=192.168.28.130
zlt.fdfs.trackerList=${zlt.fdfs.web-url}:22122
+##### s3配置
+zlt.s3.access-key=minioadmin
+zlt.s3.accessKeySecret=minioadmin
+zlt.s3.endpoint=http://192.168.28.130:9000
+zlt.s3.bucketName=test
+
##### 日志链路追踪
zlt.trace.enable=true
@@ -28,4 +34,7 @@ zlt.trace.enable=true
zlt.ribbon.isolation.enabled=false
##### mybatis-plus打印完整sql(只适用于开发环境)
-mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
\ No newline at end of file
+mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
+
+# 开启版本路由
+#zlt.loadbalance.isolation.enabled=true
\ No newline at end of file
diff --git a/zlt-config/src/main/resources/application-prod.properties b/zlt-config/src/main/resources/application-prod.properties
index 933e9b66..5fe2ca3d 100644
--- a/zlt-config/src/main/resources/application-prod.properties
+++ b/zlt-config/src/main/resources/application-prod.properties
@@ -21,5 +21,11 @@ zlt.sentinel.dashboard=192.168.28.130:6999
zlt.fdfs.web-url=192.168.28.130
zlt.fdfs.trackerList=${zlt.fdfs.web-url}:22122
+##### s3配置
+zlt.s3.access-key=minioadmin
+zlt.s3.accessKeySecret=minioadmin
+zlt.s3.endpoint=http://192.168.28.130:9000
+zlt.s3.bucketName=test
+
##### 日志链路追踪
zlt.trace.enable=true
\ No newline at end of file
diff --git a/zlt-config/src/main/resources/application-test.properties b/zlt-config/src/main/resources/application-test.properties
index b46b08ee..ddf04395 100644
--- a/zlt-config/src/main/resources/application-test.properties
+++ b/zlt-config/src/main/resources/application-test.properties
@@ -21,5 +21,11 @@ zlt.sentinel.dashboard=192.168.28.130:6999
zlt.fdfs.web-url=192.168.28.130
zlt.fdfs.trackerList=${zlt.fdfs.web-url}:22122
+##### s3配置
+zlt.s3.access-key=minioadmin
+zlt.s3.accessKeySecret=minioadmin
+zlt.s3.endpoint=http://192.168.28.130:9000
+zlt.s3.bucketName=test
+
##### 日志链路追踪
zlt.trace.enable=true
\ No newline at end of file
diff --git a/zlt-config/src/main/resources/application.properties b/zlt-config/src/main/resources/application.properties
index 87d5e328..99f7c0c0 100644
--- a/zlt-config/src/main/resources/application.properties
+++ b/zlt-config/src/main/resources/application.properties
@@ -1,18 +1,7 @@
########################## application级别通用配置 ##########################
-##### ribbon配置
-## 从注册中心刷新servelist的时间 默认30秒,单位ms
-ribbon.ServerListRefreshInterval=15000
-## 请求连接的超时时间 默认1秒,单位ms
-ribbon.ConnectTimeout=30000
-## 请求处理的超时时间 默认1秒,单位ms
-ribbon.ReadTimeout=30000
-## 对所有操作请求都进行重试,不配置这个MaxAutoRetries不起作用 默认false
-#ribbon.OkToRetryOnAllOperations=true
-## 对当前实例的重试次数 默认0
-#ribbon.MaxAutoRetries=1
-## 切换实例的重试次数 默认1
-ribbon.MaxAutoRetriesNextServer=0
-
+##### loadbalancer配置
+## 切换实例的重试
+spring.cloud.loadbalancer.retry.enabled=false
##### feign配置
feign.sentinel.enabled=true
@@ -94,4 +83,7 @@ spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接
-spring.redis.lettuce.pool.min-idle=0
\ No newline at end of file
+spring.redis.lettuce.pool.min-idle=0
+
+##### logging配置
+logging.level.com.alibaba.nacos.client.naming=warn
\ No newline at end of file
diff --git a/zlt-config/src/main/resources/bootstrap.properties b/zlt-config/src/main/resources/bootstrap.properties
index c0baec4b..5fe08308 100644
--- a/zlt-config/src/main/resources/bootstrap.properties
+++ b/zlt-config/src/main/resources/bootstrap.properties
@@ -4,6 +4,8 @@ spring.profiles.active=dev
##### nacos(注册中心和配置中心)地址
spring.cloud.nacos.server-addr=192.168.28.130:8848
+#spring.cloud.nacos.username=nacos
+#spring.cloud.nacos.password=nacos
spring.cloud.nacos.config.file-extension=yml
spring.cloud.nacos.config.shared-dataids=common.yml
spring.cloud.nacos.config.refreshable-dataids=common.yml
diff --git a/zlt-demo/dubbo-demo/README.md b/zlt-demo/dubbo-demo/README.md
new file mode 100644
index 00000000..824c4bfa
--- /dev/null
+++ b/zlt-demo/dubbo-demo/README.md
@@ -0,0 +1,12 @@
+## Demo说明
+
+Spring Cloud 集成 Dubbo 的 demo
+
+启动后访问:http://127.0.0.1:8091/test/abc
+
+
+
+## 集成 Spring Cloud Gateway
+[Dubbo想要个网关怎么办?试试整合Spring Cloud Gateway](https://mp.weixin.qq.com/s/_idYl39i1eQejLLLlCW2sg)
+
+
diff --git a/zlt-demo/dubbo-demo/pom.xml b/zlt-demo/dubbo-demo/pom.xml
new file mode 100644
index 00000000..46ef12a8
--- /dev/null
+++ b/zlt-demo/dubbo-demo/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+ com.zlt
+ zlt-demo
+ 5.3.0
+
+ dubbo-demo
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ com.zlt
+ zlt-log-spring-boot-starter
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-dubbo
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zlt-demo/dubbo-demo/src/main/java/org/zlt/WebDubboApp.java b/zlt-demo/dubbo-demo/src/main/java/org/zlt/WebDubboApp.java
new file mode 100644
index 00000000..059c4d5c
--- /dev/null
+++ b/zlt-demo/dubbo-demo/src/main/java/org/zlt/WebDubboApp.java
@@ -0,0 +1,20 @@
+package org.zlt;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+/**
+ * @author zlt
+ * @date 2020/1/30
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@EnableDiscoveryClient
+@SpringBootApplication
+public class WebDubboApp {
+ public static void main(String[] args) {
+ SpringApplication.run(WebDubboApp.class, args);
+ }
+}
diff --git a/zlt-demo/dubbo-demo/src/main/java/org/zlt/controller/WebController.java b/zlt-demo/dubbo-demo/src/main/java/org/zlt/controller/WebController.java
new file mode 100644
index 00000000..0a2e9a84
--- /dev/null
+++ b/zlt-demo/dubbo-demo/src/main/java/org/zlt/controller/WebController.java
@@ -0,0 +1,28 @@
+package org.zlt.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+import org.zlt.service.RpcService;
+
+/**
+ * @author zlt
+ * @date 2020/6/26
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Slf4j
+@RestController
+public class WebController {
+ @DubboReference
+ private RpcService dubboService;
+
+ @GetMapping("/test/{p}")
+ public String test(@PathVariable("p") String param) {
+ log.info("==============WebController");
+ return dubboService.test(param);
+ }
+}
diff --git a/zlt-demo/dubbo-demo/src/main/java/org/zlt/service/RpcService.java b/zlt-demo/dubbo-demo/src/main/java/org/zlt/service/RpcService.java
new file mode 100644
index 00000000..00e6fc3c
--- /dev/null
+++ b/zlt-demo/dubbo-demo/src/main/java/org/zlt/service/RpcService.java
@@ -0,0 +1,12 @@
+package org.zlt.service;
+
+/**
+ * @author zlt
+ * @date 2020/1/30
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+public interface RpcService {
+ String test(String param);
+}
diff --git a/zlt-demo/dubbo-demo/src/main/java/org/zlt/service/impl/RpcServiceImpl.java b/zlt-demo/dubbo-demo/src/main/java/org/zlt/service/impl/RpcServiceImpl.java
new file mode 100644
index 00000000..cfabb23e
--- /dev/null
+++ b/zlt-demo/dubbo-demo/src/main/java/org/zlt/service/impl/RpcServiceImpl.java
@@ -0,0 +1,22 @@
+package org.zlt.service.impl;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.zlt.service.RpcService;
+
+/**
+ * @author zlt
+ * @date 2020/1/30
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Slf4j
+@DubboService(protocol = "dubbo")
+public class RpcServiceImpl implements RpcService {
+ @Override
+ public String test(String param) {
+ log.info("==============RpcServiceImpl");
+ return "dubbo service: " + param;
+ }
+}
diff --git a/zlt-demo/dubbo-demo/src/main/resources/application.yml b/zlt-demo/dubbo-demo/src/main/resources/application.yml
new file mode 100644
index 00000000..5cfc3893
--- /dev/null
+++ b/zlt-demo/dubbo-demo/src/main/resources/application.yml
@@ -0,0 +1,19 @@
+dubbo:
+ scan:
+ base-packages: org.zlt.service
+ protocols:
+ dubbo:
+ name: dubbo
+ port: -1
+ registry:
+ address: spring-cloud://localhost
+ consumer:
+ timeout: 5000
+ check: false
+ retries: 0
+ cloud:
+ subscribed-services:
+
+zlt:
+ trace:
+ enable: true
\ No newline at end of file
diff --git a/zlt-demo/dubbo-demo/src/main/resources/bootstrap.yml b/zlt-demo/dubbo-demo/src/main/resources/bootstrap.yml
new file mode 100644
index 00000000..6484c93d
--- /dev/null
+++ b/zlt-demo/dubbo-demo/src/main/resources/bootstrap.yml
@@ -0,0 +1,11 @@
+server:
+ port: 8091
+
+spring:
+ application:
+ name: zlt-web-dubbo
+ main:
+ allow-bean-definition-overriding: true
+ cloud:
+ nacos:
+ server-addr: 192.168.28.130:8848
\ No newline at end of file
diff --git a/zlt-demo/pom.xml b/zlt-demo/pom.xml
index 7bc9c0c4..93988862 100644
--- a/zlt-demo/pom.xml
+++ b/zlt-demo/pom.xml
@@ -4,7 +4,7 @@
com.zlt
central-platform
- 3.5.0
+ 5.3.0
zlt-demo
pom
@@ -20,5 +20,7 @@
seata-demo
sso-demo
+
+ dubbo-demo
\ No newline at end of file
diff --git a/zlt-demo/rocketmq-demo/pom.xml b/zlt-demo/rocketmq-demo/pom.xml
index 97fbe2bb..2fb80a0b 100644
--- a/zlt-demo/rocketmq-demo/pom.xml
+++ b/zlt-demo/rocketmq-demo/pom.xml
@@ -4,7 +4,7 @@
com.zlt
zlt-demo
- 3.5.0
+ 5.3.0
rocketmq-demo
pom
diff --git a/zlt-demo/rocketmq-demo/rocketmq-consume/pom.xml b/zlt-demo/rocketmq-demo/rocketmq-consume/pom.xml
index e3983aea..ee15dd55 100644
--- a/zlt-demo/rocketmq-demo/rocketmq-consume/pom.xml
+++ b/zlt-demo/rocketmq-demo/rocketmq-consume/pom.xml
@@ -4,7 +4,7 @@
com.zlt
rocketmq-demo
- 3.5.0
+ 5.3.0
rocketmq-consume
rocketMQ消费者demo
diff --git a/zlt-demo/rocketmq-demo/rocketmq-produce/pom.xml b/zlt-demo/rocketmq-demo/rocketmq-produce/pom.xml
index bd7de467..2201711e 100644
--- a/zlt-demo/rocketmq-demo/rocketmq-produce/pom.xml
+++ b/zlt-demo/rocketmq-demo/rocketmq-produce/pom.xml
@@ -4,7 +4,7 @@
com.zlt
rocketmq-demo
- 3.5.0
+ 5.3.0
rocketmq-produce
rocketMQ生产者demo
diff --git a/zlt-demo/rocketmq-demo/rocketmq-transactional/pom.xml b/zlt-demo/rocketmq-demo/rocketmq-transactional/pom.xml
index 9227a608..0973e0e9 100644
--- a/zlt-demo/rocketmq-demo/rocketmq-transactional/pom.xml
+++ b/zlt-demo/rocketmq-demo/rocketmq-transactional/pom.xml
@@ -4,7 +4,7 @@
com.zlt
rocketmq-demo
- 3.5.0
+ 5.3.0
rocketmq-transactional
rocketMQ事务消息demo
diff --git a/zlt-demo/rocketmq-demo/rocketmq-transactional/src/main/java/com/rocketmq/demo/listener/OrderTransactionListenerImpl.java b/zlt-demo/rocketmq-demo/rocketmq-transactional/src/main/java/com/rocketmq/demo/listener/OrderTransactionListenerImpl.java
index c7ec3172..103551bc 100644
--- a/zlt-demo/rocketmq-demo/rocketmq-transactional/src/main/java/com/rocketmq/demo/listener/OrderTransactionListenerImpl.java
+++ b/zlt-demo/rocketmq-demo/rocketmq-transactional/src/main/java/com/rocketmq/demo/listener/OrderTransactionListenerImpl.java
@@ -1,6 +1,6 @@
package com.rocketmq.demo.listener;
-import com.alibaba.fastjson.JSON;
+import com.central.common.utils.JsonUtil;
import com.rocketmq.demo.model.Order;
import com.rocketmq.demo.service.IOrderService;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
@@ -24,7 +24,7 @@ public class OrderTransactionListenerImpl implements RocketMQLocalTransactionLis
public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object arg) {
//插入订单数据
String orderJson = new String(((byte[])message.getPayload()));
- Order order = JSON.parseObject(orderJson, Order.class);
+ Order order = JsonUtil.toObject(orderJson, Order.class);
orderService.save(order);
String produceError = (String)message.getHeaders().get("produceError");
diff --git a/zlt-demo/seata-demo/README.md b/zlt-demo/seata-demo/README.md
index 34205968..9c596fb7 100644
--- a/zlt-demo/seata-demo/README.md
+++ b/zlt-demo/seata-demo/README.md
@@ -1,11 +1,70 @@
## **详细的原理和部署细节请查看**
-[Spring Cloud同步场景分布式事务怎样做?试试Seata](https://mp.weixin.qq.com/s/0yCmHzlXDC9BkbUuEt0_fQ)
+[SEATA同步场景事务(v1.3)](https://www.kancloud.cn/zlt2000/microservices-platform/1280566)
+
+## 测试环境
+* mysql 5.7
+* seata 1.3
+* nacos 1.3
+> **注意**:如果nacos使用低于1.3的版本不需要配置username和password;如果使用1.3以上版本必需开启 `nacos.core.auth.enabled=true` 并且配置username和password,否则读取不到seata-server
+
+## 配置中心的配置如下
+**config.txt**
+```properties
+service.vgroupMapping.test_tx_service_group=default
+store.mode=db
+store.db.datasource=druid
+store.db.dbType=mysql
+store.db.url=jdbc:mysql://192.168.28.130:3306/seata?useUnicode=true
+store.db.driverClassName=com.mysql.jdbc.Driver
+store.db.user=root
+store.db.password=root
+store.db.minConn=5
+store.db.maxConn=30
+store.db.globalTable=global_table
+store.db.branchTable=branch_table
+store.db.queryLimit=100
+store.db.lockTable=lock_table
+store.db.maxWait=5000
+```
+>根据自己的环境修改 url、user、password 配置值
-## 说明
+
+## seata的配置如下
+**registry.conf**
+```json
+registry {
+ # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
+ type = "nacos"
+ nacos {
+ application = "seata-server"
+ serverAddr = "192.168.28.130:8848"
+ group = "SEATA_GROUP"
+ namespace = ""
+ cluster = "default"
+ username = "nacos"
+ password = "nacos"
+ }
+}
+config {
+ # file、nacos 、apollo、zk、consul、etcd3
+ type = "nacos"
+
+ nacos {
+ serverAddr = "192.168.28.130:8848"
+ namespace = ""
+ group = "SEATA_GROUP"
+ username = "nacos"
+ password = "nacos"
+ }
+}
+```
+
+
+## 说明
**包括以下5个模块,分别是**
* `business-service`:业务服务
diff --git a/zlt-demo/seata-demo/account-service/pom.xml b/zlt-demo/seata-demo/account-service/pom.xml
index f9c9681b..4c5f4143 100644
--- a/zlt-demo/seata-demo/account-service/pom.xml
+++ b/zlt-demo/seata-demo/account-service/pom.xml
@@ -5,7 +5,7 @@
com.zlt
seata-demo
- 3.5.0
+ 5.3.0
account-service
diff --git a/zlt-demo/seata-demo/account-service/src/main/resources/application.yml b/zlt-demo/seata-demo/account-service/src/main/resources/application.yml
index 9e1eaef2..1f7f5a96 100644
--- a/zlt-demo/seata-demo/account-service/src/main/resources/application.yml
+++ b/zlt-demo/seata-demo/account-service/src/main/resources/application.yml
@@ -4,8 +4,20 @@ spring:
username: root
password: 1q2w3e4r
driver-class-name: com.mysql.cj.jdbc.Driver
- cloud:
- alibaba:
- seata:
- # seata 服务分组,要与服务端nacos-config.txt中service.vgroup_mapping的后缀对应,默认是${spring.application.name}-fescar-service-group
- tx-service-group: account-service-group
\ No newline at end of file
+
+seata:
+ tx-service-group: test_tx_service_group
+ config:
+ type: nacos
+ nacos:
+ serverAddr: ${spring.cloud.nacos.server-addr}
+ group: SEATA_GROUP
+ username: nacos
+ password: nacos
+ registry:
+ type: nacos
+ nacos:
+ server-addr: ${spring.cloud.nacos.server-addr}
+ group: SEATA_GROUP
+ username: nacos
+ password: nacos
\ No newline at end of file
diff --git a/zlt-demo/seata-demo/account-service/src/main/resources/bootstrap.yml b/zlt-demo/seata-demo/account-service/src/main/resources/bootstrap.yml
index fce0c942..1c062281 100644
--- a/zlt-demo/seata-demo/account-service/src/main/resources/bootstrap.yml
+++ b/zlt-demo/seata-demo/account-service/src/main/resources/bootstrap.yml
@@ -4,7 +4,10 @@ server:
spring:
application:
name: account-service
+ main:
+ allow-bean-definition-overriding: true
cloud:
nacos:
- discovery:
- server-addr: 192.168.28.130:8848
\ No newline at end of file
+ server-addr: 192.168.28.130:8848
+ username: nacos
+ password: nacos
\ No newline at end of file
diff --git a/zlt-demo/seata-demo/account-service/src/main/resources/registry.conf b/zlt-demo/seata-demo/account-service/src/main/resources/registry.conf
deleted file mode 100644
index 96c107da..00000000
--- a/zlt-demo/seata-demo/account-service/src/main/resources/registry.conf
+++ /dev/null
@@ -1,26 +0,0 @@
-registry {
- # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
- type = "nacos"
-
- nacos {
- serverAddr = "192.168.28.130"
- namespace = "public"
- cluster = "default"
- }
- file {
- name = "file.conf"
- }
-}
-config {
- # file、nacos 、apollo、zk、consul、etcd3
- type = "nacos"
- nacos {
- serverAddr = "192.168.28.130"
- namespace = "public"
- cluster = "default"
- }
- file {
- name = "file.conf"
- }
-}
-
diff --git a/zlt-demo/seata-demo/business-service/pom.xml b/zlt-demo/seata-demo/business-service/pom.xml
index 10c61b9d..a29e3f52 100644
--- a/zlt-demo/seata-demo/business-service/pom.xml
+++ b/zlt-demo/seata-demo/business-service/pom.xml
@@ -5,14 +5,14 @@
com.zlt
seata-demo
- 3.5.0
+ 5.3.0
business-service
com.zlt
- zlt-ribbon-spring-boot-starter
+ zlt-loadbalancer-spring-boot-starter
org.springframework.boot
diff --git a/zlt-demo/seata-demo/business-service/src/main/resources/application.yml b/zlt-demo/seata-demo/business-service/src/main/resources/application.yml
index 6c197a08..8fbb3389 100644
--- a/zlt-demo/seata-demo/business-service/src/main/resources/application.yml
+++ b/zlt-demo/seata-demo/business-service/src/main/resources/application.yml
@@ -1,6 +1,16 @@
-spring:
- cloud:
- alibaba:
- seata:
- # seata 服务分组,要与服务端nacos-config.txt中service.vgroup_mapping的后缀对应,默认是${spring.application.name}-fescar-service-group
- tx-service-group: business-service-group
\ No newline at end of file
+seata:
+ tx-service-group: test_tx_service_group
+ config:
+ type: nacos
+ nacos:
+ serverAddr: ${spring.cloud.nacos.server-addr}
+ group: SEATA_GROUP
+ username: nacos
+ password: nacos
+ registry:
+ type: nacos
+ nacos:
+ server-addr: ${spring.cloud.nacos.server-addr}
+ group: SEATA_GROUP
+ username: nacos
+ password: nacos
\ No newline at end of file
diff --git a/zlt-demo/seata-demo/business-service/src/main/resources/bootstrap.yml b/zlt-demo/seata-demo/business-service/src/main/resources/bootstrap.yml
index 8196da7a..722d9145 100644
--- a/zlt-demo/seata-demo/business-service/src/main/resources/bootstrap.yml
+++ b/zlt-demo/seata-demo/business-service/src/main/resources/bootstrap.yml
@@ -4,7 +4,15 @@ server:
spring:
application:
name: business-service
+ main:
+ allow-bean-definition-overriding: true
cloud:
nacos:
- discovery:
- server-addr: 192.168.28.130:8848
\ No newline at end of file
+ server-addr: 192.168.28.130:8848
+ username: nacos
+ password: nacos
+
+ribbon:
+ ConnectTimeout: 100000
+ ReadTimeout: 1000000
+ OkToRetryOnAllOperations: false
\ No newline at end of file
diff --git a/zlt-demo/seata-demo/business-service/src/main/resources/registry.conf b/zlt-demo/seata-demo/business-service/src/main/resources/registry.conf
deleted file mode 100644
index 96c107da..00000000
--- a/zlt-demo/seata-demo/business-service/src/main/resources/registry.conf
+++ /dev/null
@@ -1,26 +0,0 @@
-registry {
- # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
- type = "nacos"
-
- nacos {
- serverAddr = "192.168.28.130"
- namespace = "public"
- cluster = "default"
- }
- file {
- name = "file.conf"
- }
-}
-config {
- # file、nacos 、apollo、zk、consul、etcd3
- type = "nacos"
- nacos {
- serverAddr = "192.168.28.130"
- namespace = "public"
- cluster = "default"
- }
- file {
- name = "file.conf"
- }
-}
-
diff --git a/zlt-demo/seata-demo/order-service/pom.xml b/zlt-demo/seata-demo/order-service/pom.xml
index 57d829fc..230e9cba 100644
--- a/zlt-demo/seata-demo/order-service/pom.xml
+++ b/zlt-demo/seata-demo/order-service/pom.xml
@@ -5,7 +5,7 @@
com.zlt
seata-demo
- 3.5.0
+ 5.3.0
order-service
@@ -17,7 +17,7 @@
com.zlt
- zlt-ribbon-spring-boot-starter
+ zlt-loadbalancer-spring-boot-starter
org.springframework.boot
diff --git a/zlt-demo/seata-demo/order-service/src/main/resources/application.yml b/zlt-demo/seata-demo/order-service/src/main/resources/application.yml
index 857eb806..1f7f5a96 100644
--- a/zlt-demo/seata-demo/order-service/src/main/resources/application.yml
+++ b/zlt-demo/seata-demo/order-service/src/main/resources/application.yml
@@ -4,8 +4,20 @@ spring:
username: root
password: 1q2w3e4r
driver-class-name: com.mysql.cj.jdbc.Driver
- cloud:
- alibaba:
- seata:
- # seata 服务分组,要与服务端nacos-config.txt中service.vgroup_mapping的后缀对应,默认是${spring.application.name}-fescar-service-group
- tx-service-group: order-service-group
\ No newline at end of file
+
+seata:
+ tx-service-group: test_tx_service_group
+ config:
+ type: nacos
+ nacos:
+ serverAddr: ${spring.cloud.nacos.server-addr}
+ group: SEATA_GROUP
+ username: nacos
+ password: nacos
+ registry:
+ type: nacos
+ nacos:
+ server-addr: ${spring.cloud.nacos.server-addr}
+ group: SEATA_GROUP
+ username: nacos
+ password: nacos
\ No newline at end of file
diff --git a/zlt-demo/seata-demo/order-service/src/main/resources/bootstrap.yml b/zlt-demo/seata-demo/order-service/src/main/resources/bootstrap.yml
index a4fe7107..13799e00 100644
--- a/zlt-demo/seata-demo/order-service/src/main/resources/bootstrap.yml
+++ b/zlt-demo/seata-demo/order-service/src/main/resources/bootstrap.yml
@@ -4,7 +4,10 @@ server:
spring:
application:
name: order-service
+ main:
+ allow-bean-definition-overriding: true
cloud:
nacos:
- discovery:
- server-addr: 192.168.28.130:8848
\ No newline at end of file
+ server-addr: 192.168.28.130:8848
+ username: nacos
+ password: nacos
\ No newline at end of file
diff --git a/zlt-demo/seata-demo/order-service/src/main/resources/registry.conf b/zlt-demo/seata-demo/order-service/src/main/resources/registry.conf
deleted file mode 100644
index 96c107da..00000000
--- a/zlt-demo/seata-demo/order-service/src/main/resources/registry.conf
+++ /dev/null
@@ -1,26 +0,0 @@
-registry {
- # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
- type = "nacos"
-
- nacos {
- serverAddr = "192.168.28.130"
- namespace = "public"
- cluster = "default"
- }
- file {
- name = "file.conf"
- }
-}
-config {
- # file、nacos 、apollo、zk、consul、etcd3
- type = "nacos"
- nacos {
- serverAddr = "192.168.28.130"
- namespace = "public"
- cluster = "default"
- }
- file {
- name = "file.conf"
- }
-}
-
diff --git a/zlt-demo/seata-demo/pom.xml b/zlt-demo/seata-demo/pom.xml
index aa5a8b31..0a9ced3a 100644
--- a/zlt-demo/seata-demo/pom.xml
+++ b/zlt-demo/seata-demo/pom.xml
@@ -4,11 +4,22 @@
com.zlt
zlt-demo
- 3.5.0
+ 5.3.0
seata-demo
seata分布式事务demo
pom
+
+
+
+
+ io.seata
+ seata-spring-boot-starter
+ 1.3.0
+
+
+
+
business-service
diff --git a/zlt-demo/seata-demo/seata-common-starter/pom.xml b/zlt-demo/seata-demo/seata-common-starter/pom.xml
index 7a8299b5..0a82b22d 100644
--- a/zlt-demo/seata-demo/seata-common-starter/pom.xml
+++ b/zlt-demo/seata-demo/seata-common-starter/pom.xml
@@ -5,7 +5,7 @@
com.zlt
seata-demo
- 3.5.0
+ 5.3.0
seata-common-starter
diff --git a/zlt-demo/seata-demo/seata-demo.sql b/zlt-demo/seata-demo/seata-demo.sql
index 8e5d80ec..cd9719ec 100644
--- a/zlt-demo/seata-demo/seata-demo.sql
+++ b/zlt-demo/seata-demo/seata-demo.sql
@@ -8,7 +8,7 @@ USE `seata-demo`;
-- you must to init this sql for you business databese. the seata server not need it.
-- 此脚本必须初始化在你当前的业务数据库中,用于AT 模式XID记录。与server端无关(注:业务数据库)
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
-drop table `undo_log`;
+DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
diff --git a/zlt-demo/seata-demo/storage-service/pom.xml b/zlt-demo/seata-demo/storage-service/pom.xml
index dc4882df..2a524d5c 100644
--- a/zlt-demo/seata-demo/storage-service/pom.xml
+++ b/zlt-demo/seata-demo/storage-service/pom.xml
@@ -5,7 +5,7 @@
com.zlt
seata-demo
- 3.5.0
+ 5.3.0
storage-service
@@ -17,7 +17,7 @@
com.zlt
- zlt-ribbon-spring-boot-starter
+ zlt-loadbalancer-spring-boot-starter
org.springframework.boot
diff --git a/zlt-demo/seata-demo/storage-service/src/main/resources/application.yml b/zlt-demo/seata-demo/storage-service/src/main/resources/application.yml
index ec287685..1f7f5a96 100644
--- a/zlt-demo/seata-demo/storage-service/src/main/resources/application.yml
+++ b/zlt-demo/seata-demo/storage-service/src/main/resources/application.yml
@@ -4,8 +4,20 @@ spring:
username: root
password: 1q2w3e4r
driver-class-name: com.mysql.cj.jdbc.Driver
- cloud:
- alibaba:
- seata:
- # seata 服务分组,要与服务端nacos-config.txt中service.vgroup_mapping的后缀对应,默认是${spring.application.name}-fescar-service-group
- tx-service-group: storage-service-group
\ No newline at end of file
+
+seata:
+ tx-service-group: test_tx_service_group
+ config:
+ type: nacos
+ nacos:
+ serverAddr: ${spring.cloud.nacos.server-addr}
+ group: SEATA_GROUP
+ username: nacos
+ password: nacos
+ registry:
+ type: nacos
+ nacos:
+ server-addr: ${spring.cloud.nacos.server-addr}
+ group: SEATA_GROUP
+ username: nacos
+ password: nacos
\ No newline at end of file
diff --git a/zlt-demo/seata-demo/storage-service/src/main/resources/bootstrap.yml b/zlt-demo/seata-demo/storage-service/src/main/resources/bootstrap.yml
index 5de51a8c..d1db4cde 100644
--- a/zlt-demo/seata-demo/storage-service/src/main/resources/bootstrap.yml
+++ b/zlt-demo/seata-demo/storage-service/src/main/resources/bootstrap.yml
@@ -4,7 +4,10 @@ server:
spring:
application:
name: storage-service
+ main:
+ allow-bean-definition-overriding: true
cloud:
nacos:
- discovery:
- server-addr: 192.168.28.130:8848
\ No newline at end of file
+ server-addr: 192.168.28.130:8848
+ username: nacos
+ password: nacos
\ No newline at end of file
diff --git a/zlt-demo/seata-demo/storage-service/src/main/resources/registry.conf b/zlt-demo/seata-demo/storage-service/src/main/resources/registry.conf
deleted file mode 100644
index 96c107da..00000000
--- a/zlt-demo/seata-demo/storage-service/src/main/resources/registry.conf
+++ /dev/null
@@ -1,26 +0,0 @@
-registry {
- # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
- type = "nacos"
-
- nacos {
- serverAddr = "192.168.28.130"
- namespace = "public"
- cluster = "default"
- }
- file {
- name = "file.conf"
- }
-}
-config {
- # file、nacos 、apollo、zk、consul、etcd3
- type = "nacos"
- nacos {
- serverAddr = "192.168.28.130"
- namespace = "public"
- cluster = "default"
- }
- file {
- name = "file.conf"
- }
-}
-
diff --git a/zlt-demo/sharding-jdbc-demo/pom.xml b/zlt-demo/sharding-jdbc-demo/pom.xml
index 5898abfc..f5781259 100644
--- a/zlt-demo/sharding-jdbc-demo/pom.xml
+++ b/zlt-demo/sharding-jdbc-demo/pom.xml
@@ -4,7 +4,7 @@
com.zlt
zlt-demo
- 3.5.0
+ 5.3.0
sharding-jdbc-demo
sharding-jdbc分库分表demo
diff --git a/zlt-demo/sharding-jdbc-demo/src/main/resources/application.yml b/zlt-demo/sharding-jdbc-demo/src/main/resources/application.yml
index 836cbddc..4701cd57 100644
--- a/zlt-demo/sharding-jdbc-demo/src/main/resources/application.yml
+++ b/zlt-demo/sharding-jdbc-demo/src/main/resources/application.yml
@@ -6,10 +6,12 @@ spring:
active: sharding-databases
application:
name: sharding-jdbc-demo
+ main:
+ allow-bean-definition-overriding: true
zlt:
datasource:
- ip: 192.168.28.131
+ ip: 192.168.28.130
username: root
password: 1q2w3e4r
diff --git a/zlt-demo/sso-demo/README.md b/zlt-demo/sso-demo/README.md
index bc41b6ec..05d8ba7d 100644
--- a/zlt-demo/sso-demo/README.md
+++ b/zlt-demo/sso-demo/README.md
@@ -1,4 +1,4 @@
* **ss-sso**:使用springSecurity来实现自动单点登录,非前后端分离
-
-* **web-sso**:前后端分离的单点登录
+* **web-sso**:前后端分离的单点登录与单点登出
+* **oidc-sso**:拥有独立用户体系的系统,使用OIDC协议的单点登录与单点登出
diff --git a/zlt-demo/sso-demo/oidc-sso/README.md b/zlt-demo/sso-demo/oidc-sso/README.md
new file mode 100644
index 00000000..672698d8
--- /dev/null
+++ b/zlt-demo/sso-demo/oidc-sso/README.md
@@ -0,0 +1,34 @@
+## **详细的原理和注意事项请查看**
+- [OIDC协议单点登录](https://www.kancloud.cn/zlt2000/microservices-platform/2278851)
+
+- [单点登出详解](https://www.kancloud.cn/zlt2000/microservices-platform/2539642)
+
+
+
+## oauth-center数据库执行以下sql
+```sql
+alter table oauth_client_details add support_id_token tinyint(1) DEFAULT 1 COMMENT '是否支持id_token';
+alter table oauth_client_details add id_token_validity int(11) DEFAULT 60 COMMENT 'id_token有效期';
+
+update oauth_client_details set additional_information = '{"LOGOUT_NOTIFY_URL_LIST":"http://127.0.0.1:8082/logoutNotify"}'
+where client_id = 'webApp';
+```
+
+## 启动以下服务
+
+1. zlt-uaa:统一认证中心
+2. user-center:用户服务
+3. sc-gateway:api网关
+4. oidc-sso:单点登录demo(webApp应用)
+5. web-sso:单点登录demo(app应用)
+
+
+
+## 测试步骤
+
+1. 登录app应用:
+ 通过地址 http://127.0.0.1:8081 先登录app应用
+2. 访问app应用(单点成功):
+ 在浏览器打开一个新的页签(共享session),通过地址 http://127.0.0.1:8082/ 访问webApp应用,单点登录成功显示当前登录用户名、应用id、token信息
+3. 再次切换回app应用 http://127.0.0.1:8081 页面点击登出按钮,登出app应用
+4. 回来webApp应用 http://127.0.0.1:8082 刷新页面,返回登录页面(单点登出成功)
\ No newline at end of file
diff --git a/zlt-demo/sso-demo/oidc-sso/pom.xml b/zlt-demo/sso-demo/oidc-sso/pom.xml
new file mode 100644
index 00000000..fd756698
--- /dev/null
+++ b/zlt-demo/sso-demo/oidc-sso/pom.xml
@@ -0,0 +1,50 @@
+
+ 4.0.0
+
+ com.zlt
+ sso-demo
+ 5.3.0
+
+ oidc-sso
+ OIDC协议单点登录demo
+
+
+
+ cn.hutool
+ hutool-all
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.cloud
+ spring-cloud-context
+
+
+ com.zlt
+ zlt-common-core
+
+
+ org.springframework.security
+ spring-security-jwt
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/zlt-demo/sso-demo/oidc-sso/src/main/java/com/sso/demo/OidcSSOApplication.java b/zlt-demo/sso-demo/oidc-sso/src/main/java/com/sso/demo/OidcSSOApplication.java
new file mode 100644
index 00000000..1b5b01d8
--- /dev/null
+++ b/zlt-demo/sso-demo/oidc-sso/src/main/java/com/sso/demo/OidcSSOApplication.java
@@ -0,0 +1,18 @@
+package com.sso.demo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author zlt
+ * @date 2020/5/22
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@SpringBootApplication
+public class OidcSSOApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(OidcSSOApplication.class, args);
+ }
+}
diff --git a/zlt-demo/sso-demo/oidc-sso/src/main/java/com/sso/demo/controller/ApiController.java b/zlt-demo/sso-demo/oidc-sso/src/main/java/com/sso/demo/controller/ApiController.java
new file mode 100644
index 00000000..74103b05
--- /dev/null
+++ b/zlt-demo/sso-demo/oidc-sso/src/main/java/com/sso/demo/controller/ApiController.java
@@ -0,0 +1,231 @@
+package com.sso.demo.controller;
+
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import com.central.common.model.Result;
+import com.central.common.utils.JsonUtil;
+import com.central.common.utils.RsaUtils;
+import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.*;
+import org.springframework.security.jwt.Jwt;
+import org.springframework.security.jwt.JwtHelper;
+import org.springframework.security.jwt.crypto.sign.RsaVerifier;
+import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
+import org.springframework.util.Assert;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+import sun.misc.BASE64Encoder;
+
+import javax.servlet.http.HttpServletRequest;
+import java.nio.charset.StandardCharsets;
+import java.security.interfaces.RSAPublicKey;
+import java.util.*;
+
+/**
+ * @author zlt
+ * @date 2020/5/22
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Slf4j
+@RestController
+public class ApiController {
+ private static final String PUBKEY_START = "-----BEGIN PUBLIC KEY-----";
+ private static final String PUBKEY_END = "-----END PUBLIC KEY-----";
+
+ @Value("${zlt.sso.client-id:}")
+ private String clientId;
+
+ @Value("${zlt.sso.client-secret:}")
+ private String clientSecret;
+
+ @Value("${zlt.sso.redirect-uri:}")
+ private String redirectUri;
+
+ @Value("${zlt.sso.access-token-uri:}")
+ private String accessTokenUri;
+
+ @Value("${zlt.sso.jwt-key-uri:}")
+ private String jwtKeyUri;
+
+ /**
+ * 公钥
+ */
+ private static RSAPublicKey publicKey;
+
+ /**
+ * 模拟用户数据库
+ */
+ private static final Map userDb = new HashMap<>();
+
+ /**
+ * nonce存储
+ */
+ private final static ThreadLocal NONCE = new ThreadLocal<>();
+
+ private final static Map localTokenMap = new HashMap<>();
+
+ @GetMapping("/token/{code}")
+ public Map tokenInfo(@PathVariable String code) throws Exception {
+ //获取token
+ Map tokenMap = getAccessToken(code);
+ String idTokenStr = (String)tokenMap.get("id_token");
+ //解析id_token
+ JsonNode idToken = this.getIdTokenJson(idTokenStr);
+ //检查id_token的有效性
+ checkToken(idToken);
+ //获取用户信息
+ MyUser user = this.getUserInfo(idToken);
+ //判断用户信息是否存在,否则注册用户信息
+ if (!userDb.containsKey(user.getId())) {
+ userDb.put(user.getId(), user);
+ }
+ String accessToken = (String)tokenMap.get("access_token");
+ localTokenMap.put(accessToken, user);
+
+ Map result = new HashMap<>(2);
+ result.put("tokenInfo", tokenMap);
+ result.put("userInfo", user);
+ return result;
+ }
+
+ @GetMapping("/logoutNotify")
+ public void logoutNotify(HttpServletRequest request) {
+ String tokens = request.getParameter("tokens");
+ log.info("=====logoutNotify: " + tokens);
+ if (StrUtil.isNotEmpty(tokens)) {
+ for (String accessToken : tokens.split(",")) {
+ localTokenMap.remove(accessToken);
+ }
+ }
+ }
+
+ @GetMapping("/user")
+ public MyUser user(HttpServletRequest request) {
+ String token = request.getParameter("access_token");
+ return localTokenMap.get(token);
+ }
+
+ /**
+ * 检查 id_token 的有效性
+ */
+ private void checkToken(JsonNode idToken) {
+ //token有效期
+ long expiresAt = idToken.get("exp").asLong();
+ long now = System.currentTimeMillis();
+ Assert.isTrue((expiresAt > now), "id_token已过期");
+
+ //应用id
+ String aud = idToken.get("aud").asText();
+ Assert.isTrue(clientId.equals(aud), "非法应用"+aud);
+
+ //随机码
+ String nonce = idToken.get("nonce").asText();
+ Assert.isTrue((StrUtil.isEmpty(nonce) || nonce.equals(NONCE.get())), "nonce参数无效");
+ }
+
+ /**
+ * 获取token
+ */
+ public Map getAccessToken(String code) {
+ RestTemplate restTemplate = new RestTemplate();
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ String base64Auth = this.getBase64ClientParam();
+ headers.add("Authorization", "Basic " + base64Auth);
+
+ MultiValueMap param = new LinkedMultiValueMap<>();
+ param.add("code", code);
+ param.add("grant_type", "authorization_code");
+ param.add("redirect_uri", redirectUri);
+ param.add("scope", "all");
+ param.add("nonce", this.genNonce());
+ HttpEntity> request = new HttpEntity<>(param, headers);
+ ResponseEntity response = restTemplate.postForEntity(accessTokenUri, request , Map.class);
+ return response.getBody();
+ }
+
+ private String genNonce() {
+ String nonce = RandomUtil.randomString(6);
+ NONCE.set(nonce);
+ return nonce;
+ }
+
+ /**
+ * 把 id_token 字符串解析为json对象
+ */
+ public JsonNode getIdTokenJson(String idToken) throws Exception {
+ RSAPublicKey publicKey = getPubKeyObj();
+ return this.decodeAndVerify(idToken, publicKey);
+ }
+
+ /**
+ * 通过 id_token 获取用户信息
+ */
+ public MyUser getUserInfo(JsonNode idToken) {
+ MyUser user = new MyUser();
+ user.setId(Long.valueOf(idToken.get("sub").textValue()));
+ user.setName(idToken.get("name").textValue());
+ user.setLoginName(idToken.get("login_name").textValue());
+ user.setPicture(idToken.get("picture").textValue());
+ return user;
+ }
+
+ private JsonNode decodeAndVerify(String jwtToken, RSAPublicKey rsaPublicKey) {
+ SignatureVerifier rsaVerifier = new RsaVerifier(rsaPublicKey);
+ Jwt jwt = JwtHelper.decodeAndVerify(jwtToken, rsaVerifier);
+ return JsonUtil.parse(jwt.getClaims());
+ }
+
+ /**
+ * 获取公钥
+ */
+ public RSAPublicKey getPubKeyObj() throws Exception {
+ if (publicKey == null) {
+ publicKey = getPubKeyByRemote();
+ }
+ return publicKey;
+ }
+
+ private RSAPublicKey getPubKeyByRemote() throws Exception {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ String base64Auth = this.getBase64ClientParam();
+ headers.add("Authorization", "Basic " + base64Auth);
+
+ HttpEntity request = new HttpEntity<>(headers);
+ RestTemplate restTemplate = new RestTemplate();
+ ResponseEntity response = restTemplate.exchange(jwtKeyUri, HttpMethod.GET, request, Result.class);
+ Result result = response.getBody();
+ Assert.isTrue((result.getResp_code() == 0), result.getResp_msg());
+
+ String publicKeyStr = result.getResp_msg();
+ publicKeyStr = publicKeyStr.substring(PUBKEY_START.length(), publicKeyStr.indexOf(PUBKEY_END));
+ return RsaUtils.getPublicKey(publicKeyStr);
+ }
+
+ /**
+ * base64加密应用参数
+ */
+ private String getBase64ClientParam() {
+ byte[] authorization = (clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8);
+ BASE64Encoder encoder = new BASE64Encoder();
+ return encoder.encode(authorization);
+ }
+
+ @Data
+ public static class MyUser {
+ private Long id;
+ private String name;
+ private String loginName;
+ private String picture;
+ }
+}
diff --git a/zlt-demo/sso-demo/oidc-sso/src/main/resources/bootstrap.yml b/zlt-demo/sso-demo/oidc-sso/src/main/resources/bootstrap.yml
new file mode 100644
index 00000000..fc4c658e
--- /dev/null
+++ b/zlt-demo/sso-demo/oidc-sso/src/main/resources/bootstrap.yml
@@ -0,0 +1,14 @@
+server:
+ port: 8082
+
+spring:
+ application:
+ name: oidc-demo
+
+zlt:
+ sso:
+ client-id: webApp
+ client-secret: webApp
+ redirect-uri: http://127.0.0.1:8082/callback.html
+ access-token-uri: http://127.0.0.1:9900/api-uaa/oauth/token
+ jwt-key-uri: http://127.0.0.1:9900/api-uaa/tokens/key
\ No newline at end of file
diff --git a/zlt-demo/sso-demo/oidc-sso/src/main/resources/static/callback.html b/zlt-demo/sso-demo/oidc-sso/src/main/resources/static/callback.html
new file mode 100644
index 00000000..f320ba84
--- /dev/null
+++ b/zlt-demo/sso-demo/oidc-sso/src/main/resources/static/callback.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+ zlt
+
+
+
+
+
+
+
diff --git a/zlt-demo/sso-demo/oidc-sso/src/main/resources/static/index.html b/zlt-demo/sso-demo/oidc-sso/src/main/resources/static/index.html
new file mode 100644
index 00000000..8061a116
--- /dev/null
+++ b/zlt-demo/sso-demo/oidc-sso/src/main/resources/static/index.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+ zlt
+
+
+
+
+
+
用户名:
+
登录名:
+
头像:
+
应用id:
+
token:
+
+
+
+
+
diff --git a/zlt-demo/sso-demo/oidc-sso/src/main/resources/static/js/jquery-3.2.1.min.js b/zlt-demo/sso-demo/oidc-sso/src/main/resources/static/js/jquery-3.2.1.min.js
new file mode 100644
index 00000000..644d35e2
--- /dev/null
+++ b/zlt-demo/sso-demo/oidc-sso/src/main/resources/static/js/jquery-3.2.1.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML=" ",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML=" ";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S),
+a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""," "],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/
+
+
用户名:
+
权限:[ ]
应用id:
token:
diff --git a/zlt-demo/sso-demo/web-sso/src/main/resources/static/js/sso.js b/zlt-demo/sso-demo/web-sso/src/main/resources/static/js/sso.js
new file mode 100644
index 00000000..84b7bd8b
--- /dev/null
+++ b/zlt-demo/sso-demo/web-sso/src/main/resources/static/js/sso.js
@@ -0,0 +1,38 @@
+const FULL_CHARTER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopgrstuvwxyz';
+//应用id
+let clientId = 'app';
+//授权中心地址
+let uaaUri = 'http://127.0.0.1:9900/api-uaa/oauth/';
+
+function getAuthorizeUri(state) {
+ return uaaUri+'authorize?client_id='+clientId+'&redirect_uri=http://127.0.0.1:8081/callback.html&response_type=code&state='+state;
+}
+
+function getLogoutUri(accessToken) {
+ return uaaUri+'remove/token?redirect_uri=http://127.0.0.1:8081/index.html&access_token='+accessToken;
+}
+
+function getUserInfo(accessToken) {
+ return 'http://127.0.0.1:8081/user?access_token='+accessToken;
+}
+
+function getState() {
+ let state='';
+ for (let i = 0; i < 6; i++) {
+ state += FULL_CHARTER[Math.floor(Math.random() * 52)];
+ }
+ return state;
+}
+
+/**
+ * 获取url参数
+ */
+function getQueryVariable(variable) {
+ var query = window.location.search.substring(1);
+ var vars = query.split("&");
+ for (var i=0;i
com.zlt
zlt-demo
- 3.5.0
+ 5.3.0
txlcn-demo
txlcn分布式事务demo
diff --git a/zlt-demo/txlcn-demo/txlcn-demo-common/pom.xml b/zlt-demo/txlcn-demo/txlcn-demo-common/pom.xml
index 6c607a62..72ac8d04 100644
--- a/zlt-demo/txlcn-demo/txlcn-demo-common/pom.xml
+++ b/zlt-demo/txlcn-demo/txlcn-demo-common/pom.xml
@@ -4,7 +4,7 @@
com.zlt
txlcn-demo
- 3.5.0
+ 5.3.0
txlcn-demo-common
demo-common
@@ -40,7 +40,7 @@
com.zlt
- zlt-ribbon-spring-boot-starter
+ zlt-loadbalancer-spring-boot-starter
com.zlt
diff --git a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-a/pom.xml b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-a/pom.xml
index 75bf4c78..bff2f2d7 100644
--- a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-a/pom.xml
+++ b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-a/pom.xml
@@ -3,7 +3,7 @@
com.zlt
txlcn-demo
- 3.5.0
+ 5.3.0
4.0.0
diff --git a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-a/src/main/resources/application.yml b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-a/src/main/resources/application.yml
index cd402049..7133edbd 100644
--- a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-a/src/main/resources/application.yml
+++ b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-a/src/main/resources/application.yml
@@ -16,4 +16,10 @@ tx-lcn:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://${zlt.datasource.ip}:3306/tx_logger?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
username: ${zlt.datasource.username}
- password: ${zlt.datasource.password}
\ No newline at end of file
+ password: ${zlt.datasource.password}
+zlt:
+ loadbalance:
+ version: test
+ isolation:
+ enabled: true
+ chooser: com.central.common.lb.chooser.RandomRuleChooser
diff --git a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-b/pom.xml b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-b/pom.xml
index b88ac6ab..8877bd4e 100644
--- a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-b/pom.xml
+++ b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-b/pom.xml
@@ -3,7 +3,7 @@
com.zlt
txlcn-demo
- 3.5.0
+ 5.3.0
4.0.0
txlcn-demo-spring-service-b
diff --git a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-b/src/main/resources/application.yml b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-b/src/main/resources/application.yml
index cd402049..68d7e81d 100644
--- a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-b/src/main/resources/application.yml
+++ b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-b/src/main/resources/application.yml
@@ -16,4 +16,9 @@ tx-lcn:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://${zlt.datasource.ip}:3306/tx_logger?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
username: ${zlt.datasource.username}
- password: ${zlt.datasource.password}
\ No newline at end of file
+ password: ${zlt.datasource.password}
+zlt:
+ loadbalance:
+ version: test
+ isolation:
+ enabled: true
\ No newline at end of file
diff --git a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-c/pom.xml b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-c/pom.xml
index 6d9c49ab..ee7f3671 100644
--- a/zlt-demo/txlcn-demo/txlcn-demo-spring-service-c/pom.xml
+++ b/zlt-demo/txlcn-demo/txlcn-demo-spring-service-c/pom.xml
@@ -3,7 +3,7 @@
com.zlt
txlcn-demo
- 3.5.0
+ 5.3.0
4.0.0
txlcn-demo-spring-service-c
diff --git a/zlt-doc/Dockerfile b/zlt-doc/Dockerfile
new file mode 100644
index 00000000..c04c805e
--- /dev/null
+++ b/zlt-doc/Dockerfile
@@ -0,0 +1,6 @@
+FROM mysql:5.7
+
+LABEL MAINTAINER=Andy
+
+COPY sql/*.sql /docker-entrypoint-initdb.d/
+# docker run --name zlt-db -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=test -d zlt-db:mysql-8.0.25
\ No newline at end of file
diff --git a/zlt-doc/sql/oauth-center.sql b/zlt-doc/sql/oauth-center.sql
index 6ed53f27..6405352c 100644
--- a/zlt-doc/sql/oauth-center.sql
+++ b/zlt-doc/sql/oauth-center.sql
@@ -18,16 +18,18 @@ CREATE TABLE `oauth_client_details` (
`access_token_validity` int(11) NULL DEFAULT NULL COMMENT 'access_token有效期',
`refresh_token_validity` int(11) NULL DEFAULT NULL COMMENT 'refresh_token有效期',
`additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '{}' COMMENT '{}',
- `autoapprove` char(4) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'true' COMMENT '是否自动授权 是-true',
+ `autoapprove` char(5) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'true' COMMENT '是否自动授权 是-true',
`create_time` datetime(0) NULL DEFAULT NULL,
`update_time` datetime(0) NULL DEFAULT NULL,
`client_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '应用名称',
+ `support_id_token` tinyint(1) DEFAULT 1 COMMENT '是否支持id_token',
+ `id_token_validity` int(11) DEFAULT 60 COMMENT 'id_token有效期',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of oauth_client_details
-- ----------------------------
-INSERT INTO `oauth_client_details` VALUES (1, 'webApp', NULL, '$2a$10$06msMGYRH8nrm4iVnKFNKOoddB8wOwymVhbUzw/d3ZixD7Nq8ot72', 'webApp', 'app', 'authorization_code,password,refresh_token,client_credentials', NULL, NULL, 3600, NULL, '{}', 'true', NULL, NULL, 'pc端');
-INSERT INTO `oauth_client_details` VALUES (2, 'app', NULL, '$2a$10$i3F515wEDiB4Gvj9ym9Prui0dasRttEUQ9ink4Wpgb4zEDCAlV8zO', 'app', 'app', 'authorization_code,password,refresh_token', 'http://127.0.0.1:8081/callback.html', NULL, 3600, NULL, '{}', 'true', NULL, NULL, '移动端');
-INSERT INTO `oauth_client_details` VALUES (3, 'zlt', NULL, '$2a$10$/o.wuORzVcXaezmYVzwYMuoY7qeWXBALwQmkskXD/7C6rqfCyPrna', 'zlt', 'all', 'authorization_code,password,refresh_token,client_credentials', 'http://127.0.0.1:8080/singleLogin', NULL, 3600, 28800, '{}', 'true', '2018-12-27 00:50:30', '2018-12-27 00:50:30', '第三方应用');
\ No newline at end of file
+INSERT INTO `oauth_client_details` VALUES (1, 'webApp', NULL, '$2a$10$06msMGYRH8nrm4iVnKFNKOoddB8wOwymVhbUzw/d3ZixD7Nq8ot72', 'webApp', 'app', 'authorization_code,password,refresh_token,client_credentials,implicit,password_code,openId,mobile_password', NULL, NULL, 3600, NULL, '{"LOGOUT_NOTIFY_URL_LIST":"http://127.0.0.1:8082/logoutNotify"}', 'true', NULL, NULL, 'pc端', 1, 60);
+INSERT INTO `oauth_client_details` VALUES (2, 'app', NULL, '$2a$10$i3F515wEDiB4Gvj9ym9Prui0dasRttEUQ9ink4Wpgb4zEDCAlV8zO', 'app', 'app', 'authorization_code,password,refresh_token', 'http://127.0.0.1:8081/callback.html', NULL, 3600, NULL, '{"LOGOUT_NOTIFY_URL_LIST":"http://127.0.0.1:8081/logoutNotify"}', 'true', NULL, NULL, '移动端', 1, 60);
+INSERT INTO `oauth_client_details` VALUES (3, 'zlt', NULL, '$2a$10$/o.wuORzVcXaezmYVzwYMuoY7qeWXBALwQmkskXD/7C6rqfCyPrna', 'zlt', 'all', 'authorization_code,password,refresh_token,client_credentials', 'http://127.0.0.1:8080/singleLogin', NULL, 3600, 28800, '{}', 'true', '2018-12-27 00:50:30', '2018-12-27 00:50:30', '第三方应用', 1, 60);
\ No newline at end of file
diff --git a/zlt-doc/sql/user-center.sql b/zlt-doc/sql/user-center.sql
index f908c667..9a48ed22 100644
--- a/zlt-doc/sql/user-center.sql
+++ b/zlt-doc/sql/user-center.sql
@@ -8,7 +8,7 @@ DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
- `password` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+ `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登录密码',
`nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`head_img_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`mobile` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
@@ -123,7 +123,7 @@ INSERT INTO `sys_menu` VALUES (2, 12, '用户管理', '#!user', 'system/user.htm
INSERT INTO `sys_menu` VALUES (3, 12, '角色管理', '#!role', 'system/role.html', NULL, 'layui-icon-user', 3, '2017-11-17 16:56:59', '2019-01-14 15:34:40', 1, 0, 'webApp');
INSERT INTO `sys_menu` VALUES (4, 12, '菜单管理', '#!menus', 'system/menus.html', NULL, 'layui-icon-menu-fill', 4, '2017-11-17 16:56:59', '2018-09-03 02:23:47', 1, 0, 'webApp');
INSERT INTO `sys_menu` VALUES (9, 37, '文件中心', '#!files', 'files/files.html', NULL, 'layui-icon-file', 3, '2017-11-17 16:56:59', '2019-01-17 20:18:44', 1, 0, 'webApp');
-INSERT INTO `sys_menu` VALUES (10, 37, '文档中心', '#!swagger', 'http://127.0.0.1:9900/swagger-ui.html', NULL, 'layui-icon-app', 4, '2017-11-17 16:56:59', '2019-01-17 20:18:48', 1, 0, 'webApp');
+INSERT INTO `sys_menu` VALUES (10, 37, '文档中心', '#!swagger', 'http://127.0.0.1:9900/doc.html', NULL, 'layui-icon-app', 4, '2017-11-17 16:56:59', '2019-01-17 20:18:48', 1, 0, 'webApp');
INSERT INTO `sys_menu` VALUES (11, 12, '我的信息', '#!myInfo', 'system/myInfo.html', NULL, 'layui-icon-login-qq', 10, '2017-11-17 16:56:59', '2018-09-02 06:12:24', 1, 0, 'webApp');
INSERT INTO `sys_menu` VALUES (12, -1, '认证管理', 'javascript:;', '', NULL, 'layui-icon-set', 1, '2017-11-17 16:56:59', '2018-12-13 15:02:49', 1, 0, 'webApp');
INSERT INTO `sys_menu` VALUES (35, 12, '应用管理', '#!app', 'attestation/app.html', NULL, 'layui-icon-link', 5, '2017-11-17 16:56:59', '2019-01-14 15:35:15', 1, 0, 'webApp');
diff --git a/zlt-doc/sql/xxl-job.sql b/zlt-doc/sql/xxl-job.sql
index 8013eb8b..8dba4f52 100644
--- a/zlt-doc/sql/xxl-job.sql
+++ b/zlt-doc/sql/xxl-job.sql
@@ -211,7 +211,7 @@ DROP TABLE IF EXISTS `XXL_JOB_QRTZ_TRIGGER_GROUP`;
CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_GROUP` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`app_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '执行器AppName',
- `title` varchar(12) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '执行器名称',
+ `title` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '执行器名称',
`order` tinyint(4) NOT NULL DEFAULT 0 COMMENT '排序',
`address_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '执行器地址类型:0=自动注册、1=手动录入',
`address_list` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '执行器地址列表,多地址逗号分隔',
diff --git "a/zlt-doc/\347\211\210\346\234\254\345\215\207\347\272\247_sql/\346\227\247\347\211\210\346\234\254\345\215\207\347\272\247v4.0.0.sql" "b/zlt-doc/\347\211\210\346\234\254\345\215\207\347\272\247_sql/\346\227\247\347\211\210\346\234\254\345\215\207\347\272\247v4.0.0.sql"
new file mode 100644
index 00000000..438dd892
--- /dev/null
+++ "b/zlt-doc/\347\211\210\346\234\254\345\215\207\347\272\247_sql/\346\227\247\347\211\210\346\234\254\345\215\207\347\272\247v4.0.0.sql"
@@ -0,0 +1,3 @@
+------------更新语句
+Use `oauth-center`;
+update oauth_client_details set authorized_grant_types = 'authorization_code,password,refresh_token,client_credentials,implicit,password_code,openId,mobile_password' where client_id = 'webApp'
\ No newline at end of file
diff --git "a/zlt-doc/\347\211\210\346\234\254\345\215\207\347\272\247_sql/\346\227\247\347\211\210\346\234\254\345\215\207\347\272\247v4.5.0.sql" "b/zlt-doc/\347\211\210\346\234\254\345\215\207\347\272\247_sql/\346\227\247\347\211\210\346\234\254\345\215\207\347\272\247v4.5.0.sql"
new file mode 100644
index 00000000..f4384603
--- /dev/null
+++ "b/zlt-doc/\347\211\210\346\234\254\345\215\207\347\272\247_sql/\346\227\247\347\211\210\346\234\254\345\215\207\347\272\247v4.5.0.sql"
@@ -0,0 +1,7 @@
+------------更新语句
+Use `oauth-center`;
+alter table oauth_client_details add support_id_token tinyint(1) DEFAULT 1 COMMENT '是否支持id_token';
+alter table oauth_client_details add id_token_validity int(11) DEFAULT 60 COMMENT 'id_token有效期';
+
+Use `user-center`;
+alter table `sys_user` MODIFY COLUMN `password` varchar(100) NOT NULL COMMENT '登录密码';
diff --git "a/zlt-doc/\347\211\210\346\234\254\345\215\207\347\272\247_sql/\346\227\247\347\211\210\346\234\254\345\215\207\347\272\247v5.1.0.sql" "b/zlt-doc/\347\211\210\346\234\254\345\215\207\347\272\247_sql/\346\227\247\347\211\210\346\234\254\345\215\207\347\272\247v5.1.0.sql"
new file mode 100644
index 00000000..b86bae45
--- /dev/null
+++ "b/zlt-doc/\347\211\210\346\234\254\345\215\207\347\272\247_sql/\346\227\247\347\211\210\346\234\254\345\215\207\347\272\247v5.1.0.sql"
@@ -0,0 +1,7 @@
+------------更新语句
+Use `oauth-center`;
+update oauth_client_details set additional_information = '{"LOGOUT_NOTIFY_URL_LIST":"http://127.0.0.1:8082/logoutNotify"}'
+where client_id = 'webApp';
+
+update oauth_client_details set additional_information = '{"LOGOUT_NOTIFY_URL_LIST":"http://127.0.0.1:8081/logoutNotify"}'
+where client_id = 'app';
\ No newline at end of file
diff --git a/zlt-gateway/pom.xml b/zlt-gateway/pom.xml
index b59be40c..e58ce502 100644
--- a/zlt-gateway/pom.xml
+++ b/zlt-gateway/pom.xml
@@ -4,13 +4,11 @@
com.zlt
central-platform
- 3.5.0
+ 5.3.0
zlt-gateway
pom
-
- zuul-gateway
sc-gateway
diff --git a/zlt-gateway/sc-gateway/pom.xml b/zlt-gateway/sc-gateway/pom.xml
index 4f420876..d15fdfd7 100644
--- a/zlt-gateway/sc-gateway/pom.xml
+++ b/zlt-gateway/sc-gateway/pom.xml
@@ -4,7 +4,7 @@
com.zlt
zlt-gateway
- 3.5.0
+ 5.3.0
sc-gateway
spring cloud gateway网关
@@ -16,7 +16,7 @@
com.zlt
- zlt-ribbon-spring-boot-starter
+ zlt-loadbalancer-spring-boot-starter
com.zlt
@@ -30,6 +30,18 @@
com.zlt
zlt-auth-client-spring-boot-starter
+
+
+ com.zlt
+ zlt-redis-spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
org.springframework.cloud
spring-cloud-starter-gateway
@@ -57,17 +69,10 @@
- io.springfox
- springfox-swagger2
-
-
- io.springfox
- springfox-swagger-ui
-
-
- com.zlt
- zlt-redis-spring-boot-starter
+ com.github.xiaoymin
+ knife4j-spring-boot-starter
+
org.springframework.security
spring-security-oauth2-resource-server
@@ -84,6 +89,10 @@
eu.bitwalker
UserAgentUtils
+
+ org.springframework.security.oauth
+ spring-security-oauth2
+
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/SCGatewayApp.java b/zlt-gateway/sc-gateway/src/main/java/com/central/SCGatewayApp.java
index e7d55fed..c2ecc2bd 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/SCGatewayApp.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/SCGatewayApp.java
@@ -1,6 +1,6 @@
package com.central;
-import com.central.common.ribbon.annotation.EnableBaseFeignInterceptor;
+import com.central.common.lb.annotation.EnableBaseFeignInterceptor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@@ -10,7 +10,7 @@
* @author zlt
* @date 2019/10/5
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@EnableFeignClients
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/CustomAuthenticationManager.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/CustomAuthenticationManager.java
index b3f30a07..e2d5019a 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/CustomAuthenticationManager.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/CustomAuthenticationManager.java
@@ -13,7 +13,7 @@
* @author zlt
* @date 2019/10/6
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class CustomAuthenticationManager implements ReactiveAuthenticationManager {
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAccessDeniedHandler.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAccessDeniedHandler.java
index 34076c8e..8a213b8f 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAccessDeniedHandler.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAccessDeniedHandler.java
@@ -1,6 +1,6 @@
package com.central.gateway.auth;
-import com.central.common.utils.ResponseUtil;
+import com.central.common.utils.WebfluxResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
@@ -14,13 +14,13 @@
* @author zlt
* @date 2019/10/7
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
public class JsonAccessDeniedHandler implements ServerAccessDeniedHandler {
@Override
public Mono handle(ServerWebExchange exchange, AccessDeniedException e) {
- return ResponseUtil.responseFailed(exchange, HttpStatus.FORBIDDEN.value(), e.getMessage());
+ return WebfluxResponseUtil.responseFailed(exchange, HttpStatus.FORBIDDEN.value(), e.getMessage());
}
}
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAuthenticationEntryPoint.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAuthenticationEntryPoint.java
index 672580a8..52dddddc 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAuthenticationEntryPoint.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAuthenticationEntryPoint.java
@@ -1,6 +1,6 @@
package com.central.gateway.auth;
-import com.central.common.utils.ResponseUtil;
+import com.central.common.utils.WebfluxResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
@@ -14,13 +14,13 @@
* @author zlt
* @date 2019/10/7
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
public class JsonAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {
@Override
public Mono commence(ServerWebExchange exchange, AuthenticationException e) {
- return ResponseUtil.responseFailed(exchange, HttpStatus.UNAUTHORIZED.value(), e.getMessage());
+ return WebfluxResponseUtil.responseFailed(exchange, HttpStatus.UNAUTHORIZED.value(), e.getMessage());
}
}
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/Oauth2AuthSuccessHandler.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/Oauth2AuthSuccessHandler.java
index 11e57ec3..ea1b1e8f 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/Oauth2AuthSuccessHandler.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/Oauth2AuthSuccessHandler.java
@@ -1,8 +1,10 @@
package com.central.gateway.auth;
import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
import com.central.common.constant.SecurityConstants;
import com.central.common.model.SysUser;
+import com.central.oauth2.common.util.AuthUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
@@ -19,13 +21,13 @@
* @author zlt
* @date 2019/10/7
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class Oauth2AuthSuccessHandler implements ServerAuthenticationSuccessHandler {
@Override
public Mono onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
- MultiValueMap headerValues = new LinkedMultiValueMap(4);
+ MultiValueMap headerValues = new LinkedMultiValueMap<>(4);
Object principal = authentication.getPrincipal();
//客户端模式只返回一个clientId
if (principal instanceof SysUser) {
@@ -37,12 +39,13 @@ public Mono onAuthenticationSuccess(WebFilterExchange webFilterExchange, A
String clientId = oauth2Authentication.getOAuth2Request().getClientId();
headerValues.add(SecurityConstants.TENANT_HEADER, clientId);
headerValues.add(SecurityConstants.ROLE_HEADER, CollectionUtil.join(authentication.getAuthorities(), ","));
-
+ String accountType = AuthUtils.getAccountType(oauth2Authentication.getUserAuthentication());
+ if (StrUtil.isNotEmpty(accountType)) {
+ headerValues.add(SecurityConstants.ACCOUNT_TYPE_HEADER, accountType);
+ }
ServerWebExchange exchange = webFilterExchange.getExchange();
ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate()
- .headers(h -> {
- h.addAll(headerValues);
- })
+ .headers(h -> h.addAll(headerValues))
.build();
ServerWebExchange build = exchange.mutate().request(serverHttpRequest).build();
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/PermissionAuthManager.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/PermissionAuthManager.java
index da4619c2..1afb01b4 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/PermissionAuthManager.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/PermissionAuthManager.java
@@ -1,7 +1,7 @@
package com.central.gateway.auth;
import com.central.common.model.SysMenu;
-import com.central.gateway.feign.MenuService;
+import com.central.gateway.feign.AsynMenuService;
import com.central.oauth2.common.service.impl.DefaultPermissionServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.reactive.ServerHttpRequest;
@@ -14,7 +14,9 @@
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
+import java.util.Collections;
import java.util.List;
+import java.util.concurrent.Future;
/**
* url权限认证
@@ -22,14 +24,14 @@
* @author zlt
* @date 2019/10/6
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
@Component
public class PermissionAuthManager extends DefaultPermissionServiceImpl implements ReactiveAuthorizationManager {
@Resource
- private MenuService menuService;
+ private AsynMenuService asynMenuService;
@Override
public Mono check(Mono authentication, AuthorizationContext authorizationContext) {
@@ -43,6 +45,12 @@ public Mono check(Mono authentication, Au
@Override
public List findMenuByRoleCodes(String roleCodes) {
- return menuService.findByRoleCodes(roleCodes);
+ Future> futureResult = asynMenuService.findByRoleCodes(roleCodes);
+ try {
+ return futureResult.get();
+ } catch (Exception e) {
+ log.error("asynMenuService.findMenuByRoleCodes-error", e);
+ }
+ return Collections.emptyList();
}
-}
+}
\ No newline at end of file
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/AsycTaskExecutorConfig.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/AsycTaskExecutorConfig.java
similarity index 71%
rename from zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/AsycTaskExecutorConfig.java
rename to zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/AsycTaskExecutorConfig.java
index 3a7c9253..49ab7e6d 100644
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/AsycTaskExecutorConfig.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/AsycTaskExecutorConfig.java
@@ -1,14 +1,19 @@
-package com.central.gateway.config;
-
-import com.central.common.config.DefaultAsycTaskConfig;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * @author zlt
- * 线程池配置、启用异步
- * @Async quartz 需要使用
- */
-@Configuration
-public class AsycTaskExecutorConfig extends DefaultAsycTaskConfig {
-
-}
+package com.central.gateway.config;
+
+import com.central.common.config.DefaultAsycTaskConfig;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 线程池配置、启用异步
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/8/8
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Configuration
+public class AsycTaskExecutorConfig extends DefaultAsycTaskConfig {
+
+}
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/CorsConfig.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/CorsConfig.java
index ed033cdc..7e2ea488 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/CorsConfig.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/CorsConfig.java
@@ -2,6 +2,8 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@@ -13,20 +15,21 @@
* @author zlt
* @date 2019/10/5
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Configuration
public class CorsConfig {
private static final String ALL = "*";
+ @Order(Ordered.HIGHEST_PRECEDENCE)
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// cookie跨域
config.setAllowCredentials(Boolean.TRUE);
config.addAllowedMethod(ALL);
- config.addAllowedOrigin(ALL);
+ config.addAllowedOriginPattern(ALL);
config.addAllowedHeader(ALL);
// 配置前端js允许访问的自定义响应头
config.addExposedHeader("setToken");
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/DynamicRouteConfig.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/DynamicRouteConfig.java
index 66330d95..5720d863 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/DynamicRouteConfig.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/DynamicRouteConfig.java
@@ -14,7 +14,7 @@
* @author zlt
* @date 2019/10/7
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Configuration
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/FeignConfig.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/FeignConfig.java
new file mode 100644
index 00000000..9f4d343d
--- /dev/null
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/FeignConfig.java
@@ -0,0 +1,45 @@
+package com.central.gateway.config;
+
+import feign.codec.Decoder;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
+import org.springframework.cloud.openfeign.support.SpringDecoder;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Feign配置类
+ * 配置Feign的Decoder解决在Gateway中使用Feign时报错找不到HttpMessageConverters
+ *
+ * @author zlt
+ * @date 2020/7/26
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Configuration
+public class FeignConfig {
+ @Bean
+ public Decoder feignDecoder() {
+ return new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()));
+ }
+
+ public ObjectFactory feignHttpMessageConverter() {
+ final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(new GateWayMappingJackson2HttpMessageConverter());
+ return () -> httpMessageConverters;
+ }
+
+ public static class GateWayMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
+ GateWayMappingJackson2HttpMessageConverter(){
+ List mediaTypes = new ArrayList<>();
+ mediaTypes.add(MediaType.valueOf(MediaType.TEXT_HTML_VALUE + ";charset=UTF-8"));
+ setSupportedMediaTypes(mediaTypes);
+ }
+ }
+}
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/ResourceServerConfiguration.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/ResourceServerConfiguration.java
index a6792804..e6a95db4 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/ResourceServerConfiguration.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/config/ResourceServerConfiguration.java
@@ -21,7 +21,7 @@
* @author zlt
* @date 2019/10/5
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Configuration
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/CustomErrorWebFluxAutoConfiguration.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/CustomErrorWebFluxAutoConfiguration.java
index d9f0b733..830f33d8 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/CustomErrorWebFluxAutoConfiguration.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/CustomErrorWebFluxAutoConfiguration.java
@@ -28,7 +28,7 @@
* @author zlt
* @date 2020/3/30
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Configuration
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/JsonErrorWebExceptionHandler.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/JsonErrorWebExceptionHandler.java
index 27c64e9d..6cd1101f 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/JsonErrorWebExceptionHandler.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/JsonErrorWebExceptionHandler.java
@@ -3,9 +3,11 @@
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
+import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
+import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.web.reactive.function.server.*;
import java.util.HashMap;
@@ -17,7 +19,7 @@
* @author zlt
* @date 2020/3/30
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class JsonErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler {
@@ -30,9 +32,9 @@ public JsonErrorWebExceptionHandler(ErrorAttributes errorAttributes, ResourcePro
* 获取异常属性
*/
@Override
- protected Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
+ protected Map getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Throwable error = super.getError(request);
- return responseError(this.buildMessage(request, error));
+ return responseError(request, error);
}
/**
@@ -49,8 +51,9 @@ protected RouterFunction getRoutingFunction(ErrorAttributes erro
* @param errorAttributes
*/
@Override
- protected HttpStatus getHttpStatus(Map errorAttributes) {
- return HttpStatus.INTERNAL_SERVER_ERROR;
+ protected int getHttpStatus(Map errorAttributes) {
+ Integer httpStatus = (Integer) errorAttributes.remove("httpStatus");
+ return httpStatus != null ? httpStatus : HttpStatus.INTERNAL_SERVER_ERROR.value();
}
/**
@@ -74,14 +77,26 @@ private String buildMessage(ServerRequest request, Throwable ex) {
/**
* 构建返回的JSON数据格式
- * @param errorMessage 异常信息
- * @return
*/
- public static Map responseError(String errorMessage) {
+ private Map responseError(ServerRequest request, Throwable error) {
+ String errorMessage = buildMessage(request, error);
+ int httpStatus = getHttpStatus(error);
Map map = new HashMap<>();
map.put("resp_code", 1);
map.put("resp_msg", errorMessage);
map.put("datas", null);
+ map.put("httpStatus", httpStatus);
return map;
}
+
+ private int getHttpStatus(Throwable error) {
+ int httpStatus;
+ if (error instanceof InvalidTokenException) {
+ InvalidTokenException ex = (InvalidTokenException)error;
+ httpStatus = ex.getHttpErrorCode();
+ } else {
+ httpStatus = HttpStatus.INTERNAL_SERVER_ERROR.value();
+ }
+ return httpStatus;
+ }
}
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/feign/AsynMenuService.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/feign/AsynMenuService.java
new file mode 100644
index 00000000..b6577abd
--- /dev/null
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/feign/AsynMenuService.java
@@ -0,0 +1,35 @@
+package com.central.gateway.feign;
+
+import com.central.common.model.SysMenu;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.AsyncResult;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.concurrent.Future;
+
+/**
+ * 异步Menu服务
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/8/8
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Component
+public class AsynMenuService {
+ @Lazy
+ @Resource
+ private MenuService menuService;
+
+ @Async
+ public Future> findByRoleCodes(String roleCodes) {
+ List result = menuService.findByRoleCodes(roleCodes);
+ return new AsyncResult<>(result);
+ }
+}
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/feign/fallback/MenuServiceFallbackFactory.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/feign/fallback/MenuServiceFallbackFactory.java
index 90aaa50d..840ae68a 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/feign/fallback/MenuServiceFallbackFactory.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/feign/fallback/MenuServiceFallbackFactory.java
@@ -2,7 +2,7 @@
import cn.hutool.core.collection.CollectionUtil;
import com.central.gateway.feign.MenuService;
-import feign.hystrix.FallbackFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/LbIsolationFilter.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/LbIsolationFilter.java
index 41c201c4..74f964d3 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/LbIsolationFilter.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/LbIsolationFilter.java
@@ -6,9 +6,9 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
-import org.springframework.cloud.gateway.config.LoadBalancerProperties;
+/*import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
-import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
+import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;*/
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
@@ -22,9 +22,10 @@
* @author zlt
* @date 2019/10/7
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
+/*
@Component
@ConditionalOnProperty(name = ConfigConstants.CONFIG_RIBBON_ISOLATION_ENABLED, havingValue = "true")
public class LbIsolationFilter extends LoadBalancerClientFilter {
@@ -45,3 +46,4 @@ protected ServiceInstance choose(ServerWebExchange exchange) {
return super.choose(exchange);
}
}
+*/
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/RequestStatisticsFilter.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/RequestStatisticsFilter.java
index b2f21e4c..ce3e88cb 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/RequestStatisticsFilter.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/RequestStatisticsFilter.java
@@ -20,7 +20,7 @@
* @author zlt
* @date 2019/10/7
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Component
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/TraceFilter.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/TraceFilter.java
index 9f77dee9..89bf0f0b 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/TraceFilter.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/TraceFilter.java
@@ -1,9 +1,7 @@
package com.central.gateway.filter;
-import cn.hutool.core.util.IdUtil;
-import com.central.common.constant.CommonConstant;
import com.central.log.properties.TraceProperties;
-import org.slf4j.MDC;
+import com.central.log.trace.MDCTraceUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
@@ -19,7 +17,7 @@
* @author zlt
* @date 2019/10/7
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Component
@@ -31,10 +29,13 @@ public class TraceFilter implements GlobalFilter, Ordered {
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if (traceProperties.getEnable()) {
//链路追踪id
- String traceId = IdUtil.fastSimpleUUID();
- MDC.put(CommonConstant.LOG_TRACE_ID, traceId);
+ MDCTraceUtils.addTrace();
+
ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate()
- .headers(h -> h.add(CommonConstant.TRACE_ID_HEADER, traceId))
+ .headers(h -> {
+ h.add(MDCTraceUtils.TRACE_ID_HEADER, MDCTraceUtils.getTraceId());
+ h.add(MDCTraceUtils.SPAN_ID_HEADER, MDCTraceUtils.getNextSpanId());
+ })
.build();
ServerWebExchange build = exchange.mutate().request(serverHttpRequest).build();
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/VersionLbIsolationFilter.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/VersionLbIsolationFilter.java
new file mode 100644
index 00000000..fab1c00a
--- /dev/null
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/filter/VersionLbIsolationFilter.java
@@ -0,0 +1,45 @@
+package com.central.gateway.filter;
+
+import com.central.common.constant.CommonConstant;
+import com.central.common.constant.ConfigConstants;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+/**
+ * 示例
+ *
+ * @author jarvis create by 2022/5/8
+ */
+@Component
+public class VersionLbIsolationFilter implements GlobalFilter, Ordered {
+
+ @Value("${"+ ConfigConstants.CONFIG_LOADBALANCE_ISOLATION_ENABLE+":}")
+ private Boolean enableVersionControl;
+
+ @Override
+ public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+ if(Boolean.TRUE.equals(enableVersionControl)
+ && exchange.getRequest().getQueryParams().containsKey(CommonConstant.Z_L_T_VERSION)){
+ String version = exchange.getRequest().getQueryParams().get(CommonConstant.Z_L_T_VERSION).get(0);
+ ServerHttpRequest rebuildRequest = exchange.getRequest().mutate().headers(header -> {
+ header.add(CommonConstant.Z_L_T_VERSION, version);
+ }).build();
+ ServerWebExchange rebuildServerWebExchange = exchange.mutate().request(rebuildRequest).build();
+ return chain.filter(rebuildServerWebExchange);
+ }
+ return chain.filter(exchange);
+ }
+
+ @Override
+ public int getOrder() {
+ return Ordered.HIGHEST_PRECEDENCE;
+ }
+}
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/route/NacosRouteDefinitionRepository.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/route/NacosRouteDefinitionRepository.java
index 1d3b536b..155fc18c 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/route/NacosRouteDefinitionRepository.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/route/NacosRouteDefinitionRepository.java
@@ -3,9 +3,9 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cloud.nacos.NacosConfigProperties;
-import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
+import com.central.common.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
@@ -24,7 +24,7 @@
* @author zlt
* @date 2019/10/7
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
@@ -87,7 +87,7 @@ public Mono delete(Mono routeId) {
private List getListByStr(String content) {
if (StrUtil.isNotEmpty(content)) {
- return JSONObject.parseArray(content, RouteDefinition.class);
+ return JsonUtil.toList(content, RouteDefinition.class);
}
return new ArrayList<>(0);
}
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerAggProperties.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerAggProperties.java
index 1e4c1084..df7762d8 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerAggProperties.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerAggProperties.java
@@ -14,7 +14,7 @@
* @author zlt
* @date 2019/10/5
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Setter
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerHandler.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerHandler.java
index 34cec884..f9be8322 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerHandler.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerHandler.java
@@ -21,7 +21,7 @@
* @author zlt
* @date 2019/10/5
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@RestController
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerProvider.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerProvider.java
index 04acef57..5156a077 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerProvider.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/swagger/SwaggerProvider.java
@@ -21,7 +21,7 @@
* @author zlt
* @date 2019/10/5
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Component
diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/utils/ReactiveAddrUtil.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/utils/ReactiveAddrUtil.java
index ca11fd96..181d8ac5 100644
--- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/utils/ReactiveAddrUtil.java
+++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/utils/ReactiveAddrUtil.java
@@ -12,7 +12,7 @@
* @author zlt
* @date 2019/10/7
*
- * Blog: https://blog.csdn.net/zlt2000
+ * Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
diff --git a/zlt-gateway/sc-gateway/src/main/resources/application.yml b/zlt-gateway/sc-gateway/src/main/resources/application.yml
index 28080a1d..f7f69bf3 100644
--- a/zlt-gateway/sc-gateway/src/main/resources/application.yml
+++ b/zlt-gateway/sc-gateway/src/main/resources/application.yml
@@ -75,7 +75,7 @@ spring:
- StripPrefix=1
# sentinel:
# datasource.ds1.nacos:
-# server-addr: ${zlt.nacos.server-addr}
+# server-addr: ${spring.cloud.nacos.server-addr}
# data-id: ${spring.application.name}-sentinel-gw-flow
# group-id: DEFAULT_GROUP
# ruleType: gw-flow
@@ -98,9 +98,9 @@ zlt:
/api-uaa/css/**,
/api-uaa/images/**,
/api-uaa/js/**,
- /api-user/users-anon/**,
/login.html,
- /user/login
+ /user/login,
+ /api-uaa/tokens/key
auth:
urlPermission:
#是否开启url级别权限
diff --git a/zlt-gateway/zuul-gateway/pom.xml b/zlt-gateway/zuul-gateway/pom.xml
deleted file mode 100644
index 3c35f793..00000000
--- a/zlt-gateway/zuul-gateway/pom.xml
+++ /dev/null
@@ -1,155 +0,0 @@
-
- 4.0.0
-
- com.zlt
- zlt-gateway
- 3.5.0
-
- zuul-gateway
- zuul网关
-
-
-
-
- com.zlt
- zlt-config
-
-
- com.zlt
- zlt-auth-client-spring-boot-starter
-
-
- com.zlt
- zlt-ribbon-spring-boot-starter
-
-
- com.zlt
- zlt-sentinel-spring-boot-starter
-
-
- com.zlt
- zlt-redis-spring-boot-starter
-
-
-
- com.alibaba.cloud
- spring-cloud-starter-alibaba-nacos-discovery
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- org.springframework.boot
- spring-boot-starter-tomcat
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-undertow
-
-
-
- org.springframework
- spring-context-support
-
-
- org.springframework.boot
- spring-boot-starter-actuator
-
-
-
- com.github.zlt2000
- swagger-butler-core
-
-
-
- com.github.xiaoymin
- swagger-bootstrap-ui
-
-
-
- com.zyplayer
- swagger-mg-ui
-
-
-
- org.springframework.cloud
- spring-cloud-starter-netflix-zuul
-
-
- com.baomidou
- mybatis-plus-extension
-
-
-
- com.squareup.okhttp3
- okhttp
-
-
-
- io.micrometer
- micrometer-registry-prometheus
-
-
- eu.bitwalker
- UserAgentUtils
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
- repackage
-
-
-
-
-
- com.spotify
- docker-maven-plugin
-
- ${docker.image.prefix}/${project.artifactId}
-
- ${project.version}
- latest
-
- true
- ${docker.baseImage}
- ${docker.volumes}
-
- ${docker.java.opts}
-
- ["sh","-c","java $JAVA_OPTS ${docker.java.security.egd} -jar /${project.build.finalName}.jar"]
-
-
- /
- ${project.build.directory}
- ${project.build.finalName}.jar
-
-
-
-
-
- ${project.artifactId}
-
-
\ No newline at end of file
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/GatewayApp.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/GatewayApp.java
deleted file mode 100644
index 7fe04b5f..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/GatewayApp.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.central;
-
-import com.central.common.ribbon.annotation.EnableBaseFeignInterceptor;
-import com.central.common.ribbon.annotation.EnableFeignInterceptor;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
-import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
-import org.springframework.cloud.openfeign.EnableFeignClients;
-
-/**
- * @author zlt
- */
-@EnableZuulProxy
-@EnableFeignClients
-@EnableBaseFeignInterceptor
-@EnableDiscoveryClient
-@SpringBootApplication
-public class GatewayApp {
- public static void main(String[] args) {
- SpringApplication.run(GatewayApp.class, args);
- }
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/CorsConfigration.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/CorsConfigration.java
deleted file mode 100644
index 2f2c0829..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/CorsConfigration.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.central.gateway.config;
-
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.Ordered;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.CorsFilter;
-
-/**
- * 跨域配置
- *
- * @author zlt
- * @date 2018/8/9 15:59
- */
-@Configuration
-public class CorsConfigration {
-
- @Bean
- public CorsFilter corsFilter() {
- UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
- CorsConfiguration config = new CorsConfiguration();
- // #允许向该服务器提交请求的URI,*表示全部允许
- config.addAllowedOrigin(CorsConfiguration.ALL);
- // 允许cookies跨域
- config.setAllowCredentials(true);
- // #允许访问的头信息,*表示全部
- config.addAllowedHeader(CorsConfiguration.ALL);
- // 允许提交请求的方法,*表示全部允许
- config.addAllowedMethod(CorsConfiguration.ALL);
- source.registerCorsConfiguration("/**", config);
- return new CorsFilter(source);
- }
-
- /**
- * 配置过滤器
- */
- @Bean
- public FilterRegistrationBean someFilterRegistration() {
- FilterRegistrationBean registration = new FilterRegistrationBean<>();
- registration.setFilter(corsFilter());
- registration.addUrlPatterns("/*");
- registration.setName("corsFilter");
- registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
- return registration;
- }
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/DynamicZuulRouteConfig.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/DynamicZuulRouteConfig.java
deleted file mode 100644
index 42c76e42..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/DynamicZuulRouteConfig.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.central.gateway.config;
-
-import com.alibaba.cloud.nacos.NacosConfigProperties;
-import com.central.gateway.route.nacos.NacosDynRouteLocator;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
-import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * 动态路由配置
- *
- * @author zlt
- * @date 2019/8/21
- */
-@Configuration
-@ConditionalOnProperty(prefix = "zlt.gateway.dynamicRoute", name = "enabled", havingValue = "true")
-public class DynamicZuulRouteConfig {
- @Autowired
- private ZuulProperties zuulProperties;
-
- @Autowired
- private DispatcherServletPath dispatcherServletPath;
-
- /**
- * Nacos实现方式
- */
- @Configuration
- @ConditionalOnProperty(prefix = "zlt.gateway.dynamicRoute", name = "dataType", havingValue = "nacos", matchIfMissing = true)
- public class NacosZuulRoute {
- @Autowired
- private NacosConfigProperties nacosConfigProperties;
-
- @Autowired
- private ApplicationEventPublisher publisher;
-
- @Bean
- public NacosDynRouteLocator nacosDynRouteLocator() {
- return new NacosDynRouteLocator(nacosConfigProperties, publisher, dispatcherServletPath.getPrefix(), zuulProperties);
- }
- }
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/ResourceServerConfiguration.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/ResourceServerConfiguration.java
deleted file mode 100644
index 58e217f6..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/ResourceServerConfiguration.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.central.gateway.config;
-
-import com.central.common.config.DefaultPasswordConfig;
-import com.central.oauth2.common.config.DefaultResourceServerConf;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
-import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
-
-/**
- * @author zlt
- */
-@Configuration
-@EnableResourceServer
-@Import({DefaultPasswordConfig.class})
-public class ResourceServerConfiguration extends DefaultResourceServerConf {
- @Override
- public HttpSecurity setAuthenticate(ExpressionUrlAuthorizationConfigurer.AuthorizedUrl authorizedUrl) {
- return authorizedUrl.access("@permissionService.hasPermission(request, authentication)").and();
- }
-}
\ No newline at end of file
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/SwaggerConfig.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/SwaggerConfig.java
deleted file mode 100644
index d28318b5..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/SwaggerConfig.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.central.gateway.config;
-
-import com.didispace.swagger.butler.EnableSwaggerButler;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * swagger 聚合文档配置
- * zuul routers 映射具体服务的/v2/api-docs swagger
- *
- * @author 作者 owen E-mail: 624191343@qq.com
- */
-@Configuration
-@EnableSwaggerButler
-public class SwaggerConfig {
-
-}
\ No newline at end of file
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/ZuulRouteEntity.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/ZuulRouteEntity.java
deleted file mode 100644
index a4d9b32d..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/config/ZuulRouteEntity.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.central.gateway.config;
-
-import lombok.Getter;
-import lombok.Setter;
-
-/**
- * zuul路由实体
- *
- * @author zlt
- * @date 2019/8/21
- */
-@Setter
-@Getter
-public class ZuulRouteEntity {
- /**
- * The ID of the route (the same as its map key by default).
- */
- private String id;
- /**
- * The path (pattern) for the route, e.g. /foo/**.
- */
- private String path;
- /**
- * The service ID (if any) to map to this route. You can specify a
- * physical URL or a service, but not both.
- */
- private String serviceId;
- /**
- * A full physical URL to map to the route. An alternative is to use a
- * service ID and service discovery to find the physical address.
- */
- private String url;
- /**
- * Flag to determine whether the prefix for this route (the path, minus
- * pattern patcher) should be stripped before forwarding.
- */
- private boolean stripPrefix = true;
- /**
- * Flag to indicate that this route should be retryable (if supported).
- * Generally retry requires a service ID and ribbon.
- */
- private Boolean retryable;
-
- private String apiName;
-
- private boolean enabled = true;
-
- private boolean customSensitiveHeaders = true;
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/feign/MenuService.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/feign/MenuService.java
deleted file mode 100644
index 032ed131..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/feign/MenuService.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.central.gateway.feign;
-
-import com.central.common.constant.ServiceNameConstants;
-import com.central.common.model.SysMenu;
-import com.central.gateway.feign.fallback.MenuServiceFallbackFactory;
-import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-
-import java.util.List;
-
-/**
- * @author zlt
- */
-@FeignClient(name = ServiceNameConstants.USER_SERVICE, fallbackFactory = MenuServiceFallbackFactory.class, decode404 = true)
-public interface MenuService {
- /**
- * 角色菜单列表
- * @param roleCodes
- */
- @GetMapping(value = "/menus/{roleCodes}")
- List findByRoleCodes(@PathVariable("roleCodes") String roleCodes);
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/feign/fallback/MenuServiceFallbackFactory.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/feign/fallback/MenuServiceFallbackFactory.java
deleted file mode 100644
index 7cba08ab..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/feign/fallback/MenuServiceFallbackFactory.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.central.gateway.feign.fallback;
-
-import cn.hutool.core.collection.CollectionUtil;
-import com.central.gateway.feign.MenuService;
-import feign.hystrix.FallbackFactory;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * menuService降级工场
- *
- * @author zlt
- * @date 2019/1/18
- */
-@Slf4j
-@Component
-public class MenuServiceFallbackFactory implements FallbackFactory {
- @Override
- public MenuService create(Throwable throwable) {
- return roleIds -> {
- log.error("调用findByRoleCodes异常:{}", roleIds, throwable);
- return CollectionUtil.newArrayList();
- };
- }
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/filter/pre/RequestStatisticsFilter.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/filter/pre/RequestStatisticsFilter.java
deleted file mode 100644
index 72c60b45..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/filter/pre/RequestStatisticsFilter.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.central.gateway.filter.pre;
-
-import cn.hutool.core.util.StrUtil;
-import com.central.common.utils.AddrUtil;
-import com.central.log.monitor.PointUtil;
-import com.netflix.zuul.ZuulFilter;
-import com.netflix.zuul.context.RequestContext;
-import eu.bitwalker.useragentutils.UserAgent;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
-import org.springframework.stereotype.Component;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * 请求统计分析埋点过滤器
- *
- * @author zlt
- * @date 2019/5/6
- */
-@Slf4j
-@Component
-public class RequestStatisticsFilter extends ZuulFilter {
- @Override
- public String filterType() {
- return FilterConstants.PRE_TYPE;
- }
-
- @Override
- public int filterOrder() {
- return 0;
- }
-
- @Override
- public boolean shouldFilter() {
- return true;
- }
-
- @Override
- public Object run() {
- RequestContext ctx = RequestContext.getCurrentContext();
- HttpServletRequest req = ctx.getRequest();
- UserAgent userAgent = UserAgent.parseUserAgentString(req.getHeader("User-Agent"));
-
- //埋点
- PointUtil.debug("0", "request-statistics",
- "ip=" + AddrUtil.getRemoteAddr(req)
- + "&browser=" + getBrowser(userAgent.getBrowser().getName())
- + "&operatingSystem=" + getOperatingSystem(userAgent.getOperatingSystem().getName()));
-
- return null;
- }
-
- private String getBrowser(String browser) {
- if (StrUtil.isNotEmpty(browser)) {
- if (browser.contains("CHROME")) {
- return "CHROME";
- } else if (browser.contains("FIREFOX")) {
- return "FIREFOX";
- } else if (browser.contains("SAFARI")) {
- return "SAFARI";
- } else if (browser.contains("EDGE")) {
- return "EDGE";
- }
- }
- return browser;
- }
-
- private String getOperatingSystem(String operatingSystem) {
- if (StrUtil.isNotEmpty(operatingSystem)) {
- if (operatingSystem.contains("MAC_OS_X")) {
- return "MAC_OS_X";
- } else if (operatingSystem.contains("ANDROID")) {
- return "ANDROID";
- }
- }
- return operatingSystem;
- }
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/filter/pre/TraceFilter.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/filter/pre/TraceFilter.java
deleted file mode 100644
index 2739492e..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/filter/pre/TraceFilter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.central.gateway.filter.pre;
-
-import cn.hutool.core.util.IdUtil;
-import com.central.common.constant.CommonConstant;
-import com.central.log.properties.TraceProperties;
-import com.netflix.zuul.ZuulFilter;
-import com.netflix.zuul.context.RequestContext;
-import org.slf4j.MDC;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
-import org.springframework.stereotype.Component;
-
-import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER;
-
-/**
- * 生成日志链路追踪id,并传入header中
- *
- * @author zlt
- * @date 2019/8/13
- */
-@Component
-public class TraceFilter extends ZuulFilter {
- @Autowired
- private TraceProperties traceProperties;
-
- @Override
- public String filterType() {
- return FilterConstants.PRE_TYPE;
- }
-
- @Override
- public int filterOrder() {
- return FORM_BODY_WRAPPER_FILTER_ORDER - 1;
- }
-
- @Override
- public boolean shouldFilter() {
- //根据配置控制是否开启过滤器
- return traceProperties.getEnable();
- }
-
- @Override
- public Object run() {
- //链路追踪id
- String traceId = IdUtil.fastSimpleUUID();
- MDC.put(CommonConstant.LOG_TRACE_ID, traceId);
- RequestContext ctx = RequestContext.getCurrentContext();
- ctx.addZuulRequestHeader(CommonConstant.TRACE_ID_HEADER, traceId);
- return null;
- }
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/filter/pre/UserInfoHeaderFilter.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/filter/pre/UserInfoHeaderFilter.java
deleted file mode 100644
index 731a907d..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/filter/pre/UserInfoHeaderFilter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.central.gateway.filter.pre;
-
-import cn.hutool.core.collection.CollectionUtil;
-import com.central.common.constant.SecurityConstants;
-import com.central.common.model.SysUser;
-import com.netflix.zuul.ZuulFilter;
-import com.netflix.zuul.context.RequestContext;
-import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
-import org.springframework.security.authentication.AnonymousAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.oauth2.provider.OAuth2Authentication;
-import org.springframework.stereotype.Component;
-
-import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER;
-
-/**
- * 将认证用户的相关信息放入header中, 后端服务可以直接读取使用
- *
- * @author zlt
- * @date 2018/11/20
- */
-@Component
-public class UserInfoHeaderFilter extends ZuulFilter {
- @Override
- public String filterType() {
- return FilterConstants.PRE_TYPE;
- }
-
- @Override
- public int filterOrder() {
- return FORM_BODY_WRAPPER_FILTER_ORDER - 1;
- }
-
- @Override
- public boolean shouldFilter() {
- return true;
- }
-
- @Override
- public Object run() {
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)) {
- Object principal = authentication.getPrincipal();
- RequestContext ctx = RequestContext.getCurrentContext();
- //客户端模式只返回一个clientId
- if (principal instanceof SysUser) {
- SysUser user = (SysUser)authentication.getPrincipal();
- ctx.addZuulRequestHeader(SecurityConstants.USER_ID_HEADER, String.valueOf(user.getId()));
- ctx.addZuulRequestHeader(SecurityConstants.USER_HEADER, user.getUsername());
- }
- OAuth2Authentication oauth2Authentication = (OAuth2Authentication)authentication;
- String clientId = oauth2Authentication.getOAuth2Request().getClientId();
- ctx.addZuulRequestHeader(SecurityConstants.TENANT_HEADER, clientId);
- ctx.addZuulRequestHeader(SecurityConstants.ROLE_HEADER, CollectionUtil.join(authentication.getAuthorities(), ","));
- }
- return null;
- }
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/route/AbstractDynRouteLocator.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/route/AbstractDynRouteLocator.java
deleted file mode 100644
index c1dbcee7..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/route/AbstractDynRouteLocator.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.central.gateway.route;
-
-import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
-import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
-import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
-import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
-import org.springframework.util.StringUtils;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * 扩展 {@link SimpleRouteLocator} 实现动态路由
- *
- * @author zlt
- * @date 2019/8/21
- */
-public abstract class AbstractDynRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
- private ZuulProperties properties;
-
- public AbstractDynRouteLocator(String servletPath, ZuulProperties properties) {
- super(servletPath, properties);
- this.properties = properties;
- }
-
- /**
- * 刷新路由
- */
- @Override
- public void refresh() {
- doRefresh();
- }
-
- @Override
- protected Map locateRoutes() {
- LinkedHashMap routesMap = new LinkedHashMap<>();
- // 从application.properties中加载静态路由信息
- routesMap.putAll(super.locateRoutes());
- // 从数据源中加载动态路由信息
- routesMap.putAll(loadDynamicRoute());
- // 优化一下配置
- LinkedHashMap values = new LinkedHashMap<>();
- for (Map.Entry entry : routesMap.entrySet()) {
- String path = entry.getKey();
- // Prepend with slash if not already present.
- if (!path.startsWith("/")) {
- path = "/" + path;
- }
- if (StringUtils.hasText(this.properties.getPrefix())) {
- path = this.properties.getPrefix() + path;
- if (!path.startsWith("/")) {
- path = "/" + path;
- }
- }
- values.put(path, entry.getValue());
- }
- return values;
- }
-
- /**
- * 加载路由配置,由子类去实现
- */
- public abstract Map loadDynamicRoute();
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/route/nacos/NacosDynRouteLocator.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/route/nacos/NacosDynRouteLocator.java
deleted file mode 100644
index fb723a7d..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/route/nacos/NacosDynRouteLocator.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package com.central.gateway.route.nacos;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.util.StrUtil;
-import com.alibaba.cloud.nacos.NacosConfigProperties;
-import com.alibaba.fastjson.JSONObject;
-import com.alibaba.nacos.api.config.listener.Listener;
-import com.alibaba.nacos.api.exception.NacosException;
-import com.central.gateway.config.ZuulRouteEntity;
-import com.central.gateway.route.AbstractDynRouteLocator;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.cloud.netflix.zuul.RoutesRefreshedEvent;
-import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
-import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
-import org.springframework.context.ApplicationEventPublisher;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * Nacos动态路由实现类
- *
- * @author zlt
- * @date 2019/8/22
- */
-@Slf4j
-public class NacosDynRouteLocator extends AbstractDynRouteLocator {
- private static final String ZUUL_DATA_ID = "zuul-routes";
- private static final String ZUUL_GROUP_ID = "ZUUL_GATEWAY";
-
- private NacosConfigProperties nacosConfigProperties;
-
- private ApplicationEventPublisher publisher;
-
- private NacosDynRouteLocator locator;
-
- @Setter
- private List zuulRouteEntities;
-
- public NacosDynRouteLocator(NacosConfigProperties nacosConfigProperties, ApplicationEventPublisher publisher,
- String servletPath, ZuulProperties properties) {
- super(servletPath, properties);
- this.nacosConfigProperties = nacosConfigProperties;
- this.publisher = publisher;
- this.locator = this;
- addListener();
- }
-
- /**
- * 添加Nacos监听
- */
- private void addListener() {
- try {
- nacosConfigProperties.configServiceInstance().addListener(ZUUL_DATA_ID, ZUUL_GROUP_ID, new Listener() {
- @Override
- public Executor getExecutor() {
- return null;
- }
-
- @Override
- public void receiveConfigInfo(String configInfo) {
- //赋值路由信息
- locator.setZuulRouteEntities(getListByStr(configInfo));
- RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(locator);
- publisher.publishEvent(routesRefreshedEvent);
- }
- });
- } catch (NacosException e) {
- log.error("nacos-addListener-error", e);
- }
- }
-
- @Override
- public Map loadDynamicRoute() {
- Map routes = new LinkedHashMap<>();
- if (zuulRouteEntities == null) {
- zuulRouteEntities = getNacosConfig();
- }
- for (ZuulRouteEntity result : zuulRouteEntities) {
- if (StrUtil.isBlank(result.getPath()) || !result.isEnabled()) {
- continue;
- }
- ZuulRoute zuulRoute = new ZuulRoute();
- BeanUtil.copyProperties(result, zuulRoute);
- routes.put(zuulRoute.getPath(), zuulRoute);
- }
- return routes;
- }
-
- /**
- * 查询zuul的路由配置
- */
- private List getNacosConfig() {
- try {
- String content = nacosConfigProperties.configServiceInstance().getConfig(ZUUL_DATA_ID, ZUUL_GROUP_ID,5000);
- return getListByStr(content);
- } catch (NacosException e) {
- log.error("listenerNacos-error", e);
- }
- return new ArrayList<>(0);
- }
-
- public List getListByStr(String content) {
- if (StrUtil.isNotEmpty(content)) {
- return JSONObject.parseArray(content, ZuulRouteEntity.class);
- }
- return new ArrayList<>(0);
- }
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/service/impl/PermissionServiceImpl.java b/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/service/impl/PermissionServiceImpl.java
deleted file mode 100644
index 422e6e1f..00000000
--- a/zlt-gateway/zuul-gateway/src/main/java/com/central/gateway/service/impl/PermissionServiceImpl.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.central.gateway.service.impl;
-
-import com.central.common.model.SysMenu;
-import com.central.gateway.feign.MenuService;
-import com.central.oauth2.common.service.impl.DefaultPermissionServiceImpl;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.security.core.Authentication;
-import org.springframework.stereotype.Service;
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import java.util.List;
-
-/**
- * 请求权限判断service
- *
- * @author zlt
- * @date 2018/10/28
- */
-@Slf4j
-@Service("permissionService")
-public class PermissionServiceImpl extends DefaultPermissionServiceImpl {
- @Resource
- private MenuService menuService;
-
- @Override
- public List findMenuByRoleCodes(String roleCodes) {
- return menuService.findByRoleCodes(roleCodes);
- }
-
- public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
- return hasPermission(authentication, request.getMethod(), request.getRequestURI());
- }
-}
diff --git a/zlt-gateway/zuul-gateway/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/zlt-gateway/zuul-gateway/src/main/resources/META-INF/additional-spring-configuration-metadata.json
deleted file mode 100644
index efd00b85..00000000
--- a/zlt-gateway/zuul-gateway/src/main/resources/META-INF/additional-spring-configuration-metadata.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "properties": [
- {
- "name": "zlt.gateway.dynamicRoute.enabled",
- "description": "是否开启动态路由.",
- "type": "java.lang.Boolean",
- "defaultValue": false
- },
- {
- "name": "zlt.gateway.dynamicRoute.dataType",
- "description": "动态路由的数据类型.",
- "type": "java.lang.String",
- "defaultValue": "nacos"
- }
- ]
-}
\ No newline at end of file
diff --git a/zlt-gateway/zuul-gateway/src/main/resources/application.yml b/zlt-gateway/zuul-gateway/src/main/resources/application.yml
deleted file mode 100644
index e2a06e3d..00000000
--- a/zlt-gateway/zuul-gateway/src/main/resources/application.yml
+++ /dev/null
@@ -1,169 +0,0 @@
-#spring:
- # sentinel动态配置规则
-# cloud:
-# sentinel:
-# zuul:
-# enabled: true
-# order:
-# pre: 2000
-# post: 500
-# error: -100
-# filter:
-# enabled: false
-# datasource:
- # 限流
-# ds1:
-# nacos:
-# server-addr: ${zlt.nacos.server-addr}
-# dataId: ${spring.application.name}-sentinel-gw-flow
-# groupId: DEFAULT_GROUP
-# rule-type: gw-flow
- # api分组
-# ds2:
-# nacos:
-# server-addr: ${zlt.nacos.server-addr}
-# dataId: ${spring.application.name}-sentinel-gw-api-group
-# groupId: DEFAULT_GROUP
-# rule-type: gw-api-group
-
-zlt:
- oauth2:
- token:
- store:
- type: redis
- security:
- ignore:
- # 忽略认证的地址
- httpUrls: >
- /api-uaa/oauth/**,
- /api-uaa/validata/**,
- /api-uaa/css/**,
- /api-uaa/images/**,
- /api-uaa/js/**,
- /api-user/users-anon/**,
- /login.html,
- /user/login
- auth:
- urlPermission:
- #是否开启url级别权限
- enable: false
- #配置只进行登录认证,不进行url权限认证的api
- ignoreUrls: >
- /api-user/menus/current,
- /api-user/users/current,
- /api-log/requestStat
- #白名单
- includeClientIds:
- - webApp
- renew:
- #是否开启token自动续签(目前只有redis实现)
- enable: true
- #白名单
- includeClientIds:
- - webApp
- gateway:
- #网关动态路由
- dynamicRoute:
- enabled: true
-
-
-zuul:
- ribbon-isolation-strategy: thread
- ribbon:
- eager-load:
- enabled: true
- threadPool:
- useSeparateThreadPools: true
- threadPoolKeyPrefix: api-gateway
- #关闭重试
- retryable: false
- ignored-headers: Access-Control-Allow-Credentials,Access-Control-Allow-Origin,Access-Control-Allow-Methods
- add-host-header: true
- routes:
- auth:
- path: /api-uaa/**
- service-id: uaa-server
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- auth-login-page:
- path: /login.html
- service-id: uaa-server
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- auth-login-process:
- path: /user/login
- service-id: uaa-server
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- auth-login-token:
- path: /oauth/token
- service-id: uaa-server
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- auth-login-authorize:
- path: /oauth/authorize
- service-id: uaa-server
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- auth-check-process:
- path: /oauth/check_token
- service-id: uaa-server
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- user:
- path: /api-user/**
- service-id: user-center
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- file:
- path: /api-file/**
- service-id: file-center
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- log:
- path: /api-log/**
- service-id: log-center
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- generator:
- path: /api-generator/**
- service-id: code-generator
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- search:
- path: /api-search/**
- service-id: search-center
- strip-prefix: true
- sensitive-headers: '*'
- custom-sensitive-headers: true
- ssl-hostname-validation-enabled: false
-
-hystrix:
- threadpool:
- default:
- coreSize: 100
- maximumSize: 2000
- allowMaximumSizeToDivergeFromCoreSize: true
- maxQueueSize: -1
- command:
- default:
- execution:
- isolation:
- thread:
- timeoutInMilliseconds: 60000
-
-swagger:
- butler:
- auto-generate-from-zuul-routes: true
- generate-routes: user,file
- apiDocsPath: v2/api-docs
\ No newline at end of file
diff --git a/zlt-gateway/zuul-gateway/src/main/resources/bootstrap.yml b/zlt-gateway/zuul-gateway/src/main/resources/bootstrap.yml
deleted file mode 100644
index b64a9d42..00000000
--- a/zlt-gateway/zuul-gateway/src/main/resources/bootstrap.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-server:
- port: 9900
- undertow:
- buffer-size: 1024
- direct-buffers: true
-
-spring:
- application:
- name: api-gateway
\ No newline at end of file
diff --git a/zlt-gateway/zuul-gateway/src/main/resources/pubkey.txt b/zlt-gateway/zuul-gateway/src/main/resources/pubkey.txt
deleted file mode 100644
index 0c1d7c8d..00000000
--- a/zlt-gateway/zuul-gateway/src/main/resources/pubkey.txt
+++ /dev/null
@@ -1,9 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjmgfejBXsPYynAIPczHA
-eEvTDfAVaNKQudyI7VszdezbHDM1CStCIgwiMmLd7QYf1SrrmQoqxhcSRbhjE3ej
-RF5qzhtx3kmepdpMrQptcsLjRkixaxCc4E2k6Us5707gGwbhoaTrRit5F2MnAdLY
-C1TS3WwnO/hQfqUcAglbK8yrJ4AwAv0DAoIUSWnWqzuniV1SYbdV57uswxUssoWy
-sEfPz+nv1ZLRs6Wz4eQ5Myqx2+CjWc9F8iXa2PV8Rmjms3dVbWcLUpCP18Dfzp8l
-n8vF9LfYB7UaLSpfJe6FFF6+vCg4JHfo12djTUgwGjauMF3e9mmjU83KIoQS66lp
-AQIDAQAB
------END PUBLIC KEY-----
\ No newline at end of file
diff --git a/zlt-job/job-admin/pom.xml b/zlt-job/job-admin/pom.xml
index 15803174..102da016 100644
--- a/zlt-job/job-admin/pom.xml
+++ b/zlt-job/job-admin/pom.xml
@@ -4,7 +4,7 @@
com.zlt
zlt-job
- 3.5.0
+ 5.3.0
job-admin
jar
diff --git a/zlt-job/job-core/pom.xml b/zlt-job/job-core/pom.xml
index 421c53ea..7a279d19 100644
--- a/zlt-job/job-core/pom.xml
+++ b/zlt-job/job-core/pom.xml
@@ -4,7 +4,7 @@
com.zlt
zlt-job
- 3.5.0
+ 5.3.0
job-core
jar
diff --git a/zlt-job/job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java b/zlt-job/job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java
index ff89001a..e86bc7b9 100644
--- a/zlt-job/job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java
+++ b/zlt-job/job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java
@@ -200,14 +200,12 @@ public static String readLines(File logFile){
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(logFile), "utf-8"));
- if (reader != null) {
- StringBuilder sb = new StringBuilder();
- String line = null;
- while ((line = reader.readLine()) != null) {
- sb.append(line).append("\n");
- }
- return sb.toString();
+ StringBuilder sb = new StringBuilder();
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line).append("\n");
}
+ return sb.toString();
} catch (IOException e) {
logger.error(e.getMessage(), e);
} finally {
diff --git a/zlt-job/job-core/src/main/java/com/xxl/job/core/thread/TriggerCallbackThread.java b/zlt-job/job-core/src/main/java/com/xxl/job/core/thread/TriggerCallbackThread.java
index 9fba156d..225a9e91 100644
--- a/zlt-job/job-core/src/main/java/com/xxl/job/core/thread/TriggerCallbackThread.java
+++ b/zlt-job/job-core/src/main/java/com/xxl/job/core/thread/TriggerCallbackThread.java
@@ -215,7 +215,7 @@ private void retryFailCallbackFile(){
}
// retry callback, 100 lines per page
- if (failCallbackParamList!=null && failCallbackParamList.size()>0) {
+ if (failCallbackParamList.size()>0) {
int pagesize = 100;
List pageData = new ArrayList<>();
for (int i = 0; i < failCallbackParamList.size(); i++) {
diff --git a/zlt-job/job-executor-samples/pom.xml b/zlt-job/job-executor-samples/pom.xml
index d6eeae3a..2a31f63c 100644
--- a/zlt-job/job-executor-samples/pom.xml
+++ b/zlt-job/job-executor-samples/pom.xml
@@ -6,7 +6,7 @@
com.zlt
zlt-job
- 3.5.0
+ 5.3.0
job-executor-samples
jar
diff --git a/zlt-job/pom.xml b/zlt-job/pom.xml
index 061dbdae..f09d6909 100644
--- a/zlt-job/pom.xml
+++ b/zlt-job/pom.xml
@@ -4,7 +4,7 @@
com.zlt
central-platform
- 3.5.0
+ 5.3.0
zlt-job
pom
@@ -35,7 +35,7 @@
3.8.1
2.5.5
2.3.0
- 2.9.8
+ 2.12.6.1