【问题标题】:Swagger shows Mongo ObjectId as complex JSON instead of StringSwagger 将 Mongo ObjectId 显示为复杂的 JSON 而不是 String
【发布时间】:2019-10-14 11:15:10
【问题描述】:

项目设置

我有一个 Kotlin Spring Boot 2.0 项目,它公开了一个返回 MongoDB 模型的 @RestController API。比如这个模型和控制器:

@RestController
@RequestMapping("/api/accounts")
class AccountsController() {
    @GetMapping
    fun list(): List<Account> {
        return listOf(Account(ObjectId(), "Account 1"), Account(ObjectId(), "Account 2"), Account(ObjectId(), "Account 3"))
    }
}

@Document
data class Account(
        @Id val id: ObjectId? = null,
        val name: String
)

这些模型具有 ObjectId 标识符,但在 API 中,我希望它们被视为普通的 String(即默认行为而不是复杂的 JSON)。

为此,我创建了这些组件来配置 Spring Boot 参数绑定和 JSON 解析:

@JsonComponent
class ObjectIdJsonSerializer : JsonSerializer<ObjectId>() {
    override fun serialize(value: ObjectId?, gen: JsonGenerator?, serializers: SerializerProvider?) {
        if (value == null || gen == null) return

        gen.writeString(value.toHexString())
    }
}

@JsonComponent
class ObjectIdJsonDeserializer : JsonDeserializer<ObjectId>() {
    override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): ObjectId? {
        if (p == null) return null

        val text = p.getCodec().readTree<TextNode>(p).textValue()
        return ObjectId(text)

    }
}

@Component
class StringToObjectIdConverter : Converter<String, ObjectId> {
    override fun convert(source: String): ObjectId? {
        return ObjectId(source)
    }
}

到目前为止,这按预期工作,对 API 的调用返回此 JSON:

[
  {
    "id": "5da454f4307b0a8b30838839",
    "name": "Account 1"
  },
  {
    "id": "5da454f4307b0a8b3083883a",
    "name": "Account 2"
  },
  {
    "id": "5da454f4307b0a8b3083883b",
    "name": "Account 3"
  }
]

问题

将 Swagger 集成到项目中时出现问题,文档显示调用此方法返回复杂的 JSON,而不是作为 id 属性的普通 String

@ApiModelProperty(dataType = "string") 添加到id 字段没有任何区别,如果不将项目中的所有id 字段更改为String,我找不到解决方法。任何帮助将不胜感激。

【问题讨论】:

标签: spring spring-boot kotlin swagger swagger-ui


【解决方案1】:

我无法让@ApiModelProperty(dataType = "") 工作,但我发现了一种更方便的方法,可以使用this responseDocket 实例的directModelSubstitute 方法在Swagger 配置中配置直接替代。

@Configuration
@EnableSwagger2
class SwaggerConfig() {
    @Bean
    fun api(): Docket {
        return Docket(DocumentationType.SWAGGER_2)
                .directModelSubstitute(ObjectId::class.java, String::class.java)
    }
}

Java 等价物:

@Bean
public Docket api() {
    return new Docket(DocumentationType.SWAGGER_2)
            .directModelSubstitute(ObjectId.class, String.class);
}

【讨论】:

    【解决方案2】:

    对于 OpenApi (Swagger 3.0) 和 SpringDoc,可以使用以下全局配置。

    static {
         SpringDocUtils.getConfig().replaceWithSchema(ObjectId.class, new StringSchema());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      • 1970-01-01
      • 2019-07-27
      • 2021-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多