Swagger UI中Map类型字段示例值序列化为字符串的解决方法
@ApiModelProperty的example参数仅接收字符串类型输入,Swagger渲染示例时会直接将该字符串作为字段值输出,不会主动将字符串形式的JSON片段反序列化为Map类型的结构化对象。即使配置了dataType = "java.util.Map",也不会覆盖example参数的直接渲染逻辑,最终导致示例中data字段被转义为字符串值。
根据项目使用的Swagger实现版本选择对应方案即可:
方案1:通过字段默认值生成示例(兼容性最好,配置最简单)
移除data字段@ApiModelProperty注解中原有的字符串形式example配置,给字段添加Map类型的默认示例值,Swagger扫描时会自动识别字段类型与默认值,按正确结构渲染示例,修改后的数据类代码如下:data class LoadTestRequest ( @ApiModelProperty(example = "https://...", required = true, value = "Url to send request") val url: String, @ApiModelProperty(example = "POST", required = true, value = "HttpMethod for a request") val method: HttpMethod, @ApiModelProperty(required = true, value = "Parameters for a request", dataType = "java.util.Map") val data: Map<String, String> = mapOf("key" to "value") )该方案不需要额外调整Swagger全局配置,兼容Springfox 2.x、springdoc-openapi 3.x等主流Swagger实现。
方案2:springdoc-openapi(OpenAPI 3规范)结构化示例配置
如果项目已经替换停止维护的Springfox,使用springdoc-openapi作为Swagger实现,可以通过@Schema注解的示例配置直接声明结构化的Map值,不会被转义为字符串:import io.swagger.v3.oas.annotations.media.Schema import io.swagger.v3.oas.annotations.media.ExampleObject data class LoadTestRequest ( @Schema(example = "https://...", requiredMode = Schema.RequiredMode.REQUIRED, description = "Url to send request") val url: String, @Schema(example = "POST", requiredMode = Schema.RequiredMode.REQUIRED, description = "HttpMethod for a request") val method: HttpMethod, @Schema( requiredMode = Schema.RequiredMode.REQUIRED, description = "Parameters for a request", examples = [ExampleObject(value = "{\"key\": \"value\"}")] ) val data: Map<String, String> )方案3:Springfox 2.x 接口级示例配置
如果必须使用老版本Springfox,不要在字段级@ApiModelProperty上为Map、自定义对象等非基础类型配置字符串形式的example,改为在对应接口方法上配置完整的请求体示例:import io.swagger.annotations.ApiOperation import io.swagger.annotations.Example import io.swagger.annotations.ExampleProperty @ApiOperation( value = "发起压测请求", examples = Example( value = [ ExampleProperty( mediaType = "application/json", value = """ { "url": "https://...", "method": "POST", "data": {"key": "value"} } """ ) ] ) ) @PostMapping("/load-test") fun runLoadTest(@RequestBody request: LoadTestRequest) { // 接口业务逻辑 }
注意:不要在字段级别的Swagger注解中,给对象、Map、数组等非基础类型直接传入字符串格式的JSON作为example值,这类输入都会被Swagger默认识别为字符串类型做转义渲染。
内容的提问来源于stack exchange,提问作者Ruslan

