From caa16bca42ef0292f0d28f4e5888afa185d869b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8D=95=E9=A3=8E=E7=9A=84=E9=80=8D=E9=81=A5=E4=BE=AF?= Date: Sat, 25 Mar 2023 22:47:54 +0800 Subject: [PATCH 1/5] =?UTF-8?q?redis=E7=9A=84localDateTime=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E5=8C=96=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/service/impl/UserServiceImpl.java | 3 + app/src/main/resources/application-beta.yml | 34 +++-- app/src/main/resources/application-test.yml | 34 +++-- common/build.gradle | 3 + .../common/configuration/BeanConfig.java | 3 + .../common/redis/DistributedLockHandler.java | 58 ++++++++ .../hxy/dream/common/redis/RedisConfig.java | 136 ++++++++++++++++++ .../common/redis/RedisConfigCacheManager.java | 66 +++++++++ .../LocalDateTimeJsonSerializer.java | 28 ++++ 9 files changed, 337 insertions(+), 28 deletions(-) create mode 100644 common/src/main/java/hxy/dream/common/redis/DistributedLockHandler.java create mode 100644 common/src/main/java/hxy/dream/common/redis/RedisConfig.java create mode 100644 common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java create mode 100644 common/src/main/java/hxy/dream/common/serializer/LocalDateTimeJsonSerializer.java diff --git a/app/src/main/java/hxy/dream/app/service/impl/UserServiceImpl.java b/app/src/main/java/hxy/dream/app/service/impl/UserServiceImpl.java index 7528f64..fa9ba0e 100644 --- a/app/src/main/java/hxy/dream/app/service/impl/UserServiceImpl.java +++ b/app/src/main/java/hxy/dream/app/service/impl/UserServiceImpl.java @@ -8,9 +8,11 @@ import hxy.dream.dao.model.UserModel; import hxy.dream.entity.enums.GenderEnum; import hxy.dream.entity.vo.BaseResponseVO; import lombok.extern.slf4j.Slf4j; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; + import java.util.List; /** @@ -40,6 +42,7 @@ public class UserServiceImpl implements UserService { } @Override + @Cacheable(value = "UserService#36000", key = "'getUser'") public UserModel get(String id) { return userMapper.selectById(id); } diff --git a/app/src/main/resources/application-beta.yml b/app/src/main/resources/application-beta.yml index a710040..7db1d0d 100755 --- a/app/src/main/resources/application-beta.yml +++ b/app/src/main/resources/application-beta.yml @@ -19,20 +19,26 @@ spring: sql: init: platform: mysql -# redis: -# database: 0 -# host: 119.23.236.94 -# port: 6379 -# password: newpass -# jedis: -# pool: -# max-active: 8 -# cache: -# redis: -# time-to-live: 0s # 缓存过期时间30分钟 -# type: redis -# rabbitmq: -# host: 119.23.236.94 + data: + # redis 配置 + redis: + # 地址 121.36.136.109 localhost + host: 52.131.246.191 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 3 + # 密码 + password: newpass + # 连接超时时间 + timeout: 10s + jedis: + pool: + min-idle: 10 + max-idle: 20 + max-wait: -1ms + max-active: 200 +# ssl: true logging: level: diff --git a/app/src/main/resources/application-test.yml b/app/src/main/resources/application-test.yml index bd590e2..04087a2 100755 --- a/app/src/main/resources/application-test.yml +++ b/app/src/main/resources/application-test.yml @@ -20,20 +20,26 @@ spring: sql: init: platform: mysql -# redis: -# database: 0 -# host: 119.23.236.94 -# port: 6379 -# password: newpass -# jedis: -# pool: -# max-active: 8 -# cache: -# redis: -# time-to-live: 0s # 缓存过期时间30分钟 -# type: redis -# rabbitmq: -# host: 119.23.236.94 + data: + # redis 配置 + redis: + # 地址 121.36.136.109 localhost + host: 52.131.246.191 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 3 + # 密码 + password: newpass + # 连接超时时间 + timeout: 10s + jedis: + pool: + min-idle: 10 + max-idle: 20 + max-wait: -1ms + max-active: 200 +# ssl: true logging: level: diff --git a/common/build.gradle b/common/build.gradle index 0ec3f28..7e26b0a 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -18,6 +18,9 @@ dependencies { api 'com.ejlchina:okhttps-jackson:3.4.0' api 'org.springframework.boot:spring-boot-starter-mail' + implementation 'org.springframework.data:spring-data-redis' + implementation 'redis.clients:jedis' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.3' implementation group: 'org.javassist', name: 'javassist', version: '3.27.0-GA' implementation group: 'org.aspectj', name: 'aspectjrt', version: '1.9.6' diff --git a/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java b/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java index 0a3568d..890c1e2 100644 --- a/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java +++ b/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java @@ -19,6 +19,7 @@ import hxy.dream.common.serializer.BaseEnumSerializer; import hxy.dream.common.serializer.BaseLongSerializer; import hxy.dream.common.serializer.DateJsonDeserializer; import hxy.dream.common.serializer.DateJsonSerializer; +import hxy.dream.common.serializer.LocalDateTimeJsonSerializer; import hxy.dream.common.serializer.SimpleDeserializersWrapper; import hxy.dream.common.serializer.StringTrimDeserializer; import hxy.dream.entity.enums.BaseEnum; @@ -27,6 +28,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import java.time.LocalDateTime; import java.util.Date; import java.util.TimeZone; @@ -46,6 +48,7 @@ public class BeanConfig { simpleModule.addSerializer(BaseEnum.class, new BaseEnumSerializer()); simpleModule.addSerializer(Date.class, new DateJsonSerializer()); + simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeJsonSerializer()); // 超过浏览器处理精度的Long类型转成String给前端 simpleModule.addSerializer(Long.class, new BaseLongSerializer()); diff --git a/common/src/main/java/hxy/dream/common/redis/DistributedLockHandler.java b/common/src/main/java/hxy/dream/common/redis/DistributedLockHandler.java new file mode 100644 index 0000000..44849a1 --- /dev/null +++ b/common/src/main/java/hxy/dream/common/redis/DistributedLockHandler.java @@ -0,0 +1,58 @@ +package hxy.dream.common.redis; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.concurrent.TimeUnit; + +/** + * 不是很严谨的分布式锁 + */ +@Component +public class DistributedLockHandler { + + private static final Logger log = LoggerFactory.getLogger(DistributedLockHandler.class); + + + public final static long LOCK_EXPIRE = 30 * 1000L; + public final static long LOCK_TRY_INTERVAL = 30L; + public final static long LOCK_TRY_TIMEOUT = 20 * 1000L; + + @Autowired + private RedisTemplate redisTemplate; + + public boolean getLock(String key, String value) { + try { + if (StringUtils.hasLength(key) && StringUtils.hasLength(value)) { + + long startTime = System.currentTimeMillis(); + do { + if (!redisTemplate.hasKey(key)) { + redisTemplate.opsForValue().set(key, value, LOCK_EXPIRE, TimeUnit.MILLISECONDS); + return true; + } + if (System.currentTimeMillis() - startTime > LOCK_TRY_TIMEOUT) { + // 获取锁超时,直接放弃 + return false; + } + Thread.sleep(LOCK_TRY_INTERVAL); + } while (redisTemplate.hasKey(key)); + } + } catch (InterruptedException e) { + log.error("{}", e.getMessage(), e); + return false; + } + return false; + } + + public void releaseLock(String key) { + if (StringUtils.hasLength(key)) { + redisTemplate.delete(key); + } + } + +} diff --git a/common/src/main/java/hxy/dream/common/redis/RedisConfig.java b/common/src/main/java/hxy/dream/common/redis/RedisConfig.java new file mode 100644 index 0000000..1496c39 --- /dev/null +++ b/common/src/main/java/hxy/dream/common/redis/RedisConfig.java @@ -0,0 +1,136 @@ +package hxy.dream.common.redis; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; +import org.springframework.beans.factory.annotation.Autowired; +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.context.annotation.Primary; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +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 org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +import java.time.Duration; +import java.time.format.DateTimeFormatter; + +/** + * redis配置 + * + */ +@Configuration +@EnableCaching +public class RedisConfig extends CachingConfigurerSupport { + + @Autowired + RedisConnectionFactory redisConnectionFactory; + + + @Bean + public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { + Jackson2ObjectMapperBuilder builder = + new Jackson2ObjectMapperBuilder() + .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) + .serializers( + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"))) + .serializationInclusion(JsonInclude.Include.NON_NULL); + return new MappingJackson2HttpMessageConverter(builder.build()); + } + + @Bean + @Primary + public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer(){ + ObjectMapper om = new ObjectMapper(); + // 解决查询缓存转换异常的问题 + om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + // 支持 jdk 1.8 日期 ---- start --- + om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + om.registerModule(new Jdk8Module()) + .registerModule(new JavaTimeModule()) + .registerModule(new ParameterNamesModule()); + // --end -- + GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om); + return genericJackson2JsonRedisSerializer; + } + + + @Bean + @Primary + @SuppressWarnings(value = { "unchecked", "rawtypes" }) + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) + { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + +// Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class); + + ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); +// serializer.setObjectMapper(mapper); + + // 使用StringRedisSerializer来序列化和反序列化redis的key值 + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(genericJackson2JsonRedisSerializer()); + + // Hash的key也采用StringRedisSerializer的序列化方式 + template.setHashKeySerializer(new StringRedisSerializer()); + template.setHashValueSerializer(genericJackson2JsonRedisSerializer()); + template.setEnableTransactionSupport(true); + template.afterPropertiesSet(); + return template; + } + + @Override + @Bean + public CacheManager cacheManager() { + + ObjectMapper om = new ObjectMapper(); + RedisSerializer redisSerializer = new StringRedisSerializer(); + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>( + Object.class); + // 解决查询缓存转换异常的问题 + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + // 支持 jdk 1.8 日期 + om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + om.registerModule(new JavaTimeModule()); + om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + om.registerModule(new Jdk8Module()) + .registerModule(new JavaTimeModule()) + .registerModule(new ParameterNamesModule()); + jackson2JsonRedisSerializer.setObjectMapper(om); + // 配置序列化(解决乱码的问题) + RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() + .entryTtl(Duration.ofMillis(-1)) + .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) + .disableCachingNullValues(); + RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); + + return new RedisConfigCacheManager(cacheWriter, config); + + } + +} diff --git a/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java b/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java new file mode 100644 index 0000000..ddb2ead --- /dev/null +++ b/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java @@ -0,0 +1,66 @@ +package hxy.dream.common.redis; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.cache.CacheKeyPrefix; +import org.springframework.data.redis.cache.RedisCache; +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.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.util.NumberUtils; + +import java.time.Duration; + +/** + * redis 配置类 + */ +@Slf4j +public class RedisConfigCacheManager extends RedisCacheManager { + + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) { + super(cacheWriter, defaultCacheConfiguration); + } + + private static final RedisSerializationContext.SerializationPair DEFAULT_PAIR = RedisSerializationContext.SerializationPair + .fromSerializer(new GenericJackson2JsonRedisSerializer()); + + private static final CacheKeyPrefix DEFAULT_CACHE_KEY_PREFIX = cacheName -> cacheName + ":"; + + @Override + protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) { + + if (name != null && name.length() > 0) { + final int lastIndexOf = name.lastIndexOf('#'); + if (lastIndexOf > -1) { + final String ttl = name.substring(lastIndexOf + 1); + if (isNumeric(ttl)) { + final Duration duration = Duration.ofSeconds(Long.parseLong(ttl)); + cacheConfig = cacheConfig.entryTtl(duration); + //修改缓存key和value值的序列化方式 + cacheConfig = cacheConfig.computePrefixWith(DEFAULT_CACHE_KEY_PREFIX) + .serializeValuesWith(DEFAULT_PAIR); + final String cacheName = name.substring(0, lastIndexOf); + return super.createRedisCache(cacheName, cacheConfig); + } else { + log.error("过期时间配置错误!!!#号后面不是数字 => {}", ttl); + } + } + } + //修改缓存key和value值的序列化方式 + cacheConfig = cacheConfig.computePrefixWith(DEFAULT_CACHE_KEY_PREFIX) + .serializeValuesWith(DEFAULT_PAIR); + return super.createRedisCache(name, cacheConfig); + } + + public static boolean isNumeric(String str) { + for (int i = str.length(); --i >= 0; ) { + if (!Character.isDigit(str.charAt(i))) { + return false; + } + } + return true; + } + +} \ No newline at end of file diff --git a/common/src/main/java/hxy/dream/common/serializer/LocalDateTimeJsonSerializer.java b/common/src/main/java/hxy/dream/common/serializer/LocalDateTimeJsonSerializer.java new file mode 100644 index 0000000..c9a3b48 --- /dev/null +++ b/common/src/main/java/hxy/dream/common/serializer/LocalDateTimeJsonSerializer.java @@ -0,0 +1,28 @@ +package hxy.dream.common.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +/** + * 或者直接yaml文件配置也是可以的 spring.jackson.date-format + */ +public class LocalDateTimeJsonSerializer extends JsonSerializer { + + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + ZoneId zoneId = ZoneId.systemDefault(); + + @Override + public void serialize(LocalDateTime date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { +// LocalDateTime localDateTime = date.toInstant().atZone(zoneId).toLocalDateTime(); + String yearMonth = date.format(dtf); + jsonGenerator.writeString(yearMonth); + } + +} \ No newline at end of file -- Gitee From 7e14f1dd04a8c47d7eca311a6242e3e4652b5e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8D=95=E9=A3=8E=E7=9A=84=E9=80=8D=E9=81=A5=E4=BE=AF?= Date: Sun, 26 Mar 2023 11:14:44 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=BF=99=E4=B8=80?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=B0=B1=E4=BC=9A=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/service/impl/UserServiceImpl.java | 3 +- .../common/configuration/BeanConfig.java | 3 - .../hxy/dream/common/redis/RedisConfig.java | 110 ++++++++---------- .../common/redis/RedisConfigCacheManager.java | 1 - .../LocalDateTimeJsonSerializer.java | 28 ----- 5 files changed, 52 insertions(+), 93 deletions(-) delete mode 100644 common/src/main/java/hxy/dream/common/serializer/LocalDateTimeJsonSerializer.java diff --git a/app/src/main/java/hxy/dream/app/service/impl/UserServiceImpl.java b/app/src/main/java/hxy/dream/app/service/impl/UserServiceImpl.java index fa9ba0e..f02b1fe 100644 --- a/app/src/main/java/hxy/dream/app/service/impl/UserServiceImpl.java +++ b/app/src/main/java/hxy/dream/app/service/impl/UserServiceImpl.java @@ -44,7 +44,8 @@ public class UserServiceImpl implements UserService { @Override @Cacheable(value = "UserService#36000", key = "'getUser'") public UserModel get(String id) { - return userMapper.selectById(id); + UserModel userModel = userMapper.selectById(id); + return userModel; } @Override diff --git a/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java b/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java index 890c1e2..0a3568d 100644 --- a/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java +++ b/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java @@ -19,7 +19,6 @@ import hxy.dream.common.serializer.BaseEnumSerializer; import hxy.dream.common.serializer.BaseLongSerializer; import hxy.dream.common.serializer.DateJsonDeserializer; import hxy.dream.common.serializer.DateJsonSerializer; -import hxy.dream.common.serializer.LocalDateTimeJsonSerializer; import hxy.dream.common.serializer.SimpleDeserializersWrapper; import hxy.dream.common.serializer.StringTrimDeserializer; import hxy.dream.entity.enums.BaseEnum; @@ -28,7 +27,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; -import java.time.LocalDateTime; import java.util.Date; import java.util.TimeZone; @@ -48,7 +46,6 @@ public class BeanConfig { simpleModule.addSerializer(BaseEnum.class, new BaseEnumSerializer()); simpleModule.addSerializer(Date.class, new DateJsonSerializer()); - simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeJsonSerializer()); // 超过浏览器处理精度的Long类型转成String给前端 simpleModule.addSerializer(Long.class, new BaseLongSerializer()); diff --git a/common/src/main/java/hxy/dream/common/redis/RedisConfig.java b/common/src/main/java/hxy/dream/common/redis/RedisConfig.java index 1496c39..d9895eb 100644 --- a/common/src/main/java/hxy/dream/common/redis/RedisConfig.java +++ b/common/src/main/java/hxy/dream/common/redis/RedisConfig.java @@ -1,15 +1,11 @@ package hxy.dream.common.redis; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; @@ -19,6 +15,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; 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.core.RedisTemplate; @@ -27,15 +24,13 @@ 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 org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.time.Duration; -import java.time.format.DateTimeFormatter; +import java.util.HashSet; +import java.util.Set; /** * redis配置 - * */ @Configuration @EnableCaching @@ -44,21 +39,9 @@ public class RedisConfig extends CachingConfigurerSupport { @Autowired RedisConnectionFactory redisConnectionFactory; - - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - Jackson2ObjectMapperBuilder builder = - new Jackson2ObjectMapperBuilder() - .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) - .serializers( - new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"))) - .serializationInclusion(JsonInclude.Include.NON_NULL); - return new MappingJackson2HttpMessageConverter(builder.build()); - } - @Bean @Primary - public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer(){ + public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer() { ObjectMapper om = new ObjectMapper(); // 解决查询缓存转换异常的问题 om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); @@ -70,47 +53,37 @@ public class RedisConfig extends CachingConfigurerSupport { .registerModule(new JavaTimeModule()) .registerModule(new ParameterNamesModule()); // --end -- - GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om); + GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om); return genericJackson2JsonRedisSerializer; } - @Bean @Primary - @SuppressWarnings(value = { "unchecked", "rawtypes" }) - public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) - { - RedisTemplate template = new RedisTemplate<>(); - template.setConnectionFactory(connectionFactory); - -// Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class); - - ObjectMapper mapper = new ObjectMapper(); - mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); - mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); -// serializer.setObjectMapper(mapper); - - // 使用StringRedisSerializer来序列化和反序列化redis的key值 - template.setKeySerializer(new StringRedisSerializer()); - template.setValueSerializer(genericJackson2JsonRedisSerializer()); - - // Hash的key也采用StringRedisSerializer的序列化方式 - template.setHashKeySerializer(new StringRedisSerializer()); - template.setHashValueSerializer(genericJackson2JsonRedisSerializer()); - template.setEnableTransactionSupport(true); - template.afterPropertiesSet(); - return template; + public RedisTemplate redisTemplate() { + + RedisTemplate redisTemplate = new RedisTemplate(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + // 这里 + redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer()); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + // 这里 + redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer()); + redisTemplate.setEnableTransactionSupport(true); + redisTemplate.afterPropertiesSet(); + return redisTemplate; } - @Override @Bean + @Override public CacheManager cacheManager() { + // 设置序列化 + RedisSerializer stringSerializer = new StringRedisSerializer(); + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + + //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); - RedisSerializer redisSerializer = new StringRedisSerializer(); - Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>( - Object.class); - // 解决查询缓存转换异常的问题 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); // 支持 jdk 1.8 日期 @@ -121,16 +94,33 @@ public class RedisConfig extends CachingConfigurerSupport { .registerModule(new JavaTimeModule()) .registerModule(new ParameterNamesModule()); jackson2JsonRedisSerializer.setObjectMapper(om); - // 配置序列化(解决乱码的问题) + RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() - .entryTtl(Duration.ofMillis(-1)) - .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) + .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) - .disableCachingNullValues(); - RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); - - return new RedisConfigCacheManager(cacheWriter, config); - + .disableCachingNullValues() + // 缓存过期时间 + .entryTtl(Duration.ofMinutes(30)); + + boolean ok = false; + if (ok) { + // TODO 这一部分不会报错,但是redis的缓存失效时间就没有实现了 + RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder + .fromConnectionFactory(redisConnectionFactory) + .cacheDefaults(config) + .transactionAware(); + @SuppressWarnings("serial") + Set cacheNames = new HashSet() { + { + add("codeNameCache"); + } + }; + builder.initialCacheNames(cacheNames); + return builder.build(); + } else { + // FIXME 使用这一部分就会报错 + RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); + return new RedisConfigCacheManager(cacheWriter, config); + } } - } diff --git a/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java b/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java index ddb2ead..8857f57 100644 --- a/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java +++ b/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java @@ -8,7 +8,6 @@ import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheWriter; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; -import org.springframework.util.NumberUtils; import java.time.Duration; diff --git a/common/src/main/java/hxy/dream/common/serializer/LocalDateTimeJsonSerializer.java b/common/src/main/java/hxy/dream/common/serializer/LocalDateTimeJsonSerializer.java deleted file mode 100644 index c9a3b48..0000000 --- a/common/src/main/java/hxy/dream/common/serializer/LocalDateTimeJsonSerializer.java +++ /dev/null @@ -1,28 +0,0 @@ -package hxy.dream.common.serializer; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.util.Date; - -/** - * 或者直接yaml文件配置也是可以的 spring.jackson.date-format - */ -public class LocalDateTimeJsonSerializer extends JsonSerializer { - - DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - ZoneId zoneId = ZoneId.systemDefault(); - - @Override - public void serialize(LocalDateTime date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { -// LocalDateTime localDateTime = date.toInstant().atZone(zoneId).toLocalDateTime(); - String yearMonth = date.format(dtf); - jsonGenerator.writeString(yearMonth); - } - -} \ No newline at end of file -- Gitee From 9afede7be63968e4d1b1e2dd5630f4d8e5792b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8D=95=E9=A3=8E=E7=9A=84=E9=80=8D=E9=81=A5=E4=BE=AF?= Date: Sun, 26 Mar 2023 11:56:37 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E8=BD=AC=E6=8D=A2=E5=BC=82=E5=B8=B8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/configuration/BeanConfig.java | 17 ++++++++++++ .../hxy/dream/common/redis/RedisConfig.java | 26 +++++-------------- .../common/redis/RedisConfigCacheManager.java | 15 +++++++++-- .../serializer/DefaultInputJsonToEnum.java | 2 +- .../java/hxy/dream/entity/enums/BaseEnum.java | 2 ++ 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java b/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java index 0a3568d..2a59104 100644 --- a/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java +++ b/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java @@ -11,9 +11,15 @@ import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import hxy.dream.common.serializer.BaseEnumDeserializer; import hxy.dream.common.serializer.BaseEnumSerializer; import hxy.dream.common.serializer.BaseLongSerializer; @@ -57,6 +63,17 @@ public class BeanConfig { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); objectMapper.registerModule(simpleModule); + // 解决查询缓存转换异常的问题 + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + // 支持 jdk 1.8 日期 ---- start --- + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.registerModule(new Jdk8Module()) + .registerModule(new JavaTimeModule()) + .registerModule(new ParameterNamesModule()); + // --end -- + // 配置忽略未知属性 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); diff --git a/common/src/main/java/hxy/dream/common/redis/RedisConfig.java b/common/src/main/java/hxy/dream/common/redis/RedisConfig.java index d9895eb..2f96df9 100644 --- a/common/src/main/java/hxy/dream/common/redis/RedisConfig.java +++ b/common/src/main/java/hxy/dream/common/redis/RedisConfig.java @@ -39,23 +39,8 @@ public class RedisConfig extends CachingConfigurerSupport { @Autowired RedisConnectionFactory redisConnectionFactory; - @Bean - @Primary - public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer() { - ObjectMapper om = new ObjectMapper(); - // 解决查询缓存转换异常的问题 - om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); - om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); - // 支持 jdk 1.8 日期 ---- start --- - om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - om.registerModule(new Jdk8Module()) - .registerModule(new JavaTimeModule()) - .registerModule(new ParameterNamesModule()); - // --end -- - GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om); - return genericJackson2JsonRedisSerializer; - } + @Autowired + ObjectMapper objectMapper; @Bean @Primary @@ -63,12 +48,13 @@ public class RedisConfig extends CachingConfigurerSupport { RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(redisConnectionFactory); + // 这里 redisTemplate.setKeySerializer(new StringRedisSerializer()); + GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper); + redisTemplate.setValueSerializer(serializer); // 这里 - redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); - // 这里 - redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer()); + redisTemplate.setHashValueSerializer(serializer); redisTemplate.setEnableTransactionSupport(true); redisTemplate.afterPropertiesSet(); return redisTemplate; diff --git a/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java b/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java index 8857f57..887e711 100644 --- a/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java +++ b/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java @@ -1,5 +1,13 @@ package hxy.dream.common.redis; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; +import hxy.dream.common.util.SpringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.cache.CacheKeyPrefix; import org.springframework.data.redis.cache.RedisCache; @@ -22,14 +30,17 @@ public class RedisConfigCacheManager extends RedisCacheManager { super(cacheWriter, defaultCacheConfiguration); } - private static final RedisSerializationContext.SerializationPair DEFAULT_PAIR = RedisSerializationContext.SerializationPair - .fromSerializer(new GenericJackson2JsonRedisSerializer()); private static final CacheKeyPrefix DEFAULT_CACHE_KEY_PREFIX = cacheName -> cacheName + ":"; @Override protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) { + ObjectMapper objectMapper = SpringUtils.getBean(ObjectMapper.class); + + RedisSerializationContext.SerializationPair DEFAULT_PAIR = RedisSerializationContext.SerializationPair + .fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)); + if (name != null && name.length() > 0) { final int lastIndexOf = name.lastIndexOf('#'); if (lastIndexOf > -1) { diff --git a/common/src/main/java/hxy/dream/common/serializer/DefaultInputJsonToEnum.java b/common/src/main/java/hxy/dream/common/serializer/DefaultInputJsonToEnum.java index fb6619f..2e19af9 100644 --- a/common/src/main/java/hxy/dream/common/serializer/DefaultInputJsonToEnum.java +++ b/common/src/main/java/hxy/dream/common/serializer/DefaultInputJsonToEnum.java @@ -29,7 +29,7 @@ public class DefaultInputJsonToEnum { for (BaseEnum value : values) { //因为inputParameter都是string类型的,code转成字符串才能比较 - if (inputParameter.equals(String.valueOf(value.code())) || inputParameter.equals(value.description())) { + if (inputParameter.equals(String.valueOf(value.code())) || inputParameter.equals(value.description())|| inputParameter.equals(value.name())) { baseEnum = value; break; } diff --git a/entity/src/main/java/hxy/dream/entity/enums/BaseEnum.java b/entity/src/main/java/hxy/dream/entity/enums/BaseEnum.java index cb60938..5a2fdc1 100644 --- a/entity/src/main/java/hxy/dream/entity/enums/BaseEnum.java +++ b/entity/src/main/java/hxy/dream/entity/enums/BaseEnum.java @@ -20,4 +20,6 @@ public interface BaseEnum { */ String description(); + String name(); + } \ No newline at end of file -- Gitee From 08c4cfbcaf713e0e0004fc72b575cc3704be5c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8D=95=E9=A3=8E=E7=9A=84=E9=80=8D=E9=81=A5=E4=BE=AF?= Date: Sun, 26 Mar 2023 12:10:43 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E8=BD=AC=E6=8D=A2=E5=BC=82=E5=B8=B8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/configuration/BeanConfig.java | 11 ++----- .../hxy/dream/common/redis/RedisConfig.java | 31 ++++++++++++++++--- .../common/redis/RedisConfigCacheManager.java | 21 +++++++++++-- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java b/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java index 2a59104..a356d4d 100644 --- a/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java +++ b/common/src/main/java/hxy/dream/common/configuration/BeanConfig.java @@ -11,15 +11,9 @@ import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import hxy.dream.common.serializer.BaseEnumDeserializer; import hxy.dream.common.serializer.BaseEnumSerializer; import hxy.dream.common.serializer.BaseLongSerializer; @@ -62,8 +56,8 @@ public class BeanConfig { builder.timeZone(TimeZone.getDefault()); ObjectMapper objectMapper = builder.createXmlMapper(false).build(); objectMapper.registerModule(simpleModule); - - // 解决查询缓存转换异常的问题 +/* + // FIXME 解决查询缓存转换异常的问题,这个月应该加在redis自己里面,加在全局,就会操作返回值里面带上类信息。 objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); @@ -74,6 +68,7 @@ public class BeanConfig { .registerModule(new ParameterNamesModule()); // --end -- + */ // 配置忽略未知属性 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); diff --git a/common/src/main/java/hxy/dream/common/redis/RedisConfig.java b/common/src/main/java/hxy/dream/common/redis/RedisConfig.java index 2f96df9..81c4e24 100644 --- a/common/src/main/java/hxy/dream/common/redis/RedisConfig.java +++ b/common/src/main/java/hxy/dream/common/redis/RedisConfig.java @@ -39,8 +39,28 @@ public class RedisConfig extends CachingConfigurerSupport { @Autowired RedisConnectionFactory redisConnectionFactory; - @Autowired - ObjectMapper objectMapper; + /** + * 这个仅仅针对Redis 序列化问题解决! 不能纳入到全局,否则会造成返回前端带上了类名。 + * + * @return + */ + @Bean + @Primary + public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer() { + ObjectMapper om = new ObjectMapper(); + // 解决查询缓存转换异常的问题 + om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + // 支持 jdk 1.8 日期 ---- start --- + om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + om.registerModule(new Jdk8Module()) + .registerModule(new JavaTimeModule()) + .registerModule(new ParameterNamesModule()); + // --end -- + GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om); + return genericJackson2JsonRedisSerializer; + } @Bean @Primary @@ -50,7 +70,7 @@ public class RedisConfig extends CachingConfigurerSupport { redisTemplate.setConnectionFactory(redisConnectionFactory); // 这里 redisTemplate.setKeySerializer(new StringRedisSerializer()); - GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper); + GenericJackson2JsonRedisSerializer serializer = genericJackson2JsonRedisSerializer(); redisTemplate.setValueSerializer(serializer); // 这里 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); @@ -85,8 +105,9 @@ public class RedisConfig extends CachingConfigurerSupport { .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues() - // 缓存过期时间 - .entryTtl(Duration.ofMinutes(30)); + // 缓存过期时间 Duration.ZERO -> eternal + .entryTtl(Duration.ZERO); +// .entryTtl(Duration.ofMinutes(30)); boolean ok = false; if (ok) { diff --git a/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java b/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java index 887e711..10e5778 100644 --- a/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java +++ b/common/src/main/java/hxy/dream/common/redis/RedisConfigCacheManager.java @@ -7,7 +7,6 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; -import hxy.dream.common.util.SpringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.cache.CacheKeyPrefix; import org.springframework.data.redis.cache.RedisCache; @@ -36,10 +35,10 @@ public class RedisConfigCacheManager extends RedisCacheManager { @Override protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) { - ObjectMapper objectMapper = SpringUtils.getBean(ObjectMapper.class); +// GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = SpringUtils.getBean(GenericJackson2JsonRedisSerializer.class); RedisSerializationContext.SerializationPair DEFAULT_PAIR = RedisSerializationContext.SerializationPair - .fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)); + .fromSerializer(genericJackson2JsonRedisSerializer()); if (name != null && name.length() > 0) { final int lastIndexOf = name.lastIndexOf('#'); @@ -64,6 +63,22 @@ public class RedisConfigCacheManager extends RedisCacheManager { return super.createRedisCache(name, cacheConfig); } + public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer() { + ObjectMapper om = new ObjectMapper(); + // 解决查询缓存转换异常的问题 + om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + // 支持 jdk 1.8 日期 ---- start --- + om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + om.registerModule(new Jdk8Module()) + .registerModule(new JavaTimeModule()) + .registerModule(new ParameterNamesModule()); + // --end -- + GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om); + return genericJackson2JsonRedisSerializer; + } + public static boolean isNumeric(String str) { for (int i = str.length(); --i >= 0; ) { if (!Character.isDigit(str.charAt(i))) { -- Gitee From 078cbe5ad90b153ef06fcf4f13c739693315116d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8D=95=E9=A3=8E=E7=9A=84=E9=80=8D=E9=81=A5=E4=BE=AF?= Date: Sun, 26 Mar 2023 12:12:00 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E8=BD=AC=E6=8D=A2=E5=BC=82=E5=B8=B8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SERIALIZE.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SERIALIZE.md b/SERIALIZE.md index 4db64a9..dc8aa4d 100644 --- a/SERIALIZE.md +++ b/SERIALIZE.md @@ -713,6 +713,10 @@ https://github.com/baomidou/mybatis-plus-samples/tree/master/mybatis-plus-sample > https://www.cnblogs.com/xwzp/p/14685452.html +# 解决 redis 序列化 java8 LocalDateTime 问题 + +https://blog.csdn.net/zhuzhoulin/article/details/106758473 + ### 配置文件 ![img.png](img.png) -- Gitee