Redisson 和 Json 对象
Redisson and Json for objects
我目前正在尝试将 Redisson 作为 Redis 客户端,到目前为止,我已经能够毫无问题地替换大量代码。我现在遇到的唯一问题是尝试使用分布式集合,例如 Queue 或 List。
List<MyEntry> entries = // read some sample data from a file
RedissonClient client = // create client
RBlockingQueue<MyEntry> queue = client.getBlockingQueue("test-queue", new JsonJacksonCodec());
queue.addAll(entries);
List<MyEntry> readBack = new ArrayList<>();
queue.drainTo(readBack);
当我到达最后一行时,我总是得到这个异常 -
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class'
at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 1439]
当我将 @JsonTypeInfo 添加到我的 class 时,它似乎可以工作,但是,大多数 classes 我无权将 @JsonTypeInfo 注释添加到。
我在这里遗漏了什么?解决此问题的一种方法是使用 ByteArrayCodec 和 serialize/deserialize 使用我自己的 ObjectMapper(编辑:尝试这会引发另一种类型的异常!),但如果可能的话,我更愿意让 Redisson 处理它,因为它提供已经有很多编解码器了。
像往常一样非常感谢您的帮助!
更多信息 - 我最终编写了自己的简单编解码器,它只需要一个 Class 作为参数,并创建一个解码器和编码器,其工作方式与 JsonJacksonCodec 的工作方式类似,但有一个区别 -
private static class MyCodec<T> implements Codec {
private final Decoder<Object> decoder = new Decoder<Object>() {
@Override
public T decode(ByteBuf buf, State state) throws IOException {
return mapper.readValue((InputStream) new ByteBufInputStream(buf), type);
}
};
private final ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
private final Class<T> type;
public MyCodec(Class<T> type) {
this.type = type;
}
// rest of methods...
}
并且我能够让我的示例工作 - 但这感觉像是一种变通方法,而不是原始问题的解决方案,而且我不想为我拥有的每个实现编写额外的编解码器:)
Redisson 为 类 提供默认的 Jackson 编解码器,没有使用 Jackson 注释进行注释。您现有的注释优先于默认的编解码器设置,因此出现了问题。您可以尝试其他类型的编解码器,如 fst 编解码器,或者为 Jackson 编解码器提供您自己的兼容对象映射器。
见Fundamental API design flaw -- with respect to encoding and serialization
我很想错了。目前正在寻找一种不需要大手术的方法来解决这个问题。
我目前正在尝试将 Redisson 作为 Redis 客户端,到目前为止,我已经能够毫无问题地替换大量代码。我现在遇到的唯一问题是尝试使用分布式集合,例如 Queue 或 List。
List<MyEntry> entries = // read some sample data from a file
RedissonClient client = // create client
RBlockingQueue<MyEntry> queue = client.getBlockingQueue("test-queue", new JsonJacksonCodec());
queue.addAll(entries);
List<MyEntry> readBack = new ArrayList<>();
queue.drainTo(readBack);
当我到达最后一行时,我总是得到这个异常 -
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class' at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 1439]
当我将 @JsonTypeInfo 添加到我的 class 时,它似乎可以工作,但是,大多数 classes 我无权将 @JsonTypeInfo 注释添加到。
我在这里遗漏了什么?解决此问题的一种方法是使用 ByteArrayCodec 和 serialize/deserialize 使用我自己的 ObjectMapper(编辑:尝试这会引发另一种类型的异常!),但如果可能的话,我更愿意让 Redisson 处理它,因为它提供已经有很多编解码器了。
像往常一样非常感谢您的帮助!
更多信息 - 我最终编写了自己的简单编解码器,它只需要一个 Class 作为参数,并创建一个解码器和编码器,其工作方式与 JsonJacksonCodec 的工作方式类似,但有一个区别 -
private static class MyCodec<T> implements Codec {
private final Decoder<Object> decoder = new Decoder<Object>() {
@Override
public T decode(ByteBuf buf, State state) throws IOException {
return mapper.readValue((InputStream) new ByteBufInputStream(buf), type);
}
};
private final ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
private final Class<T> type;
public MyCodec(Class<T> type) {
this.type = type;
}
// rest of methods...
}
并且我能够让我的示例工作 - 但这感觉像是一种变通方法,而不是原始问题的解决方案,而且我不想为我拥有的每个实现编写额外的编解码器:)
Redisson 为 类 提供默认的 Jackson 编解码器,没有使用 Jackson 注释进行注释。您现有的注释优先于默认的编解码器设置,因此出现了问题。您可以尝试其他类型的编解码器,如 fst 编解码器,或者为 Jackson 编解码器提供您自己的兼容对象映射器。
见Fundamental API design flaw -- with respect to encoding and serialization
我很想错了。目前正在寻找一种不需要大手术的方法来解决这个问题。