如何用OpenAPI定义非包装式XML响应及序列化问题
解决OpenAPI Generator生成模型的XML序列化问题
问题分析
你遇到的两个XML序列化问题,本质是OpenAPI Generator默认的数组XML映射规则不符合需求:
- 默认会给数组添加包装标签(比如
<TileMapServices>) - 默认会将数组字段名复数化作为元素标签名
要解决这两个问题,需要从OpenAPI规范定义和生成器配置两方面调整,确保生成的模型带有正确的Jackson XML注解。
解决方案
1. 修改OpenAPI YAML规范
在数组字段上添加XML扩展配置,指定不使用包装标签,同时强制元素标签名为单数形式:
openapi: 3.0.3 info: title: TileMap Service API version: 1.0.0 components: schemas: ServicesRoot: type: object xml: name: Services # 指定根标签为<Services> properties: tileMapServices: type: array items: $ref: '#/components/schemas/TileMapService' xml: wrapped: false # 禁用数组包装标签 name: TileMapService # 指定数组元素的XML标签名 TileMapService: type: object xml: name: TileMapService properties: name: type: string url: type: string
2. 调整Gradle插件配置
确保OpenAPI Generator正确生成Jackson XML注解,在openApiGenerate任务中添加必要的配置项:
Groovy DSL(build.gradle)
plugins { id 'org.openapi.generator' version '7.6.0' } openApiGenerate { generatorName = 'spring' inputSpec = "$rootDir/src/main/resources/openapi.yaml" outputDir = "$buildDir/generated/openapi" apiPackage = 'com.yourpackage.api' modelPackage = 'com.yourpackage.model' configOptions = [ withXml: 'true', xmlAnnotations: 'true', useJacksonXml: 'true', serializableModel: 'true' ] }
Kotlin DSL(build.gradle.kts)
plugins { id("org.openapi.generator") version "7.6.0" } openApiGenerate { generatorName.set("spring") inputSpec.set("$rootDir/src/main/resources/openapi.yaml") outputDir.set("$buildDir/generated/openapi") apiPackage.set("com.yourpackage.api") modelPackage.set("com.yourpackage.model") configOptions.set(mapOf( "withXml" to "true", "xmlAnnotations" to "true", "useJacksonXml" to "true", "serializableModel" to "true" )) }
3. 验证生成的模型
执行openApiGenerate任务后,生成的ServicesRoot类应该包含以下Jackson XML注解:
package com.yourpackage.model; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import java.util.List; @JacksonXmlRootElement(localName = "Services") public class ServicesRoot { @JacksonXmlElementWrapper(useWrapping = false) @JacksonXmlProperty(localName = "TileMapService") private List<TileMapService> tileMapServices; // Getters and Setters }
4. 序列化效果
使用Jackson XMLMapper序列化ServicesRoot对象时,会生成符合需求的XML结构:
<Services> <TileMapService> <name>Sample Service 1</name> <url>http://example.com/service1</url> </TileMapService> <TileMapService> <name>Sample Service 2</name> <url>http://example.com/service2</url> </TileMapService> </Services>
内容的提问来源于stack exchange,提问作者G. Fiedler
相关产品推荐
相关产品推荐

