我有一个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而不是简单的String
作为id
属性:
将@ApiModelProperty(dataType = "string")
添加到id
字段没有什么影响,并且我无法找到一种解决方案,而无需将项目中的所有id
字段都更改为String
。任何帮助,将不胜感激。
我无法使@ApiModelProperty(dataType = "")
工作,但是我发现了一种更方便的方法,即使用directModelSubstitute
中Docket
实例的this response方法在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);
}