Java 如何使用@JsonTypeInfo、@JsonSubType根据同级字段';s值多少?
假设我有这样一个类结构:-Java 如何使用@JsonTypeInfo、@JsonSubType根据同级字段';s值多少?,java,spring,jackson,jackson-databind,jackson2,Java,Spring,Jackson,Jackson Databind,Jackson2,假设我有这样一个类结构:- class ShapeRequest { ShapeInfo shapeInfo; Shape shape; static class ShapeInfo { String shapeName; String shapeDimension; } static abstract class Shape { } static class Square extends Shap
class ShapeRequest {
ShapeInfo shapeInfo;
Shape shape;
static class ShapeInfo {
String shapeName;
String shapeDimension;
}
static abstract class Shape {
}
static class Square extends Shape{
int area;
}
static class Circle extends Shape{
int area;
}
}
根据shapeInfo.shapeName字段值,如何将字段shape映射为方形或圆形,从而反序列化ShapeRequest
例如,以下JSON应该映射到具有圆形形状类型的ShapeRequest,因为shapeInfo.shapeName=“Circle”
您可以在下面使用它:
public class JsonTypeExample {
// Main method to test our code.
public static void main(String args[]) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
// json to circle based on shapeName
String json = "{\"shapeName\":\"circle\",\"area\":10}";
Shape shape = objectMapper.readerFor(Shape.class).readValue(json);
System.out.println(shape.getClass());
System.out.println(objectMapper.writeValueAsString(shape));
// json to square based on shapeName
json = "{\"shapeName\":\"square\",\"area\":10}";
shape = objectMapper.readerFor(Shape.class).readValue(json);
System.out.println(shape.getClass());
System.out.println(objectMapper.writeValueAsString(shape));
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "shapeName")
@JsonSubTypes({
@JsonSubTypes.Type(value = Square.class, name = "square"),
@JsonSubTypes.Type(value = Circle.class, name = "circle")
})
static class Shape {
Shape() {
}
}
@JsonTypeName("square")
static class Square extends Shape {
public int area;
Square(int area){
super();
this.area = area;
}
}
@JsonTypeName("circle")
static class Circle extends Shape {
public int area;
Circle(int area){
super();
this.area = area;
}
}
}
在这里,Shape类使用JsonTypeInfo和JsonSubTypes进行注释
@JsonTypeInfo用于指示序列化和反序列化中要包含的类型信息的详细信息。
此处属性表示确定子类型时要考虑的值
@JsonSubTypes用于指示注释类型的子类型。
在这里,名称和值将shapeName映射到相应的子类型类
只要像示例中那样传递JSON,就会通过JsonSubTypes进行反序列化,然后它会基于shapeName返回相应的JAVA对象。感谢您的响应。但是,您错过了反序列化到包含shapeInfo和实际ShapeQuest的类ShapeRequest{}的全部要点。您可以分享一个示例,说明如何序列化/反序列化ShapeRequest?看起来您没有正确地构建问题陈述。把类型能指放在不同的地方并不理想。试着把它移到合适的位置。但不幸的是,这就是为什么它来自外部系统。我尝试了很多来实现你想要的,但这似乎是不可能的。可以将形状最大化设置为圆形/方形,但不能设置面积。这可以通过使用显式映射器实现:new ObjectMapper().readerFor(Shape.class).readValue(new ObjectMapper().writeValueAsString(ImmutableMap.of(“shapeName”,shapeInfo.getShapeName(),“area”,0))。。这应该在shapeInfo setter中调用,而忽略ShapeRequest中的shapesetter。我觉得这不容易实现,因为问题陈述与JsonSubTypes所支持的相反。
public class JsonTypeExample {
// Main method to test our code.
public static void main(String args[]) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
// json to circle based on shapeName
String json = "{\"shapeName\":\"circle\",\"area\":10}";
Shape shape = objectMapper.readerFor(Shape.class).readValue(json);
System.out.println(shape.getClass());
System.out.println(objectMapper.writeValueAsString(shape));
// json to square based on shapeName
json = "{\"shapeName\":\"square\",\"area\":10}";
shape = objectMapper.readerFor(Shape.class).readValue(json);
System.out.println(shape.getClass());
System.out.println(objectMapper.writeValueAsString(shape));
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "shapeName")
@JsonSubTypes({
@JsonSubTypes.Type(value = Square.class, name = "square"),
@JsonSubTypes.Type(value = Circle.class, name = "circle")
})
static class Shape {
Shape() {
}
}
@JsonTypeName("square")
static class Square extends Shape {
public int area;
Square(int area){
super();
this.area = area;
}
}
@JsonTypeName("circle")
static class Circle extends Shape {
public int area;
Circle(int area){
super();
this.area = area;
}
}
}