Reputation: 83
I'm using spring boot 2.0.3 and spring-boot-starter-data-redis. Also using jackson-datatype-jsr310.
I want to store Object into redis.
the object(MyObj):
String text;
Instant instant;
Here's my code:
@Test
public void test() {
ListOperations<String, MyObj> listOps = redisTemplate.opsForList();
MyObj o1 = new MyObj();
o1.setText("foo");
o1.setInstant(Instant.now());
listOps.leftPush("foo", o1);
MyObj o2 = new MyObj();
o2.setText("bar");
o2.setInstant(Instant.now());
listOps.leftPush("foo", o2);
List<MyObj> list = listOps.range("foo", 0, -1);
for (MyObj o : list) {
System.out.println(o.getText());
System.out.println(o.getInstant());
}
}
in my RedisConfig:
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
But when I'm pushing into redis, the error occurs below:
org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of
java.time.Instant
(no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
How to serialize java instant type with Redis?
Any opinion would be appreciated.
Upvotes: 5
Views: 2431
Reputation: 1
While this is quite an old post, I ran into this problem recently and did the lazy man search and found this before deciding to read the class file. I found that you can easily override the default ObjectMapper
with a custom one. Use the setObjectMapper(ObjectMapper objectMapper)
method on the Serializer to override the default.
// Taken from Jackson library
public class Jackson2JsonRedisSerializer<T> implements RedisSerializer<T> {
public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private final JavaType javaType;
private ObjectMapper objectMapper = new ObjectMapper();
// truncated
public void setObjectMapper(ObjectMapper objectMapper) {
Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper;
}
You just need to create an ObjectMapper with the JavaTime.Module registered like below
public static ObjectMapper dateMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return mapper;
Jackson2JsonRedisSerializer<MyObj> valueSerializer = new
Jackson2JsonRedisSerializer<>(MyObj.class);
valueSerializer.setObjectMapper(dateMapper());
}
disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
turns of default behavior.
Upvotes: 0