Swagger中能否将JsonObject用作属性?相关实例化报错如何解决
问题解答
1. Swagger是否支持JsonObject作为属性
是可以的,你遇到的报错本质是Jackson反序列化Klaxon JsonObject失败的问题,和Swagger本身配置无关。
2. 报错原因
你使用的是com.beust.klaxon.JsonObject,该类的构造函数需要传入一个非空的map参数,Jackson在默认反序列化规则下,无法直接把传入的JSON结构实例化为Klaxon的JsonObject对象,因此会抛出缺少非空参数map的错误。
3. 排查解决步骤
- 方案1:替换JsonObject类型为Jackson原生支持的类型
直接把jsonEntity的类型改为com.fasterxml.jackson.databind.JsonNode,不需要额外配置反序列化规则,Swagger的示例配置也能正常生效,修改后代码如下:
后续如果需要转Klaxon JsonObject,直接调用@ApiModel() class RequestBody( @ApiModelProperty(example = "John Doe") val name: String? = null, @ApiModelProperty(example = "Coolstreet 1") val address: String? = null, @ApiModelProperty(example = """ { "name" : "HDD", "capacityInGb" : 512, "sizeInInch" : 2.5 } """) val jsonEntity: JsonNode? = null )Klaxon().parseJsonObject(jsonEntity.toString())转换即可。 - 方案2:为Klaxon JsonObject注册自定义反序列化器
如果必须保留JsonObject类型,可以给Jackson添加Klaxon JsonObject的反序列化规则:- 自定义反序列化类:
class KlaxonJsonObjectDeserializer : StdDeserializer<JsonObject>(JsonObject::class.java) { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): JsonObject { val map = p.readValueAs<Map<String, Any>>(Map::class.java) return JsonObject(map) } }- 将反序列化器注册到Jackson的ObjectMapper中:
@Configuration class JacksonConfig { @Bean fun objectMapper(): ObjectMapper { val module = SimpleModule() module.addDeserializer(JsonObject::class.java, KlaxonJsonObjectDeserializer()) return ObjectMapper() .registerModule(KotlinModule()) .registerModule(module) } } - 方案3:直接用Map类型接收
把jsonEntity类型改为Map<String, Any>?,不需要额外配置,后续如果需要转JsonObject直接传入Map构造即可。
额外注意
你提供的代码中@ApiModelPropery拼写错误,正确写法是@ApiModelProperty,也有可能是拼写错误导致Swagger的示例配置未生效,测试时传入空值触发报错。
内容的提问来源于stack exchange,提问作者Dimitry
相关产品推荐
相关产品推荐

