Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jackson将子JSON反序列化为父属性_Java_Json_Jackson_Mapping_Parent Child - Fatal编程技术网

Java Jackson将子JSON反序列化为父属性

Java Jackson将子JSON反序列化为父属性,java,json,jackson,mapping,parent-child,Java,Json,Jackson,Mapping,Parent Child,这是我的要求。我有下面的POJO class Car { private String brandName; private String color; private Model model; } class Model { private String modelName; private String year; } 如果我得到如下所示的输入json,那么它应该反序列化并映射到这两个类 String json = "{\"brandName\" : \"Toyoto\"

这是我的要求。我有下面的POJO

class Car {
  private String brandName;
  private String color;
  private Model model;
}

class Model {
 private String modelName;
 private String year;
}
如果我得到如下所示的输入json,那么它应该反序列化并映射到这两个类

String json = "{\"brandName\" : \"Toyoto\", \"color\" : \"Silver\", \"model\" : {\"modelName\": \"Corolla\", \"year\": \"2019\"}}"
ObjectMapper mapper = new ObjectMapper();
Car car = mapper.readValue(json, Car.class);
assertEquals("Corolla", car.getModel().getModelName()); 
这个案子没问题

但若我传递子json,那个么在不改变映射类的情况下也应该可以工作

String json = "{\"modelName\": \"Corolla\", \"year\": \"2019\"}"
ObjectMapper mapper = new ObjectMapper();
Car car = mapper.readValue(json, Car.class);
assertEquals("Corolla", car.getModel().getModelName()); 

任何解决此问题的方法

您都可以为汽车类实现自定义反序列化器,如:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import java.io.IOException;

/**
 * @author Ehsan Zaery Moghaddam
 */
public class CarDeserializer extends StdDeserializer<Car> {

    public CarDeserializer() {
        this(null);
    }

    public CarDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Car deserialize(JsonParser jp, DeserializationContext dctx)
            throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        Car c = new Car();
        Model cModel = new Model();

        if(node.has("brandName")) {
            //  the JSON string contains both car and model details
            c.setBrandName(node.get("brandName").asText());
            c.setColor(node.get("color").asText());

            JsonNode modelNode = node.get("model");
            cModel.setModelName(modelNode.get("modelName").asText());
            cModel.setYear(modelNode.get("year").asText());
        } else {
            // the JSON string just has model details
            cModel.setModelName(node.get("modelName").asText());
            cModel.setYear(node.get("year").asText());
        }

        c.setModel(cModel);

        return c;
    }
}
这不需要更改您的POJO。但是,如果可以这样做,您可以选择在POJO类中使用注释注册自定义反序列化程序,如下所示:

@JsonDeserialize(using = CarDeserializer.class)
public class Car { ... }

感谢您的代码,尽管我之前考虑过这种方法,但我正在寻找一些更简单的方法,否则我需要像上面那样有许多自定义实现。
@JsonDeserialize(using = CarDeserializer.class)
public class Car { ... }