这是我的要求。我在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());
解决这个问题的任何想法
答案 0 :(得分:2)
您可以为Car类实现自定义反序列化器,例如:
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 (ezm@one.com)
*/
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;
}
}
,当您要调用Jackson API进行实际的反序列化时,请提前注册您的反序列化器:
String json = "{\"modelName\": \"Corolla\", \"year\": \"2019\"}";
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Car.class, new CarDeserializer());
mapper.registerModule(module);
Car car = mapper.readValue(json, Car.class);
assertEquals("Corolla", car.getModel().getModelName());
这不需要更改您的POJO。但是,如果可以这样做,则可以选择使用POJO类中的注释注册自定义反序列化器,如下所示:
@JsonDeserialize(using = CarDeserializer.class)
public class Car { ... }