当前位置: 首页 > 知识库问答 >
问题:

Swagger将Mongo ObjectId显示为复杂的JSON而不是String

汪信鸥
2023-03-14

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

@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,而不是一个普通的String,作为id属性:

@ApiModelProperty(dataType=“string”)添加到id字段没有任何区别,我无法找到一种方法来解决这个问题,而不将项目中的所有id字段更改为string。任何帮助都将不胜感激。

共有2个答案

潘辰龙
2023-03-14

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

static {
     SpringDocUtils.getConfig().replaceWithSchema(ObjectId.class, new StringSchema());
}
尹承业
2023-03-14

我无法让@ApiModelProperty(dataType = "")工作,但我发现了一种更方便的方法,即在Swagger配置中使用此响应中Docket实例的DirectModelSub0004方法配置直接替代品。

@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);
}
 类似资料:
  • 试图制作一个简单的应用程序,从服务器获取JSON数据,并在自定义列表中显示它们,非常简单的事情。 但当我运行应用程序时,它显示的是白色空白屏幕,但没有数据。它也没有显示任何错误,我假设如果有任何错误,它不会在我的手机中运行。但不显示获取的数据。 下面是类 我发现的其他问题与我的问题不匹配,否则不会添加这个问题。

  • 我有一个HashMap对象,它将存储在NoSQL数据库中。当它有条目时,它看起来像: 如果db中不存在此“input”,我希望响应显示“input”:{},而不是“input”:null。最好的方法是什么? 谢谢

  • 此表单在基于函数的视图中显示单选按钮,但在我引入基于类的视图时更改为复选框,有什么解决办法。我希望他们再次显示单选按钮 表单.py models.py 模板 views.py

  • 我正在使用swagger工具来记录我基于Jersey的REST API(我正在使用的swaggerui是在2014年6月下载的,我不知道这个问题是否在以后的版本中得到了解决,但由于我对其代码进行了大量定制,所以我没有选择下载最新版本,而无需再次投入大量时间进行定制)。 到目前为止,我所有的传输对象都有一级深度属性(没有嵌入的POJO)。但现在,我添加了一些返回更复杂对象(两级深度)的rest路径,

  • 我试图用Swagger来描述我正在构建的web-api。问题是我无法理解如何描述复杂的json对象? 比如如何描述这个对象:

  • 我有一个spring的网络应用程序,我增加了swagger和swagger-UI。我添加了一个虚拟类来测试Swagger: 构建/部署之后,我可以在swagger页面上看到虚拟类(参见附件1)。问题是,“列表操作”没有显示任何内容。原始输出如下: 我想,问题是一个缺失的标签“操作”或类似的东西……但我不确定(也不知道,如何修复这一点)。有什么建议吗?