Victools JSON模式生成器为同一类创建两个定义

发布于 2025-02-10 04:29:10 字数 2653 浏览 0 评论 0 原文

使用Victools的JSON模式生成器(这是基于Java类生成JSON模式),如果我将两个类与常见的Supertype相关联,并且使用 @jsontypename

请考虑以下代码:

@JsonTypeName("Root")
public class Root {
    private String rootName;
    ... 
    private List<SuperClass1> superclass1 = new ArrayList<SuperClass1>();
    ...
}

@JsonTypeName("SuperClass1")
@JsonTypeInfo(  use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({ @JsonSubTypes.Type(value = Sub1.class, name = "Sub1"),
@JsonSubTypes.Type(value = Sub2.class, name = "Sub2")})
public abstract class SuperClass1 {
    String name;
    int someThingElse;
    
    Root root;

    ...
}
@JsonTypeName("Sub1")
public class Sub1 extends SuperClass1 {
    String sub1;
    ...
    Sub2 sub2;
    ...
}
@JsonTypeName("Sub2")
public class Sub2 extends SuperClass1{
    String sub2;
    ...
}

生成以下JSON架构:

{
  "$schema" : "http://json-schema.org/draft-07/schema#",
  "definitions" : {
    "Sub1" : {
      "type" : "object",
      "properties" : {
        "root" : {
          "$ref" : "#"
        },
        "sub1" : {
          "type" : "string"
        },
        "sub2" : {
          "$ref" : "#/definitions/Sub2-2"
        }
      }
    },
    "Sub2-1" : {
      "type" : "object",
      "properties" : {
        "root" : {
          "$ref" : "#"
        },
        "sub2" : {
          "type" : "string"
        }
      }
    },
    "Sub2-2" : {
      "allOf" : [ {
        "$ref" : "#/definitions/Sub2-1"
      }, {
        "type" : "object",
        "properties" : {
          "type" : {
            "const" : "json_test.Sub2"
          }
        },
        "required" : [ "type" ]
      } ]
    }
  },
  "type" : "object",
  "properties" : {
    "rootName" : {
      "type" : "string"
    },
    "superclass1" : {
      "type" : "array",
      "items" : {
        "anyOf" : [ {
          "allOf" : [ {
            "$ref" : "#/definitions/Sub1"
          }, {
            "type" : "object",
            "properties" : {
              "type" : {
                "const" : "json_test.Sub1"
              }
            },
            "required" : [ "type" ]
          } ]
        }, {
          "$ref" : "#/definitions/Sub2-2"
        } ]
      }
    }
  }
}

如果 sub1 类的属性引用 sub2 类,以及 @jsontypeinpeinfo(use = jsontypeinfo.id.class,include = jsontypeinfo.as.property,属性=“ type”))。

有人可以向我解释为什么它会生成 sub2-1 sub2-2 ,而不仅仅是 sub2 在“定义”部分中?

谢谢

- Jaap

Using the JSON schema generator from victools (this generates a JSON schema based on Java classes), I get a strange result if I relate two classes with a common supertype, and @JsonTypeName is used.

Please consider the following code:

@JsonTypeName("Root")
public class Root {
    private String rootName;
    ... 
    private List<SuperClass1> superclass1 = new ArrayList<SuperClass1>();
    ...
}

@JsonTypeName("SuperClass1")
@JsonTypeInfo(  use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({ @JsonSubTypes.Type(value = Sub1.class, name = "Sub1"),
@JsonSubTypes.Type(value = Sub2.class, name = "Sub2")})
public abstract class SuperClass1 {
    String name;
    int someThingElse;
    
    Root root;

    ...
}
@JsonTypeName("Sub1")
public class Sub1 extends SuperClass1 {
    String sub1;
    ...
    Sub2 sub2;
    ...
}
@JsonTypeName("Sub2")
public class Sub2 extends SuperClass1{
    String sub2;
    ...
}

generates the following JSON schema:

{
  "$schema" : "http://json-schema.org/draft-07/schema#",
  "definitions" : {
    "Sub1" : {
      "type" : "object",
      "properties" : {
        "root" : {
          "$ref" : "#"
        },
        "sub1" : {
          "type" : "string"
        },
        "sub2" : {
          "$ref" : "#/definitions/Sub2-2"
        }
      }
    },
    "Sub2-1" : {
      "type" : "object",
      "properties" : {
        "root" : {
          "$ref" : "#"
        },
        "sub2" : {
          "type" : "string"
        }
      }
    },
    "Sub2-2" : {
      "allOf" : [ {
        "$ref" : "#/definitions/Sub2-1"
      }, {
        "type" : "object",
        "properties" : {
          "type" : {
            "const" : "json_test.Sub2"
          }
        },
        "required" : [ "type" ]
      } ]
    }
  },
  "type" : "object",
  "properties" : {
    "rootName" : {
      "type" : "string"
    },
    "superclass1" : {
      "type" : "array",
      "items" : {
        "anyOf" : [ {
          "allOf" : [ {
            "$ref" : "#/definitions/Sub1"
          }, {
            "type" : "object",
            "properties" : {
              "type" : {
                "const" : "json_test.Sub1"
              }
            },
            "required" : [ "type" ]
          } ]
        }, {
          "$ref" : "#/definitions/Sub2-2"
        } ]
      }
    }
  }
}

This happens if a property of the Sub1 class refers to the Sub2 class, and @JsonTypeInfo( use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type") is used.

Can someone explain me why it generates Sub2-1 and Sub2-2, and not just Sub2 in the definitions section?

Thanks,

-- Jaap

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

山田美奈子 2025-02-17 04:29:10

区别在于架构生成器的内部工作:

  • sub2-1 表示“原始”类型,如果您将
  • sub2-2 代表 sub2-1 在杰克逊通常添加的附加“类型”属性中

,如果 sub2-1 仅引用一次,则应将其列入第二个架构,因此允许将第二个架构标记为 sub2 。至少对于 sub1 ,似乎按预期工作。

我建议您在 victools github存储库上提供一个完整的可重复示例,作为“问题”,我可以看看这是一个很容易解决的错误还是至少由您的特定设置解释。

注意:我是该库的维护者。

The difference is due to the inner workings of the schema generator:

  • Sub2-1 represents the “raw” type if you will
  • Sub2-2 represents Sub2-1 with the additional “type” property added by Jackson

Normally, if Sub2-1 is only referenced once, it should be inlined into the second schema and therefore allow that second schema to be labelled as just Sub2. At least for Sub1 that appears to be working as intended.

I suggest you provide a full reproducible example as “Issue” on the victools GitHub repository and I can take a look, whether this is a bug that can be easily fixed or at least explained by your specific setup.

Note: I’m the maintainer of that library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文