1:yml配置
server :
port : 8082
spring :
application :
name : order- nacos
redis :
host : 127.0.0.1
password : 123456
database : 0
logging :
level :
root : info
2:pom.xm依赖
< parent>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-parent</ artifactId>
< version> 2.6.11</ version>
< relativePath/>
</ parent>
< dependencies>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-web</ artifactId>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-data-redis</ artifactId>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-websocket</ artifactId>
</ dependency>
< dependency>
< groupId> commons-lang</ groupId>
< artifactId> commons-lang</ artifactId>
< version> 2.6</ version>
</ dependency>
< dependency>
< groupId> com.alibaba</ groupId>
< artifactId> fastjson</ artifactId>
< version> 1.2.83_noneautotype</ version>
</ dependency>
3-1:RedisConfig
package com. test. order. config ;
import com. fasterxml. jackson. annotation. JsonAutoDetect ;
import com. fasterxml. jackson. annotation. PropertyAccessor ;
import com. fasterxml. jackson. databind. ObjectMapper ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. cache. CacheManager ;
import org. springframework. cache. annotation. CachingConfigurerSupport ;
import org. springframework. cache. annotation. EnableCaching ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. data. redis. cache. RedisCacheConfiguration ;
import org. springframework. data. redis. cache. RedisCacheManager ;
import org. springframework. data. redis. cache. RedisCacheWriter ;
import org. springframework. data. redis. connection. RedisConnectionFactory ;
import org. springframework. data. redis. connection. lettuce. LettuceConnectionFactory ;
import org. springframework. data. redis. core. RedisTemplate ;
import org. springframework. data. redis. listener. ChannelTopic ;
import org. springframework. data. redis. listener. RedisMessageListenerContainer ;
import org. springframework. data. redis. listener. adapter. MessageListenerAdapter ;
import org. springframework. data. redis. serializer. Jackson2JsonRedisSerializer ;
import org. springframework. data. redis. serializer. RedisSerializationContext ;
import org. springframework. data. redis. serializer. RedisSerializer ;
import org. springframework. data. redis. serializer. StringRedisSerializer ;
import javax. annotation. Resource ;
import java. time. Duration ;
import static java. util. Collections . singletonMap ;
@Slf4j
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Resource
private LettuceConnectionFactory lettuceConnectionFactory;
@Bean
public RedisTemplate < String , Object > redisTemplate ( LettuceConnectionFactory lettuceConnectionFactory) {
log. info ( " --- redis config init --- " ) ;
Jackson2JsonRedisSerializer < Object > jackson2JsonRedisSerializer = jacksonSerializer ( ) ;
RedisTemplate < String , Object > redisTemplate = new RedisTemplate < String , Object > ( ) ;
redisTemplate. setConnectionFactory ( lettuceConnectionFactory) ;
RedisSerializer < String > stringSerializer = new StringRedisSerializer ( ) ;
redisTemplate. setKeySerializer ( stringSerializer) ;
redisTemplate. setValueSerializer ( jackson2JsonRedisSerializer) ;
redisTemplate. setHashKeySerializer ( stringSerializer) ;
redisTemplate. setHashValueSerializer ( jackson2JsonRedisSerializer) ;
redisTemplate. afterPropertiesSet ( ) ;
return redisTemplate;
}
@Bean
public CacheManager cacheManager ( LettuceConnectionFactory factory) {
Jackson2JsonRedisSerializer < Object > jackson2JsonRedisSerializer = jacksonSerializer ( ) ;
RedisCacheConfiguration config = RedisCacheConfiguration . defaultCacheConfig ( ) . entryTtl ( Duration . ofHours ( 6 ) ) ;
RedisCacheConfiguration redisCacheConfiguration = config. serializeKeysWith ( RedisSerializationContext. SerializationPair . fromSerializer ( new StringRedisSerializer ( ) ) )
. serializeValuesWith ( RedisSerializationContext. SerializationPair . fromSerializer ( jackson2JsonRedisSerializer) ) ;
RedisCacheWriter writer = new JeecgRedisCacheWriter ( factory, Duration . ofMillis ( 50L ) ) ;
RedisCacheManager cacheManager = RedisCacheManager . builder ( writer) . cacheDefaults ( redisCacheConfiguration)
. withInitialCacheConfigurations ( singletonMap ( CacheConstant . SYS_DICT_TABLE_CACHE ,
RedisCacheConfiguration . defaultCacheConfig ( ) . entryTtl ( Duration . ofMinutes ( 10 ) ) . disableCachingNullValues ( )
. serializeValuesWith ( RedisSerializationContext. SerializationPair . fromSerializer ( jackson2JsonRedisSerializer) ) ) )
. withInitialCacheConfigurations ( singletonMap ( CacheConstant . TEST_DEMO_CACHE , RedisCacheConfiguration . defaultCacheConfig ( ) . entryTtl ( Duration . ofMinutes ( 5 ) ) . disableCachingNullValues ( ) ) )
. withInitialCacheConfigurations ( singletonMap ( CacheConstant . PLUGIN_MALL_RANKING , RedisCacheConfiguration . defaultCacheConfig ( ) . entryTtl ( Duration . ofHours ( 24 ) ) . disableCachingNullValues ( ) ) )
. withInitialCacheConfigurations ( singletonMap ( CacheConstant . PLUGIN_MALL_PAGE_LIST , RedisCacheConfiguration . defaultCacheConfig ( ) . entryTtl ( Duration . ofHours ( 24 ) ) . disableCachingNullValues ( ) ) )
. transactionAware ( ) . build ( ) ;
return cacheManager;
}
@Bean
public RedisMessageListenerContainer redisContainer ( RedisConnectionFactory redisConnectionFactory, RedisReceiver redisReceiver, MessageListenerAdapter commonListenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer ( ) ;
container. setConnectionFactory ( redisConnectionFactory) ;
container. addMessageListener ( commonListenerAdapter, new ChannelTopic ( GlobalConstants . REDIS_TOPIC_NAME ) ) ;
return container;
}
@Bean
MessageListenerAdapter commonListenerAdapter ( RedisReceiver redisReceiver) {
MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter ( redisReceiver, "onMessage" ) ;
messageListenerAdapter. setSerializer ( jacksonSerializer ( ) ) ;
return messageListenerAdapter;
}
private Jackson2JsonRedisSerializer jacksonSerializer ( ) {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer ( Object . class ) ;
ObjectMapper objectMapper = new ObjectMapper ( ) ;
objectMapper. setVisibility ( PropertyAccessor . ALL , JsonAutoDetect. Visibility . ANY ) ;
objectMapper. enableDefaultTyping ( ObjectMapper. DefaultTyping . NON_FINAL ) ;
jackson2JsonRedisSerializer. setObjectMapper ( objectMapper) ;
return jackson2JsonRedisSerializer;
}
}
3-2:RedisReceiver
package com. test. order. config ;
import cn. hutool. core. util. ObjectUtil ;
import org. springframework. stereotype. Component ;
@Component
public class RedisReceiver {
public void onMessage ( BaseMap params) {
Object handlerName = params. get ( "handlerName" ) ;
JeecgRedisListener messageListener = ( JeecgRedisListener ) SpringContextHolder . getHandler ( handlerName. toString ( ) , JeecgRedisListener . class ) ;
if ( ObjectUtil . isNotEmpty ( messageListener) ) {
messageListener. onMessage ( params) ;
}
}
public RedisReceiver ( ) {
}
public boolean equals ( final Object o) {
if ( o == this ) {
return true ;
} else if ( ! ( o instanceof RedisReceiver ) ) {
return false ;
} else {
RedisReceiver other = ( RedisReceiver ) o;
return other. canEqual ( this ) ;
}
}
protected boolean canEqual ( final Object other) {
return other instanceof RedisReceiver ;
}
public int hashCode ( ) {
return 1 ;
}
public String toString ( ) {
return "RedisReceiver()" ;
}
}
3-3:JeecgRedisClient
package com. test. order. config ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. data. redis. core. RedisTemplate ;
import javax. annotation. Resource ;
@Configuration
public class JeecgRedisClient {
@Resource
private RedisTemplate < String , Object > redisTemplate;
public JeecgRedisClient ( ) {
}
public void sendMessage ( String handlerName, BaseMap params) {
params. put ( "handlerName" , handlerName) ;
this . redisTemplate. convertAndSend ( "jeecg_redis_topic" , params) ;
}
}
3-4:JeecgRedisListener
package com. test. order. config ;
public interface JeecgRedisListener {
void onMessage ( BaseMap message) ;
}
3-5:BaseMap
package com. test. order. config ;
import cn. hutool. core. util. ObjectUtil ;
import java. math. BigDecimal ;
import java. util. HashMap ;
import java. util. List ;
import java. util. Map ;
import java. util. Optional ;
import java. util. stream. Collectors ;
import org. apache. commons. beanutils. ConvertUtils ;
public class BaseMap extends HashMap < String , Object > {
private static final long serialVersionUID = 1L ;
public BaseMap ( ) {
}
public BaseMap ( Map < String , Object > map) {
this . putAll ( map) ;
}
public BaseMap put ( String key, Object value) {
super . put ( key, Optional . ofNullable ( value) . orElse ( "" ) ) ;
return this ;
}
public BaseMap add ( String key, Object value) {
super . put ( key, Optional . ofNullable ( value) . orElse ( "" ) ) ;
return this ;
}
public < T > T get ( String key) {
Object obj = super . get ( key) ;
return ObjectUtil . isNotEmpty ( obj) ? ( T ) obj : null ;
}
public Boolean getBoolean ( String key) {
Object obj = super . get ( key) ;
return ObjectUtil . isNotEmpty ( obj) ? Boolean . valueOf ( obj. toString ( ) ) : false ;
}
public Long getLong ( String key) {
Object v = this . get ( key) ;
return ObjectUtil . isNotEmpty ( v) ? new Long ( v. toString ( ) ) : null ;
}
public Long [ ] getLongs ( String key) {
Object v = this . get ( key) ;
return ObjectUtil . isNotEmpty ( v) ? ( Long [ ] ) ( ( Long [ ] ) v) : null ;
}
public List < Long > getListLong ( String key) {
List < String > list = ( List ) this . get ( key) ;
return ObjectUtil . isNotEmpty ( list) ? ( List ) list. stream ( ) . map ( ( e) -> {
return new Long ( e) ;
} ) . collect ( Collectors . toList ( ) ) : null ;
}
public Long [ ] getLongIds ( String key) {
Object ids = this . get ( key) ;
return ObjectUtil . isNotEmpty ( ids) ? ( Long [ ] ) ( ( Long [ ] ) ConvertUtils . convert ( ids. toString ( ) . split ( "," ) , Long . class ) ) : null ;
}
public Integer getInt ( String key, Integer def) {
Object v = this . get ( key) ;
return ObjectUtil . isNotEmpty ( v) ? Integer . parseInt ( v. toString ( ) ) : def;
}
public Integer getInt ( String key) {
Object v = this . get ( key) ;
return ObjectUtil . isNotEmpty ( v) ? Integer . parseInt ( v. toString ( ) ) : 0 ;
}
public BigDecimal getBigDecimal ( String key) {
Object v = this . get ( key) ;
return ObjectUtil . isNotEmpty ( v) ? new BigDecimal ( v. toString ( ) ) : new BigDecimal ( "0" ) ;
}
public < T > T get ( String key, T def) {
Object obj = super . get ( key) ;
return ObjectUtil . isEmpty ( obj) ? def : ( T ) obj;
}
public static BaseMap toBaseMap ( Map < String , Object > obj) {
BaseMap map = new BaseMap ( ) ;
map. putAll ( obj) ;
return map;
}
}
3-6:CacheConstant
package com. test. order. config ;
public interface CacheConstant {
public static final String SYS_DICT_CACHE = "sys:cache:dict" ;
public static final String SYS_ENABLE_DICT_CACHE = "sys:cache:dictEnable" ;
public static final String SYS_DICT_TABLE_CACHE = "sys:cache:dictTable" ;
public static final String SYS_DICT_TABLE_BY_KEYS_CACHE = SYS_DICT_TABLE_CACHE + "ByKeys" ;
public static final String SYS_DATA_PERMISSIONS_CACHE = "sys:cache:permission:datarules" ;
public static final String SYS_USERS_CACHE = "sys:cache:encrypt:user" ;
public static final String SYS_DEPARTS_CACHE = "sys:cache:depart:alldata" ;
public static final String SYS_DEPART_IDS_CACHE = "sys:cache:depart:allids" ;
public static final String TEST_DEMO_CACHE = "test:demo" ;
public static final String SYS_DYNAMICDB_CACHE = "sys:cache:dbconnect:dynamic:" ;
public static final String GATEWAY_ROUTES = "sys:cache:cloud:gateway_routes" ;
public static final String ROUTE_JVM_RELOAD_TOPIC = "gateway_jvm_route_reload_topic" ;
public static final String PLUGIN_MALL_RANKING = "pluginMall::rankingList" ;
public static final String PLUGIN_MALL_PAGE_LIST = "pluginMall::queryPageList" ;
public static final String ONLINE_LIST = "sys:cache:online:list" ;
public static final String ONLINE_FORM = "sys:cache:online:form" ;
public static final String ONLINE_RP = "sys:cache:online:rp" ;
public static final String ONLINE_GRAPH = "sys:cache:online:graph" ;
public static final String DRAG_PAGE_CACHE = "drag:cache:page" ;
}
3-7:CommonAPI
package com. test. order. config ;
import java. util. List ;
import java. util. Map ;
import java. util. Set ;
public interface CommonAPI {
Set < String > queryUserRoles ( String username) ;
Set < String > queryUserAuths ( String userId) ;
String translateDictFromTable ( String table, String text, String code, String key) ;
String translateDict ( String code, String key) ;
}
3-8:CommonConfig
package com. test. order. config ;
import org. springframework. boot. autoconfigure. condition. ConditionalOnMissingBean ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
@Configuration
public class CommonConfig {
@Bean
@ConditionalOnMissingBean ( SpringContextHolder . class )
public SpringContextHolder springContextHolder ( ) {
SpringContextHolder holder = new SpringContextHolder ( ) ;
return holder;
}
}
3-9:CommonSendStatus
package com. test. order. config ;
public interface CommonSendStatus {
public static final String UNPUBLISHED_STATUS_0 = "0" ;
public static final String PUBLISHED_STATUS_1 = "1" ;
public static final String REVOKE_STATUS_2 = "2" ;
public static final String APP_SESSION_SUFFIX = "_app" ;
public static final String TZMB_BPM_CUIBAN = "bpm_cuiban" ;
public static final String TZMB_BPM_CC = "bpm_cc" ;
public static final String TZMB_BPM_CUIBAN_EMAIL = "bpm_cuiban_email" ;
public static final String TZMB_SYS_TS_NOTE = "sys_ts_note" ;
public static final String TZMB_BPM_CHAOSHI_TIP = "bpm_chaoshi_tip" ;
public static final String MSG_ABSTRACT_JSON = "msg_abstract" ;
}
3-10:GlobalConstants
package com. test. order. config ;
public class GlobalConstants {
public static final String HANDLER_NAME = "handlerName" ;
public static final String LODER_ROUDER_HANDLER = "loderRouderHandler" ;
public static final String REDIS_TOPIC_NAME = "jeecg_redis_topic" ;
}
3-11:JeecgRedisCacheWriter
package com. test. order. config ;
import java. nio. charset. StandardCharsets ;
import java. time. Duration ;
import java. util. Collections ;
import java. util. Optional ;
import java. util. Set ;
import java. util. concurrent. TimeUnit ;
import java. util. function. Consumer ;
import java. util. function. Function ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. dao. PessimisticLockingFailureException ;
import org. springframework. data. redis. cache. CacheStatistics ;
import org. springframework. data. redis. cache. CacheStatisticsCollector ;
import org. springframework. data. redis. cache. RedisCacheWriter ;
import org. springframework. data. redis. connection. RedisConnection ;
import org. springframework. data. redis. connection. RedisConnectionFactory ;
import org. springframework. data. redis. connection. RedisStringCommands . SetOption ;
import org. springframework. data. redis. core. types. Expiration ;
import org. springframework. lang. Nullable ;
import org. springframework. util. Assert ;
@Slf4j
public class JeecgRedisCacheWriter implements RedisCacheWriter {
private final RedisConnectionFactory connectionFactory;
private final Duration sleepTime;
public JeecgRedisCacheWriter ( RedisConnectionFactory connectionFactory) {
this ( connectionFactory, Duration . ZERO ) ;
}
public JeecgRedisCacheWriter ( RedisConnectionFactory connectionFactory, Duration sleepTime) {
Assert . notNull ( connectionFactory, "ConnectionFactory must not be null!" ) ;
Assert . notNull ( sleepTime, "SleepTime must not be null!" ) ;
this . connectionFactory = connectionFactory;
this . sleepTime = sleepTime;
}
@Override
public void put ( String name, byte [ ] key, byte [ ] value, @Nullable Duration ttl) {
Assert . notNull ( name, "Name must not be null!" ) ;
Assert . notNull ( key, "Key must not be null!" ) ;
Assert . notNull ( value, "Value must not be null!" ) ;
this . execute ( name, ( connection) -> {
if ( shouldExpireWithin ( ttl) ) {
connection. set ( key, value, Expiration . from ( ttl. toMillis ( ) , TimeUnit . MILLISECONDS ) , SetOption . upsert ( ) ) ;
} else {
connection. set ( key, value) ;
}
return "OK" ;
} ) ;
}
@Override
public byte [ ] get ( String name, byte [ ] key) {
Assert . notNull ( name, "Name must not be null!" ) ;
Assert . notNull ( key, "Key must not be null!" ) ;
return ( byte [ ] ) this . execute ( name, ( connection) -> {
return connection. get ( key) ;
} ) ;
}
@Override
public byte [ ] putIfAbsent ( String name, byte [ ] key, byte [ ] value, @Nullable Duration ttl) {
Assert . notNull ( name, "Name must not be null!" ) ;
Assert . notNull ( key, "Key must not be null!" ) ;
Assert . notNull ( value, "Value must not be null!" ) ;
return ( byte [ ] ) this . execute ( name, ( connection) -> {
if ( this . isLockingCacheWriter ( ) ) {
this . doLock ( name, connection) ;
}
Object var7;
try {
boolean put;
if ( shouldExpireWithin ( ttl) ) {
put = connection. set ( key, value, Expiration . from ( ttl) , SetOption . ifAbsent ( ) ) ;
} else {
put = connection. setNX ( key, value) ;
}
if ( ! put) {
byte [ ] var11 = connection. get ( key) ;
return var11;
}
var7 = null ;
} finally {
if ( this . isLockingCacheWriter ( ) ) {
this . doUnlock ( name, connection) ;
}
}
return ( byte [ ] ) var7;
} ) ;
}
@Override
public void remove ( String name, byte [ ] key) {
Assert . notNull ( name, "Name must not be null!" ) ;
Assert . notNull ( key, "Key must not be null!" ) ;
String keyString = new String ( key) ;
log. info ( "redis remove key:" + keyString) ;
String keyIsAll = "*" ;
if ( keyString!= null && keyString. endsWith ( keyIsAll) ) {
execute ( name, connection -> {
Set < byte [ ] > keys = connection. keys ( key) ;
int delNum = 0 ;
for ( byte [ ] keyByte : keys) {
delNum += connection. del ( keyByte) ;
}
return delNum;
} ) ;
} else {
this . execute ( name, ( connection) -> {
return connection. del ( new byte [ ] [ ] { key} ) ;
} ) ;
}
}
@Override
public void clean ( String name, byte [ ] pattern) {
Assert . notNull ( name, "Name must not be null!" ) ;
Assert . notNull ( pattern, "Pattern must not be null!" ) ;
this . execute ( name, ( connection) -> {
boolean wasLocked = false ;
try {
if ( this . isLockingCacheWriter ( ) ) {
this . doLock ( name, connection) ;
wasLocked = true ;
}
byte [ ] [ ] keys = ( byte [ ] [ ] ) ( ( Set ) Optional . ofNullable ( connection. keys ( pattern) ) . orElse ( Collections . emptySet ( ) ) ) . toArray ( new byte [ 0 ] [ ] ) ;
if ( keys. length > 0 ) {
connection. del ( keys) ;
}
} finally {
if ( wasLocked && this . isLockingCacheWriter ( ) ) {
this . doUnlock ( name, connection) ;
}
}
return "OK" ;
} ) ;
}
void lock ( String name) {
this . execute ( name, ( connection) -> {
return this . doLock ( name, connection) ;
} ) ;
}
void unlock ( String name) {
this . executeLockFree ( ( connection) -> {
this . doUnlock ( name, connection) ;
} ) ;
}
private Boolean doLock ( String name, RedisConnection connection) {
return connection. setNX ( createCacheLockKey ( name) , new byte [ 0 ] ) ;
}
private Long doUnlock ( String name, RedisConnection connection) {
return connection. del ( new byte [ ] [ ] { createCacheLockKey ( name) } ) ;
}
boolean doCheckLock ( String name, RedisConnection connection) {
return connection. exists ( createCacheLockKey ( name) ) ;
}
private boolean isLockingCacheWriter ( ) {
return ! this . sleepTime. isZero ( ) && ! this . sleepTime. isNegative ( ) ;
}
private < T > T execute ( String name, Function < RedisConnection , T > callback) {
RedisConnection connection = this . connectionFactory. getConnection ( ) ;
try {
this . checkAndPotentiallyWaitUntilUnlocked ( name, connection) ;
return callback. apply ( connection) ;
} finally {
connection. close ( ) ;
}
}
private void executeLockFree ( Consumer < RedisConnection > callback) {
RedisConnection connection = this . connectionFactory. getConnection ( ) ;
try {
callback. accept ( connection) ;
} finally {
connection. close ( ) ;
}
}
private void checkAndPotentiallyWaitUntilUnlocked ( String name, RedisConnection connection) {
if ( this . isLockingCacheWriter ( ) ) {
try {
while ( this . doCheckLock ( name, connection) ) {
Thread . sleep ( this . sleepTime. toMillis ( ) ) ;
}
} catch ( InterruptedException var4) {
Thread . currentThread ( ) . interrupt ( ) ;
throw new PessimisticLockingFailureException ( String . format ( "Interrupted while waiting to unlock cache %s" , name) , var4) ;
}
}
}
private static boolean shouldExpireWithin ( @Nullable Duration ttl) {
return ttl != null && ! ttl. isZero ( ) && ! ttl. isNegative ( ) ;
}
private static byte [ ] createCacheLockKey ( String name) {
return ( name + "~lock" ) . getBytes ( StandardCharsets . UTF_8 ) ;
}
private final CacheStatisticsCollector statistics = CacheStatisticsCollector . create ( ) ;
@Override
public CacheStatistics getCacheStatistics ( String cacheName) {
return statistics. getCacheStatistics ( cacheName) ;
}
@Override
public void clearStatistics ( String name) {
}
@Override
public RedisCacheWriter withStatisticsCollector ( CacheStatisticsCollector cacheStatisticsCollector) {
return null ;
}
}
3-12:RedisUtil
package com. test. order. config ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. data. redis. core. RedisTemplate ;
import org. springframework. stereotype. Component ;
import java. util. Arrays ;
import java. util. List ;
import java. util. Map ;
import java. util. Set ;
import java. util. concurrent. TimeUnit ;
@Component
public class RedisUtil {
@Autowired
private RedisTemplate < String , Object > redisTemplate;
public RedisUtil ( ) {
}
public boolean expire ( String key, long time) {
try {
if ( time > 0L ) {
this . redisTemplate. expire ( key, time, TimeUnit . SECONDS ) ;
}
return true ;
} catch ( Exception var5) {
var5. printStackTrace ( ) ;
return false ;
}
}
public long getExpire ( String key) {
return this . redisTemplate. getExpire ( key, TimeUnit . SECONDS ) ;
}
public boolean hasKey ( String key) {
try {
return this . redisTemplate. hasKey ( key) ;
} catch ( Exception var3) {
var3. printStackTrace ( ) ;
return false ;
}
}
public void del ( String . . . key) {
if ( key != null && key. length > 0 ) {
if ( key. length == 1 ) {
this . redisTemplate. delete ( key[ 0 ] ) ;
} else {
this . redisTemplate. delete ( Arrays . asList ( key) ) ;
}
}
}
public Object get ( String key) {
return key == null ? null : this . redisTemplate. opsForValue ( ) . get ( key) ;
}
public boolean set ( String key, Object value) {
try {
this . redisTemplate. opsForValue ( ) . set ( key, value) ;
return true ;
} catch ( Exception var4) {
var4. printStackTrace ( ) ;
return false ;
}
}
public boolean set ( String key, Object value, long time) {
try {
if ( time > 0L ) {
this . redisTemplate. opsForValue ( ) . set ( key, value, time, TimeUnit . SECONDS ) ;
} else {
this . set ( key, value) ;
}
return true ;
} catch ( Exception var6) {
var6. printStackTrace ( ) ;
return false ;
}
}
public long incr ( String key, long delta) {
if ( delta < 0L ) {
throw new RuntimeException ( "递增因子必须大于0" ) ;
} else {
return this . redisTemplate. opsForValue ( ) . increment ( key, delta) ;
}
}
public long decr ( String key, long delta) {
if ( delta < 0L ) {
throw new RuntimeException ( "递减因子必须大于0" ) ;
} else {
return this . redisTemplate. opsForValue ( ) . increment ( key, - delta) ;
}
}
public Object hget ( String key, String item) {
return this . redisTemplate. opsForHash ( ) . get ( key, item) ;
}
public Map < Object , Object > hmget ( String key) {
return this . redisTemplate. opsForHash ( ) . entries ( key) ;
}
public boolean hmset ( String key, Map < String , Object > map) {
try {
this . redisTemplate. opsForHash ( ) . putAll ( key, map) ;
return true ;
} catch ( Exception var4) {
var4. printStackTrace ( ) ;
return false ;
}
}
public boolean hmset ( String key, Map < String , Object > map, long time) {
try {
this . redisTemplate. opsForHash ( ) . putAll ( key, map) ;
if ( time > 0L ) {
this . expire ( key, time) ;
}
return true ;
} catch ( Exception var6) {
var6. printStackTrace ( ) ;
return false ;
}
}
public boolean hset ( String key, String item, Object value) {
try {
this . redisTemplate. opsForHash ( ) . put ( key, item, value) ;
return true ;
} catch ( Exception var5) {
var5. printStackTrace ( ) ;
return false ;
}
}
public boolean hset ( String key, String item, Object value, long time) {
try {
this . redisTemplate. opsForHash ( ) . put ( key, item, value) ;
if ( time > 0L ) {
this . expire ( key, time) ;
}
return true ;
} catch ( Exception var7) {
var7. printStackTrace ( ) ;
return false ;
}
}
public void hdel ( String key, Object . . . item) {
this . redisTemplate. opsForHash ( ) . delete ( key, item) ;
}
public boolean hHasKey ( String key, String item) {
return this . redisTemplate. opsForHash ( ) . hasKey ( key, item) ;
}
public double hincr ( String key, String item, double by) {
return this . redisTemplate. opsForHash ( ) . increment ( key, item, by) ;
}
public double hdecr ( String key, String item, double by) {
return this . redisTemplate. opsForHash ( ) . increment ( key, item, - by) ;
}
public Set < Object > sGet ( String key) {
try {
return this . redisTemplate. opsForSet ( ) . members ( key) ;
} catch ( Exception var3) {
var3. printStackTrace ( ) ;
return null ;
}
}
public boolean sHasKey ( String key, Object value) {
try {
return this . redisTemplate. opsForSet ( ) . isMember ( key, value) ;
} catch ( Exception var4) {
var4. printStackTrace ( ) ;
return false ;
}
}
public long sSet ( String key, Object . . . values) {
try {
return this . redisTemplate. opsForSet ( ) . add ( key, values) ;
} catch ( Exception var4) {
var4. printStackTrace ( ) ;
return 0L ;
}
}
public long sSetAndTime ( String key, long time, Object . . . values) {
try {
Long count = this . redisTemplate. opsForSet ( ) . add ( key, values) ;
if ( time > 0L ) {
this . expire ( key, time) ;
}
return count;
} catch ( Exception var6) {
var6. printStackTrace ( ) ;
return 0L ;
}
}
public long sGetSetSize ( String key) {
try {
return this . redisTemplate. opsForSet ( ) . size ( key) ;
} catch ( Exception var3) {
var3. printStackTrace ( ) ;
return 0L ;
}
}
public long setRemove ( String key, Object . . . values) {
try {
Long count = this . redisTemplate. opsForSet ( ) . remove ( key, values) ;
return count;
} catch ( Exception var4) {
var4. printStackTrace ( ) ;
return 0L ;
}
}
public List < Object > lGet ( String key, long start, long end) {
try {
return this . redisTemplate. opsForList ( ) . range ( key, start, end) ;
} catch ( Exception var7) {
var7. printStackTrace ( ) ;
return null ;
}
}
public long lGetListSize ( String key) {
try {
return this . redisTemplate. opsForList ( ) . size ( key) ;
} catch ( Exception var3) {
var3. printStackTrace ( ) ;
return 0L ;
}
}
public Object lGetIndex ( String key, long index) {
try {
return this . redisTemplate. opsForList ( ) . index ( key, index) ;
} catch ( Exception var5) {
var5. printStackTrace ( ) ;
return null ;
}
}
public boolean lSet ( String key, Object value) {
try {
this . redisTemplate. opsForList ( ) . rightPush ( key, value) ;
return true ;
} catch ( Exception var4) {
var4. printStackTrace ( ) ;
return false ;
}
}
public boolean lSet ( String key, Object value, long time) {
try {
this . redisTemplate. opsForList ( ) . rightPush ( key, value) ;
if ( time > 0L ) {
this . expire ( key, time) ;
}
return true ;
} catch ( Exception var6) {
var6. printStackTrace ( ) ;
return false ;
}
}
public boolean lSet ( String key, List < Object > value) {
try {
this . redisTemplate. opsForList ( ) . rightPushAll ( key, value) ;
return true ;
} catch ( Exception var4) {
var4. printStackTrace ( ) ;
return false ;
}
}
public boolean lSet ( String key, List < Object > value, long time) {
try {
this . redisTemplate. opsForList ( ) . rightPushAll ( key, value) ;
if ( time > 0L ) {
this . expire ( key, time) ;
}
return true ;
} catch ( Exception var6) {
var6. printStackTrace ( ) ;
return false ;
}
}
public boolean lUpdateIndex ( String key, long index, Object value) {
try {
this . redisTemplate. opsForList ( ) . set ( key, index, value) ;
return true ;
} catch ( Exception var6) {
var6. printStackTrace ( ) ;
return false ;
}
}
public long lRemove ( String key, long count, Object value) {
try {
Long remove = this . redisTemplate. opsForList ( ) . remove ( key, count, value) ;
return remove;
} catch ( Exception var6) {
var6. printStackTrace ( ) ;
return 0L ;
}
}
}
3-13:SocketHandler
package com. test. order. config ;
import cn. hutool. core. util. ObjectUtil ;
import com. test. order. controller. OrderController ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. stereotype. Component ;
@Slf4j
@Component ( WebSocket . REDIS_TOPIC_NAME )
public class SocketHandler implements JeecgRedisListener {
@Autowired
private WebSocket webSocket;
@Override
public void onMessage ( BaseMap map) {
log. info ( "【Redis发布订阅模式】redis Listener: {},参数:{}" , WebSocket . REDIS_TOPIC_NAME , map. toString ( ) ) ;
String userId = map. get ( "userId" ) ;
String message = map. get ( "message" ) ;
if ( ObjectUtil . isNotEmpty ( userId) ) {
webSocket. pushMessage ( userId, message) ;
webSocket. pushMessage ( userId+ CommonSendStatus . APP_SESSION_SUFFIX , message) ;
} else {
webSocket. pushMessage ( message) ;
}
}
}
3-14:SpringContextHolder
package com. test. order. config ;
import cn. hutool. core. util. ObjectUtil ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. context. ApplicationContext ;
import org. springframework. context. ApplicationContextAware ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. stereotype. Component ;
@Slf4j
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext ( ApplicationContext applicationContext) {
SpringContextHolder . applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext ( ) {
checkApplicationContext ( ) ;
return applicationContext;
}
public static < T > T getBean ( String name) {
checkApplicationContext ( ) ;
return ( T ) applicationContext. getBean ( name) ;
}
public static < T > T getHandler ( String name, Class < T > cls) {
T t = null ;
if ( ObjectUtil . isNotEmpty ( name) ) {
checkApplicationContext ( ) ;
try {
t = applicationContext. getBean ( name, cls) ;
} catch ( Exception e) {
log. warn ( "Customize redis listener handle [ " + name + " ], does not exist!" ) ;
}
}
return t;
}
public static < T > T getBean ( Class < T > clazz) {
checkApplicationContext ( ) ;
return applicationContext. getBean ( clazz) ;
}
public static void cleanApplicationContext ( ) {
applicationContext = null ;
}
private static void checkApplicationContext ( ) {
if ( applicationContext == null ) {
throw new IllegalStateException ( "applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder" ) ;
}
}
}
3-15:WebsocketConst
package com. test. order. config ;
public class WebsocketConst {
public static final String MSG_CMD = "cmd" ;
public static final String MSG_ID = "msgId" ;
public static final String MSG_TXT = "msgTxt" ;
public static final String MSG_USER_ID = "userId" ;
public static final String MSG_CHAT = "chat" ;
public static final String CMD_CHECK = "heartcheck" ;
public static final String CMD_USER = "user" ;
public static final String CMD_TOPIC = "topic" ;
public static final String CMD_EMAIL = "email" ;
public static final String CMD_SIGN = "sign" ;
public static final String NEWS_PUBLISH = "publish" ;
}
3-16:WebSocket
package com. test. order. config ;
import java. util. Map ;
import java. util. concurrent. ConcurrentHashMap ;
import javax. websocket. * ;
import javax. websocket. server. PathParam ;
import javax. websocket. server. ServerEndpoint ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. stereotype. Component ;
import lombok. extern. slf4j. Slf4j ;
@Component
@Slf4j
@ServerEndpoint ( "/websocket/{userId}" )
public class WebSocket {
private static ConcurrentHashMap < String , Session > sessionPool = new ConcurrentHashMap < > ( ) ;
public static final String REDIS_TOPIC_NAME = "socketHandler" ;
@Autowired
private JeecgRedisClient jeecgRedisClient;
@OnOpen
public void onOpen ( Session session, @PathParam ( value = "userId" ) String userId) {
try {
sessionPool. put ( userId, session) ;
log. info ( "【系统 WebSocket】有新的连接,总数为:" + sessionPool. size ( ) ) ;
} catch ( Exception e) {
}
}
@OnClose
public void onClose ( @PathParam ( "userId" ) String userId) {
try {
sessionPool. remove ( userId) ;
log. info ( "【系统 WebSocket】连接断开,总数为:" + sessionPool. size ( ) ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
public void pushMessage ( String userId, String message) {
for ( Map. Entry < String , Session > item : sessionPool. entrySet ( ) ) {
if ( item. getKey ( ) . contains ( userId) ) {
Session session = item. getValue ( ) ;
try {
synchronized ( session) {
log. debug ( "【系统 WebSocket】推送单人消息:" + message) ;
session. getBasicRemote ( ) . sendText ( message) ;
}
} catch ( Exception e) {
log. error ( e. getMessage ( ) , e) ;
}
}
}
}
public void pushMessage ( String message) {
try {
for ( Map. Entry < String , Session > item : sessionPool. entrySet ( ) ) {
try {
item. getValue ( ) . getAsyncRemote ( ) . sendText ( message) ;
} catch ( Exception e) {
log. error ( e. getMessage ( ) , e) ;
}
}
log. debug ( "【系统 WebSocket】群发消息:" + message) ;
} catch ( Exception e) {
log. error ( e. getMessage ( ) , e) ;
}
}
@OnMessage
public void onMessage ( String message, @PathParam ( value = "userId" ) String userId) {
if ( ! "ping" . equals ( message) && ! WebsocketConst . CMD_CHECK . equals ( message) ) {
log. debug ( "【系统 WebSocket】收到客户端消息:" + message) ;
} else {
log. debug ( "【系统 WebSocket】收到客户端消息:" + message) ;
}
}
@OnError
public void onError ( Session session, Throwable t) {
log. warn ( "【系统 WebSocket】消息出现错误" ) ;
t. printStackTrace ( ) ;
}
public void sendMessage ( String message) {
BaseMap baseMap = new BaseMap ( ) ;
baseMap. put ( "userId" , "" ) ;
baseMap. put ( "message" , message) ;
jeecgRedisClient. sendMessage ( WebSocket . REDIS_TOPIC_NAME , baseMap) ;
}
public void sendMessage ( String userId, String message) {
BaseMap baseMap = new BaseMap ( ) ;
baseMap. put ( "userId" , userId) ;
baseMap. put ( "message" , message) ;
jeecgRedisClient. sendMessage ( WebSocket . REDIS_TOPIC_NAME , baseMap) ;
}
public void sendMessage ( String [ ] userIds, String message) {
for ( String userId : userIds) {
sendMessage ( userId, message) ;
}
}
}
WebSocket 使用@ServerEndpoint生效需要注入一下bean,如果需要WebSocket 认证功能点击连接去查看
@Bean
public ServerEndpointExporter serverEndpointExporter ( ) {
return new ServerEndpointExporter ( ) ;
}
3-17:OrderController
package com. test. order. controller ;
import com. alibaba. fastjson. JSONObject ;
import com. test. order. config. WebSocket ;
import com. test. order. config. WebsocketConst ;
import org. springframework. web. bind. annotation. RequestMapping ;
import org. springframework. web. bind. annotation. RestController ;
import javax. annotation. Resource ;
@RestController
@RequestMapping ( "/order" )
public class OrderController {
@Resource
WebSocket webSocket;
@RequestMapping ( "/test" )
public void add ( ) {
String message= "message22" ;
JSONObject obj = new JSONObject ( ) ;
obj. put ( WebsocketConst . MSG_CMD , WebsocketConst . CMD_TOPIC ) ;
obj. put ( WebsocketConst . MSG_ID , "M0001" ) ;
obj. put ( WebsocketConst . MSG_TXT , message) ;
webSocket. sendMessage ( obj. toJSONString ( ) ) ;
}
}