Java JSON与来自父节点的类型信息的jackson的多态反序列化

Java JSON与来自父节点的类型信息的jackson的多态反序列化,java,json,jackson,deserialization,Java,Json,Jackson,Deserialization,我有这个JSON文档 1: { "type": "first_type", "configs": [ { "itemLevel": 1, "power": { "firstTypeParam": "xxxx" } }, { "itemLevel": 2, "power": { "firstTypeParam": "yyy" } } ] } 2: {

我有这个JSON文档

1:
{
  "type": "first_type",
  "configs": [
    {
      "itemLevel": 1,
      "power": {
        "firstTypeParam": "xxxx"
      }
    },
    {
      "itemLevel": 2,
      "power": {
        "firstTypeParam": "yyy"
      }
    }
  ]
}

2:
{
  "type": "second_type",
  "configs": [
    {
      "itemLevel": 11,
      "power": {
        "anotherParam": true
      }
    },
    {
      "itemLevel": 12,
      "power": {
        "anotherParam": false
    }
  ]
}
几个java类

public class Dto {
  String type;
  Collection<Config>; 
}

public class Config {
  int itemLevel;
  Collection<Power> powers; 
}

public interface Power {}

public class FirstPower implements Power {
  String firstTypeParam;
}

public class SecondPower implements Power {
  boolean anotherParam;
}
我尝试在Power接口上使用=MyStdDeserializer.class实现自定义jackson反序列化器@jsondesellized,但找不到如何使用类型标志访问父节点的邻居节点

您知道如何修复类层次结构和/或使用jackson特性/注释将JSON反序列化为FirstPower类上的first_类型和SecondPower上的second_类型吗

我用的是杰克逊2.9.7 可以稍微更改类层次结构和JSON格式,而且我能够使用基于注释的反序列化。

由于类型信息存储在Dto类中,因此应该为“Dto”类而不是“Power”接口实现自定义JsonDeserializer,以便访问类型信息。下面代码中自定义JsonDeserializer实现的关键部分是行

config.powers.addparser.readValueAsgetPowerClassdto.type

其中getPowerClass方法确定使用dto类型所需的classFirstPower或SecondPower。一旦知道了类,我们就可以通过调用readValueAs方法来反序列化power对象。下面的类应该放在同一个包中,演示如何实现自定义JsonDeserializer

主类

import java.io.IOException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class PolymorphicDeserialize {
    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
        ObjectMapper mapper = new ObjectMapper();

        Dto type1 = mapper.readValue(getType1Json(), Dto.class);
        Dto type2 = mapper.readValue(getType2Json(), Dto.class);

        printDto(type1);
        printDto(type2);
    }

    private static void printDto(Dto dto) {
        System.out.println("type :" + dto.type);
        for (Config config : dto.configs) {
            System.out.println("itemLevel:" + config.itemLevel);
            System.out.println("powers:" + config.powers);
        }
    }

    private static String getType1Json() {

        return "   {                                                       "
                + "        \"type\": \"first_type\",                       "
                + "        \"configs\": [                                  "
                + "          {                                             "
                + "            \"itemLevel\": 1,                           "
                + "            \"power\": {                                "
                + "              \"firstTypeParam\": \"xxxx\"              "
                + "            }                                           "
                + "          },                                            "
                + "          {                                             "
                + "            \"itemLevel\": 2,                           "
                + "            \"power\": {                                "
                + "              \"firstTypeParam\": \"yyy\"               "
                + "            }                                           "
                + "          }                                             "
                + "        ]                                               "
                + "      }                                                 ";

    }

    private static String getType2Json() {

        return "   {                                                       "
                + "        \"type\": \"second_type\",                      "
                + "        \"configs\": [                                  "
                + "          {                                             "
                + "            \"itemLevel\": 11,                          "
                + "            \"power\": {                                "
                + "              \"anotherParam\": true                    "
                + "            }                                           "
                + "          },                                            "
                + "          {                                             "
                + "            \"itemLevel\": 12,                          "
                + "            \"power\": {                                "
                + "              \"anotherParam\": false                   "
                + "            }                                           "
                + "          }                                             "
                + "        ]                                               "
                + "      }                                                 ";

    }
} 
Dto类

import java.util.Collection;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

@JsonDeserialize(using = DtoDeserializer.class)
public class Dto {
    String type;
    Collection<Config> configs;
}
头等舱

public class FirstPower implements Power {
    String firstTypeParam;

    String getFirstTypeParam() {
        return firstTypeParam;
    }

    void setFirstTypeParam(String firstTypeParam) {
        this.firstTypeParam = firstTypeParam;
    }

    @Override
    public String toString() {
        return "firstTypeParam:" + firstTypeParam;
    }
}
public class SecondPower implements Power {
    boolean anotherParam;

    boolean isAnotherParam() {
        return anotherParam;
    }

    void setAnotherParam(boolean anotherParam) {
        this.anotherParam = anotherParam;
    }

    @Override
    public String toString() {
        return "anotherParam:" + String.valueOf(anotherParam);
    }
}
二级功率级

public class FirstPower implements Power {
    String firstTypeParam;

    String getFirstTypeParam() {
        return firstTypeParam;
    }

    void setFirstTypeParam(String firstTypeParam) {
        this.firstTypeParam = firstTypeParam;
    }

    @Override
    public String toString() {
        return "firstTypeParam:" + firstTypeParam;
    }
}
public class SecondPower implements Power {
    boolean anotherParam;

    boolean isAnotherParam() {
        return anotherParam;
    }

    void setAnotherParam(boolean anotherParam) {
        this.anotherParam = anotherParam;
    }

    @Override
    public String toString() {
        return "anotherParam:" + String.valueOf(anotherParam);
    }
}

为什么配置的第二个字段是集合?对不起,它的类型错误