Springfox 3.0.0为何仅对嵌套对象忽略@XmlElement注解?
问题根因
Springfox 3.x的Swagger示例生成逻辑和业务侧配置的XmlMapper完全隔离,它自带的模型属性解析逻辑仅对基础类型(String、Instant等)会正确读取@XmlElement的name属性,对自定义POJO类型的字段会直接跳过JAXB注解的读取,默认使用字段的小驼峰原名,因此出现了嵌套对象字段bar、anotherBar没有按配置首字母大写的问题。
可行解决方案
所有方案均不会影响接口实际返回的JSON格式,符合你不能使用@JsonProperty的要求:
方案1:加注解单独覆盖Swagger属性名(侵入性最小)
Springfox提供的@ApiModelProperty注解只会修改Swagger文档的展示内容,不会影响接口实际序列化逻辑,直接在对应字段上配置即可:
@XmlRootElement(name = "Foo") public class Foo { @XmlElement(name = "MyDate") private Instant myDate; @XmlElement(name = "Bar") @ApiModelProperty(name = "Bar") private Bar bar; @XmlElement(name = "AnotherBar") @ApiModelProperty(name = "AnotherBar") private Bar anotherBar; // Getter / Setter... }
方案2:全局自定义Springfox解析插件(无业务代码侵入)
可以扩展Springfox的属性解析逻辑,全局统一读取@XmlElement的name属性,无需修改业务类代码:
- 新增自定义插件类:
import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin; import springfox.documentation.spi.schema.contexts.ModelPropertyContext; import javax.xml.bind.annotation.XmlElement; import java.util.Optional; @Component @Order(Integer.MAX_VALUE) // 最后执行覆盖默认解析结果 public class XmlElementNameReaderPlugin implements ModelPropertyBuilderPlugin { @Override public void apply(ModelPropertyContext context) { Optional<XmlElement> xmlAnno = context.findAnnotation(XmlElement.class); if (xmlAnno.isPresent()) { String configName = xmlAnno.get().name(); if (!"##default".equals(configName)) { context.getBuilder().name(configName); } } } @Override public boolean supports(DocumentationType delimiter) { return DocumentationType.OAS_30.equals(delimiter) || DocumentationType.SWAGGER_2.equals(delimiter); } }
- 在Spring配置类中扫描到该插件类即可生效,后续所有标注了
@XmlElement的字段,不管是基础类型还是自定义POJO类型,都会正确识别别名。
方案3:切换为SpringDoc替代Springfox
如果允许调整依赖,SpringDoc作为Springfox的官方替代项目,已经原生修复了JAXB注解的兼容问题,无需额外配置就能正确识别嵌套对象上的@XmlElement注解,同时可以保证JSON、XML的序列化结果和Swagger展示完全一致。
内容的提问来源于stack exchange,提问作者JsonMraz
相关产品推荐
相关产品推荐

