java 可以在请求体中标识继承者而不指定类型吗?

7nbnzgx9  于 2023-05-05  发布在  Java
关注(0)|答案(1)|浏览(165)

我有一个例子,我的请求体有一个由继承支持的对象。因此,当我使用@requestbody并且没有显式指定子类的类型时,它不会自动选择/确定。有没有一种方法可以做到这一点:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Fence.class, name = "fence"),
        @JsonSubTypes.Type(value = Rectangle.class, name = "rectangle"),
        @JsonSubTypes.Type(value = Point.class, name = "point"),
        @JsonSubTypes.Type(value = Circle.class, name = "circle")
})
public class Element implements Serializable {
}

是否有任何开源库可以处理这个问题,当requestBody进来时,它会自动检测子类的示例。
我本想使用JsonTypeInfo.Id#DEDUCTION,但当子类中有嵌套对象时,它无法工作。

public class Rectangle extends Element implements Serializable {

    private Point leftDown;
    private Point rightUpper;

}

public class Point extends Element implements Serializable {

    private double lng;
    private double lat;
}

给了我这个错误

"JSON parse error: Could not resolve subtype of [simple type, class com.mapabc.entity.Point]: Cannot deduce unique subtype of `com.mapabc.entity.Point` (2 candidates match); nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.mapabc.entity.Point]: Cannot deduce unique subtype of `com.mapabc.entity.Point` (2 candidates match)\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 8, column: 9] (through reference chain: java.util.ArrayList[0]->com.moveinsync.geofencing.models.Geofence[\"geometry\"]->com.mapabc.entity.Rectangle[\"leftDown\"])"

这里是元素类-〉

@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
        @JsonSubTypes.Type(Fence.class),
        @JsonSubTypes.Type(Rectangle.class),
        @JsonSubTypes.Type(Point.class),
        @JsonSubTypes.Type(Circle.class)
})
public class Element implements Serializable {
    public CommandArgs<String, String> getCommandArgs(String key, String member){
        return null;
    }
}

点类-〉

public class Point extends Element implements Serializable {

private double lng;
private double lat;

public Point() {}

public Point(double lng, double lat) {
    this.lng = lng;
    this.lat = lat;
}

public double getLng() {
    return lng;
}

public void setLng(double lng) {
    this.lng = lng;
}

public double getLat() {
    return lat;
}

public void setLat(double lat) {
    this.lat = lat;
}

@Override
public String toString() {
    return "Point{" +
            "lng=" + lng +
            ", lat=" + lat +
            '}';
}

}
矩形类-〉

public class Rectangle extends Element implements Serializable {

    private Point leftDown;
    private Point rightUpper;

    @Override
    public CommandArgs<String, String> getCommandArgs(String key, String member) {
        double lng1 = leftDown.getLng();
        double lat1 = leftDown.getLat();
        double lng2 = rightUpper.getLng();
        double lat2 = rightUpper.getLat();
        return new CommandArgs<>(StringCodec.UTF8).add(key).add(member).add("BOUNDS").add(lng1).add(lat1).add(lng2).add(lat2);
    }

    public Rectangle() {}

    public Rectangle(Point leftDown, Point rightUpper) {
        this.leftDown = leftDown;
        this.rightUpper = rightUpper;
    }

    public Point getLeftDown() {
        return leftDown;
    }

    public void setLeftDown(Point leftDown) {
        this.leftDown = leftDown;
    }

    public Point getRightUpper() {
        return rightUpper;
    }

    public void setRightUpper(Point rightUpper) {
        this.rightUpper = rightUpper;
    }

}

这是请求体-〉

{
        "leftDown": {
            "lng" : 4.0,
            "lat" : 1.0
        },
        "rightUpper" : {
            "lng" : 1.0,
            "lat" : 4.0
        }
    }

只有两个类,一切都很好,但如果我们添加第三个类,它就会崩溃-〉

@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
        @JsonSubTypes.Type(Rectangle.class),
        @JsonSubTypes.Type(Point.class),
        @JsonSubTypes.Type(Circle.class)
})
public class Element implements Serializable {

}

public class Circle extends Element implements Serializable {
    private double lng;
    private double lat;
    private int r;
}
oaxa6hgo

oaxa6hgo1#

问题在于将PointCircle类定义为Element类的子类:

public class Point extends Element implements Serializable {

    private double lng;
    private double lat;
}

public class Circle extends Element implements Serializable {
    private double lng;
    private double lat;
    private int r;
}

基本上,当Jackson库从json文件中读取"leftDown": {"lng" : 4.0, "lat" : 1.0}属性时,它可以将其解释为Point对象或Circle对象的表示,同时没有定义其半径,由于表示不明确,因此存在例外。一个可能的解决方案,也许是最自然的想法是将Circle类重新定义为一对Point中心和它的半径(取决于你的另一个可能的解决方案,你可以考虑更适合你的需求):

public class Circle extends Element implements Serializable {

    Point center;
    private int r;
}

相关问题