近期
最近很懈怠,感觉自己做的事情没什么意义,未来很迷茫,现在很焦虑,常常觉得不能虚度光阴
但总是浑浑噩噩着过着,有点麻木了,不太喜欢现在这种生活,还是以前过着苦日子,吃着面条的生活更有精神
钱是一点存不了,自身也没什么值得骄傲的进步,时间一点点过,岁月从不饶人,我觉得是时候要做出改变了
我心里有内耗,这我是知道的,但总有一天我会丢掉它,我总有一天会活在当下,脱离掉内耗的自己,加油万一!
回归正题,这两天被一个bug整自闭了,项目中代码从oracle数据库中获取字段和相应的值,
拿到数据后序列化保存到reids中,但总是报错,报错样式见下方:
org.springframework.data.redis.serializer.SerializationException:Could not write JSON:
No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer
Caused by:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer
(to avoid Exception,disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
(through reference chain:com.ecominfo.modules.oeams.core.dto.RedisStructDataDTO["oeaDateObjectList"]->java.util.ArrayList[0]
->com.ecominfo.modules.oeams.core.dto.RedisStructDataObject["dataMap"]->java.util.HashMap["end_time"]->oracle.sql.TIMESTAMP["stream"])
看样子是因为redis序列化oracle数据库中的TIMESTAMP字段失败,redis序列化使用的是jackson的类型转换器
但对TIMESTAMP类型字段并没有合适的解析器,然后就报错了,大概是这意思吧。所以我们要为redis使用的jackson转换器配置一个适用于TIMESTAMP类型的解析器
网上找了很久才找到解决办法:
创建OracleTimestampSerializer自定义解析器
@Slf4j public class OracleTimestampSerializer extends JsonSerializer<TIMESTAMP> { @Override public void serialize(TIMESTAMP value, JsonGenerator gen, SerializerProvider serializers) throws IOException { Timestamp tt = null; try { tt = value.timestampValue(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS"); gen.writeString(dateFormat.format(tt)); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void serializeWithType(TIMESTAMP value, JsonGenerator g, SerializerProvider provider, TypeSerializer typeSer) throws IOException { // NOTE: need not really be string; just indicates "scalar of some kind" WritableTypeId typeIdDef = typeSer.writeTypePrefix(g, typeSer.typeId(value, JsonToken.VALUE_STRING)); serialize(value, g, provider); typeSer.writeTypeSuffix(g, typeIdDef); } }
在redisConfig中添加我们配置的自定义解析器
/** * 开启缓存支持 * @author zyf * @Return: */ @Slf4j @EnableCaching @Configuration public class RedisConfig extends CachingConfigurerSupport { @Resource private LettuceConnectionFactory lettuceConnectionFactory; /** * RedisTemplate配置 * @param lettuceConnectionFactory * @return */ @Bean("redisTemplate") 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(); // key序列化 redisTemplate.setKeySerializer(stringSerializer); // value序列化 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // Hash key序列化 redisTemplate.setHashKeySerializer(stringSerializer); // Hash value序列化 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 缓存配置管理器 * * @param factory * @return */ @Bean("cacheManager") public CacheManager cacheManager(LettuceConnectionFactory factory) { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = jacksonSerializer(); // 配置序列化(解决乱码的问题),并且配置缓存默认有效期 6小时 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6)); RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith( RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)); //.disableCachingNullValues(); // 以锁写入的方式创建RedisCacheWriter对象 //update-begin-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符* RedisCacheWriter writer = new JeecgRedisCacheWriter(factory, Duration.ofMillis(50L)); //RedisCacheWriter.lockingRedisCacheWriter(factory); // 创建默认缓存配置对象 /* 默认配置,设置缓存有效期 1小时*/ //RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)); /* 自定义配置test:demo 的超时时间为 5分钟*/ 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(); //update-end-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符* return cacheManager; } /** * redis 监听配置 * * @param redisConnectionFactory redis 配置 * @return */ @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(); SimpleModule module = new SimpleModule(); // 注册相关类型的自定义Serializer module.addSerializer(TIMESTAMP.class, new OracleTimestampSerializer()); objectMapper.registerModule(module); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); return jackson2JsonRedisSerializer; } }
相关的文章