多个@JsonTypeInfo和@JsonSubTypes

问题描述 投票:0回答:1

我知道 - 基于这里的不同问题:

在多重继承的情况下(Carproperty = "carType"

但是我有不同的场景现在对我有用 - 这是否也不支持? - 我还需要使用两个鉴别器的场景,但不在“继承链”中:

第一级:

carType
(重要提示:奥迪有场
private ColorDiscriminator color;

public enum CarType {

    AUDI, TOYOTA;

    public static final String AUDI_STR = "AUDI";
    public static final String TOYOTA_STR = "TOYOTA";
}

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "carType",
        visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = Audi.class, name = CarType.AUDI_STR),
        @JsonSubTypes.Type(value = Toyota.class, name = CarType.TOYOTA_STR)
})
public abstract class CarDiscriminator {

    private CarType carType;

    public CarType getCarType () {
        return carType;
    }

    public void setCarType (CarType carType) {
        this.carType = carType;
    }
}

@JsonTypeName(CarType.AUDI_STR )
public class Audi extends CarDiscriminator {
  private ColorDiscriminator color;
  // ommited
}

@JsonTypeName(CarType.TOYOTA_STR)
public class Toyota extends CarDiscriminator {
  // ommited
}

第二级:

colorType

public enum ColorType {

    BLUE, RED;

    public static final String BLUE_STR = "BLUE";
    public static final String RED_STR = "RED";
}

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "colorType",
        visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = Blue.class, name = ColorType.BLUE_STR),
        @JsonSubTypes.Type(value = Red.class, name = ColorType.RED_STR)
})
public abstract class ColorDiscriminator {

    private ColorType colorType;

    public ColorType getColorType () {
        return colorType;
    }

    public void setColorType (ColorType colorType) {
        this.colorType = colorType;
    }
}

@JsonTypeName(ColorType.BLUE_STR)
public class Blue extends ColorDiscriminator {
  // ommited
}

@JsonTypeName(ColorType.RED_STR)
public class Red extends ColorDiscriminator {
  // ommited
}

在生成的 swagger json(和 ui)定义中,我首先可以正确看到

oneOf
carType:
Audi
|
Toyota
。但第二个
colorType
不是。生成的 json 甚至不包含
Blue
也不包含
Red
对象定义。

java jackson swagger openapi
1个回答
0
投票

您提供的两个链接都表示不支持多重继承,并且根据他们的官方 GitHub 存储库,已经说过几次没有计划。

这不受支持,并且没有计划朝这个方向扩展类型解析。

对多级分辨率的支持不存在,也没有计划。因此定义的链接将不起作用。

不支持并且没有计划支持它。不要假设这将会实现来设计您的系统。

顺便说一句,不要用仅支持单继承的语言设计具有多重继承的类。此外,您正在建模的对象(汽车模型和颜色)不共享继承关系。

继承是一种规范关系,我们从更广泛的类型(基类)到更具体的类型(派生类)。派生类仍然具有与基类相同的属性和行为,但它通常会添加或重新定义以将其专门用于其旨在解决的问题类。在继承中,基类的实例也称为基类的实例。这种关系通常被称为 is-a

is-a的一个典型例子是

Vehicle > Car > Audi
,其中,由于汽车是一辆车辆,所以奥迪是一辆汽车和车辆。在您的代码中不能说同样的事情,您试图将不存在的多重继承关系映射到 json 中。仅仅因为奥迪是蓝色的,并不意味着它是一种颜色。那只是一个财产。如果两者之间确实存在继承关系,那么它们也应该共享相同的属性和行为,但事实并非如此。一般来说,在设计继承时,我们应该问自己is X a Y?”。如果答案是肯定的,那么这两个对象实际上具有 is-a 关系,并且应该这样设计;否则,如果答案是否定的,我们就不应该强制两者之间继承。

在您的情况下,更好的实现是下面的,其中

ColorType
被保留,以防您只需要一组预定义的颜色。

public enum ColorType {

    BLUE("BLUE"), RED("RED");

    private String color;

    ColorType(String color){
        this.color = color;
    }

    public String getColor() {
        return color;
    }
}

public class Car {
    private String brand;
    private String model;
    private ColorType color;

    // ... rest of the implementation ...
}

相反,如果由于某种原因您需要在数据模型中的汽车之间进行实际分离,您可以这样编写。在这里,您仍在描述实际的继承关系,其中颜色被视为属性,并且管理奥迪的不同实例、丰田的不同实例等对您来说很重要。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "brand")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Audi.class, name = "audi"),
        @JsonSubTypes.Type(value = Toyota.class, name = "toyota")
})
public abstract class Car {
    protected ColorType color;

    //common car properties

    // some abstract methods that will be specialized in the derived classes

    public Car() {
    }

    public Car(ColorType color) {
        this.color = color;
    }

    public ColorType getColor() {
        return color;
    }

    public void setColor(ColorType color) {
        this.color = color;
    }

}

public class Audi extends Car {

    public Audi() {
    }

    public Audi(ColorType color) {
        super(color);
    }

    //specialized properties that only Audi cars have

    //specialized behavior
}

public class Toyota extends Car {
    public Toyota() {
    }

    public Toyota(ColorType color) {
        super(color);
    }

    //specialized properties that only Toyota cars have

    //specialized behavior
}

这里还有 OneCompiler

的代码演示
© www.soinside.com 2019 - 2024. All rights reserved.