杰克逊 - 反序列化为运行时指定的类 [英] Jackson - deserialize into runtime specified class

查看:114
本文介绍了杰克逊 - 反序列化为运行时指定的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a class that uses Jackson to serialize/deserialize objects. At compile time I don't know which is the type of the objects I will be serializing/deserializing.

我读了几篇关于<的用法的文章和问题code> TypeReference 和 TypeFactory ,但我仍然遇到一些问题。

I read a couple of articles and questions about the usages of TypeReference and TypeFactory, however I'm still having some issues.

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

My class looks like (removed some irrelevant code):

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);
    } // ...
  }
}

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

And this is the snippet of code I'm using to test this:

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()方法返回的对象仍然是 Map ,我理解这是默认的类反序列化。

As far as I could understand, using typeReference should be enough to let know the deserializer that the value read from the byte stream should be put in a Clazz object. However, the object returned by the decode() method is still a Map, which I understand is the default class for deserializing.

我还尝试更改 decode()方法以返回返回objectMapper。 readValue(cachedData.getData(),objectMapper.getTypeFactory()。constructType(typeReference)),但我遇到了同样的问题。

I tried also changing the decode() method to return return objectMapper.readValue(cachedData.getData(), objectMapper.getTypeFactory().constructType(typeReference)), but I'm getting the same problem.

我很确定这是关于我将类型传递给序列化程序的方式,但到目前为止我还没能解决它。谢谢。

I'm quite sure it's something regarding the way I pass the type into the serializer, but I haven't been able so far to fix it. Thanks.

推荐答案

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

It is not quite clear what exactly you are trying to do: much of the code does not make change. Specifically usage of TypeReference is wrong: you can not use type variables with it, type must be concrete.

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

However, perhaps solution is simpler than you thought. If you can keep track of original Class, just store that (or name from clazz.getName()), and pass that when deserializing.

这篇关于杰克逊 - 反序列化为运行时指定的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆