0

我正在编写一个使用 Jackson 序列化/反序列化对象的类。在编译时,我不知道我将要序列化/反序列化的对象的类型。

我阅读了几篇关于 and 用法的文章和问题TypeReferenceTypeFactory但是我仍然遇到一些问题。

我的课看起来像(删除了一些不相关的代码):

public class JsonSerializer<T> {

  private ObjectMapper objectMapper;
  private TypeReference typeReference;

  @PostConstruct
  public void init() {
      objectMapper = new ObjectMapper();
      typeReference = new TypeReference<T>(){ };
  }

  // ...


  public Object decode(CachedData cachedData) {
    try {
        return objectMapper.readValue(cachedData.getData(), typeReference);
    } // ...
  }
}

这是我用来测试的代码片段:

public class SerializerTest {

  private JsonSerializer<Clazz> serializer;
  private ObjectMapper objectMapper = new ObjectMapper();
  private static final String CHARSET = "UTF-8";
  private Clazz data = generateData(); // creates a simple object

  @BeforeMethod
  public void beforeMethod() {
      serializer = new JsonSerializer<Clazz>();
      serializer.init();
  }

  // ...

  public void shouldDecodeDataCorrectly() throws Exception {
    CachedData cachedData = new CachedData(0, 
      objectMapper.writeValueAsString(data).getBytes(CHARSET), 
      CachedData.MAX_SIZE);

    Object object = serializer.decode(cachedData);
    assertEquals(data, object);
  }

  public static class Clazz {
    // POJO with getters and setters
  }

}

据我所知,使用typeReference应该足以让反序列化器知道从字节流中读取的值应该放在一个Clazz对象中。但是,该decode()方法返回的对象仍然是 a Map,据我了解是反序列化的默认类。

我也尝试将decode()方法更改为 return return objectMapper.readValue(cachedData.getData(), objectMapper.getTypeFactory().constructType(typeReference)),但我遇到了同样的问题。

我很确定这与我将类型传递到序列化程序的方式有关,但到目前为止我还无法修复它。谢谢。

4

3 回答 3

1

目前尚不清楚您到底要做什么:大部分代码都没有改变。具体用法TypeReference是错误的:你不能使用类型变量,类型必须是具体的。

但是,也许解决方案比您想象的要简单。如果您可以跟踪 original Class,只需存储它(或名称来自clazz.getName()),并在反序列化时传递它。

于 2012-09-10T20:40:28.420 回答
0

你检查了@JsonTypeInfo 吗?请查看它的文档。

于 2012-09-10T16:35:32.973 回答
0

基于http://jackson.codehaus.org/1.9.9/javadoc/org/codehaus/jackson/type/TypeReference.html上的 javadoc, 我将这样做:

从 JsonSerializer 中删除 typeReference 字段

修改 JsonSerializer.decode 方法以将类型引用作为参数

将类型引用作为参数传递

Object object = transcoder.decode(cachedData, new TypeReference<Clazz>() {});

顺便说一句 - “转码器”应该是“序列化器”?错字?

于 2012-09-10T17:26:23.900 回答