//错误代码
protected void process(ReconRedisContext reconRedisContext) {
String key = this.getLockKey(reconRedisContext);
Pagination pagination = this.queryReconData(reconRedisContext);
if (ObjectUtils.isNotEmpty(pagination)
&& CollectionUtils.isNotEmpty(pagination.getList())) {
List<?> resList = pagination.getList();
redisTemplate.executePipelined(new RedisCallback<Set<?>>() {
@Override
public Set<?> doInRedis(RedisConnection connection) throws DataAccessException {
resList.stream().forEach(value -> {
connection.sAdd(key.getBytes(StandardCharsets.UTF_8), value.toString().getBytes(StandardCharsets.UTF_8));
});
return null;
}
});
}
}
// 抛出序列化异常
org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unrecognized token 'value': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
protected void process(ReconRedisContext reconRedisContext) {
RedisSerializer keySerializer = redisTemplate.getKeySerializer();
RedisSerializer valueSerializer = redisTemplate.getValueSerializer();
String key = this.getLockKey(reconRedisContext);
Pagination pagination = this.queryReconData(reconRedisContext);
if (ObjectUtils.isNotEmpty(pagination)
&& CollectionUtils.isNotEmpty(pagination.getList())) {
List<?> resList = pagination.getList();
redisTemplate.executePipelined(new RedisCallback<Set<?>>() {
@Override
public Set<?> doInRedis(RedisConnection connection) throws DataAccessException {
resList.stream().forEach(value -> {
connection.sAdd(keySerializer.serialize(key), valueSerializer.serialize(value));
});
return null;
}
});
}
}
// RedisTemplate 默认使用 DefaultSetOperations 存放数据的源码如下:
public Long add(K key, V... values) {
byte[] rawKey = rawKey(key);
byte[][] rawValues = rawValues((Object[]) values);
return execute(connection -> connection.sAdd(rawKey, rawValues));
}
byte[] rawKey(Object key) {
Assert.notNull(key, "non null key required");
if (keySerializer() == null && key instanceof byte[]) {
return (byte[]) key;
}
return keySerializer().serialize(key);
}
byte[] rawValue(Object value) {
if (valueSerializer() == null && value instanceof byte[]) {
return (byte[]) value;
}
return valueSerializer().serialize(value);
}
看源码,RedisTemplate 也是把 key 和 value 都转为了字节,但是使用了我们自己设置的 Serializer ,所以,我们在使用 pipeline 时,也需要使用我们设置的 Serializer。
注意:根据源码来看,Redis 的其他数据结构,使用 pipeline 时,也会存在序列化的问题,在代码编写的时候,需要注意。
源自