杰克逊:反序列化为不同类型

huangapple 未分类评论46阅读模式
英文:

Jackson: deserialize to different type

问题

我知道已经有一个类似的问题存在(https://stackoverflow.com/questions/10427929/jackson-deserializing-to-a-different-type),但那里的答案对我没有帮助。旧的 JSON 文件已经在生产中使用,无法更改。

我有一个常规的应用程序,使用旧的 POJO(普通Java对象)。现在我有了新的 POJO,目前为了支持旧文件,我正在反序列化为旧的 POJO,然后手动转换为新的 POJO。我希望直接将转换编写到Jackson反序列化器中,但我遇到了问题。过去我曾编写过一个简单的Jackson模块,用于序列化和反序列化特定类型,并且我对Jackson有一些基础知识。

我有类似以下的代码:

public class MyModule extends com.fasterxml.jackson.databind.module.SimpleModule {

  public MyModule() {
    super("MyModule", Version.unknownVersion());

    addDeserializer(OldPojo.class, new JsonDeserializer<NewPojo>() {
      @Override
      public NewPojo deserialize(JsonParser p, DeserializationContext ctxt) {
        // 转换并返回新的POJO
      }
    });
  
    // 其他的反序列化器...
  }
}

这种方法可行吗?我做错了什么?非常感谢。

英文:

I know a similar question already exists (https://stackoverflow.com/questions/10427929/jackson-deserializing-to-a-different-type) but the answer there does not help me. The old JSON files are already in production and cannot be changed.

I have a regular application with old POJOs. Now I have new POJOs and currently to support the old files I am deserializing to the old POJOs and converting manually to the new ones. I would like to write the conversion directly into a Jackson deserializer but I am having trouble. In the past I have writen a simple Jackson module for serializing and deserializing certain types and I have some basic knowledge of Jackson.

I have something like:

public class MyModule extends com.fasterxml.jackson.databind.module.SimpleModule

  public MyModule() {
    super(&quot;MyModule&quot;, Version.unknownVersion());

    addDeserializer(OldPojo.class, new JsonDeserializer&lt;NewPojo&gt;() {
      @Override
      public NewPojo deserialize(JsonParser p, DeserializationContext ctxt) {
        // convert and return new pojo
      }
    }
  
    // others deserializers ...
  }
}

Would this approach be possible? And what am I doing wrong? Lots of thanks.

答案1

得分: 0

SimpleModule.addDeserializer()] [1] 的文档为该方法提供了以下签名:

public <T> SimpleModule addDeserializer(Class<T> type, JsonDeserializer<? extends T> deser)

其中 &lt;T&gt;JsonDeserializer.deserialize() 的返回类型(好的,&lt;? extends T&gt; 就是该类型……)。

所以在您的情况下,您必须能够将 NewPojo 实例强制转换为 OldPojo 引用:

NewPojo o = new NewPojo();
OldPojo r = (OldPojo) o;

如果这样的转换没有引发 ClassCastException,那么您的方法可能会成功……

您说过您不能更改 JSON 文件 - 但是您是否必须保留 OldPojo 类?为什么下面的代码段不起作用:


addDeserializer( NewPojo.class, new JsonDeserializer<NewPojo>() )
{
    
英文:

The [documentation for `SimpleModule.addDeserializer()] 1 gives the signature for that method like this:

public &lt;T&gt; SimpleModule addDeserializer(Class&lt;T&gt; type, JsonDeserializer&lt;? extends T&gt; deser)

where &lt;T&gt; is the return type of JsonDeserializer.deserialize() (ok, &lt;? extends T&gt; is that type …).

So in your case, you must be able to case a NewPojo instance to an OldPojo reference:

NewPojo o = new NewPojo();
OldPojo r = (OldPojo) o;

If that works without a ClassCastException, you approach may be successful …

You said that you cannot change the JSON files – but do you have to keep the OldPojo class as well? Why does

…
addDeserializer( **NewPojo.class**, new JsonDeserializer&lt;NewPojo&gt;() )
{
    …

do not work for you?

huangapple
  • 本文由 发表于 2020年4月6日 17:11:44
  • 转载请务必保留本文链接:https://java.coder-hub.com/61056406.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定