java - 为什么鉴别器属性被序列化两次?

标签 java jackson swagger swagger-codegen openapi-generator

我在组件模式中使用 OpenAPI 3.0 继承,并且我有由 openapi-generator (使用 Jackson)生成的(Java)类。
为什么鉴别器属性在生成的 JSON 中被序列化两次?
这是一个 JHipster API-First 项目,它应该使用 openapi-generator 来生成 Java 模型(带有 Jackson 注释的 POJO)和 API Controller (与 Spring 的 @Api 注释的接口(interface))。
通过遵循 OpenAPI 3.x 文档/示例,似乎该属性用作 discriminator还必须在 properties 中指定架构列表。
这样,生成的 Java 类似乎与 Jackson 的多态类型处理指南(here)不同,其中用作鉴别器的属性不得出现在类中。相反,生成的代码还包含此属性作为具有 getter/setter 的类属性。这会导致 JSON 输出包含该属性两次,如下所示。
我还尝试从 OpenAPI properties 中删除该属性列表,保留 discriminator部分;这样生成的代码符合 jackson 的指导方针,并且序列化工作得很好。另一方面,我在反序列化过程中遇到错误,因为在目标类中找不到(删除的)属性。
遵循 OpenAPI 3.x 文档指南:

TicketEvent:
  type: object
  description: A generic event
  discriminator:
    propertyName: type
  required:
    - id
    - sequenceNumber
    - timestamp
    - type
  properties:
    id:
      type: integer
      format: int64
      readOnly: true
    sequenceNumber:
      type: integer
      readOnly: true
    timestamp:
      type: string
      format: date-time
      readOnly: true
    type:
      type: string
      readOnly: true
TicketMovedEvent:
  description: A ticket move event
  allOf:
    - $ref: '#/components/schemas/Event'
    - type: object
      required:
        - source
        - target
      properties:
        source:
          $ref: '#/components/schemas/Queue'
        target:
          $ref: '#/components/schemas/Queue'
生成的类:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
@JsonSubTypes({
  @JsonSubTypes.Type(value = TicketMovedEvent.class, name = "TicketMovedEvent")
})

public class TicketEvent   {
   ...

   @JsonProperty("type")
   private String type;
JSON 包含属性 两次 :
{
        ...
    "type": "TicketMovedEvent",
    "type": null,
        ...
}
properties 中删除鉴别器属性列表:
TicketEvent:
  type: object
  description: A generic event
  discriminator:
    propertyName: type
  required:
    - id
    - sequenceNumber
    - timestamp
  properties:
    id:
      type: integer
      format: int64
      readOnly: true
    sequenceNumber:
      type: integer
      readOnly: true
    timestamp:
      type: string
      format: date-time
      readOnly: true
生成的类没有 type属性(property):
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
@JsonSubTypes({
  @JsonSubTypes.Type(value = TicketMovedEvent.class, name = "TicketMovedEvent")
})

public class TicketEvent   {
   ...

   // now the "type" property is missing
})
JSON 现在是正确的:
{
        ...
    "type": "TicketMovedEvent",
        ...
}
我希望通过遵循 OpenAPI 3.x 指南,生成的类能够正确序列化/反序列化。
(边注)
在反序列化过程中,使用上述方法,您可能会收到以下错误:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type" (class it.blutec.bludesk.web.api.model.TicketMovedEvent), not marked as ignorable ...
要解决此问题,您需要配置 Jackson ObjectMapper 对象以忽略这种情况。
ObjectMapper om = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

最佳答案

我自己也遇到了这个。在 OpenApi 属性列表中不包括鉴别器字段确实可以解决序列化时的双字段问题,同时在反序列化时导致 UnrecognizedPropertyException。
经过反复试验,我发现第二个问题可以通过删除 "visible = true" 来解决。 @JsonTypeInfo 的属性(或将其设置为 false)生成代码中的注释。 (如果您将构建过程设置为始终从开放 API 规范重新生成代码,那么当然,这不是一个真正的解决方案)。

关于java - 为什么鉴别器属性被序列化两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57706241/

相关文章:

python - 如何使用蓝图将 Flasgger 与 Flask 应用程序一起使用?

kotlin - 如何在kotlin中使用@ApiResponse注解

java - 用 Java 替换大型文本文件中所有特殊字符和数字的有效方法

java - mapper.readValue 的后备类<?>

java - jackson 和 JAX-RS : type resolving abstract types based on @PathParam

java - 无法使用 jackson 将具有内部对象的JSON解析为Java对象

Python Swagger 问题

java - 如何设置 Flume 以收集简单文件中的日志

java - 尝试使用 OWASP ESAPI 库时出现 antisamy-esapi.xml not find 异常

java - .getInputStream() 出现问题