OpenAPI生成Java类后返回额外$Ref字段的解决方法咨询
解决OpenAPI生成类中$ref序列化冗余字段问题
方案1:调整OpenAPI Maven插件生成配置(根源解决)
如果使用openapi-generator-maven-plugin,可通过配置让生成的Java类自动带上Jackson注解,强制指定序列化字段名:
在插件的<configuration>中添加以下配置:
<configOptions> <useJacksonAnnotations>true</useJacksonAnnotations> </configOptions>
开启useJacksonAnnotations后,生成的$ref字段会自动添加@JsonProperty("$ref")注解,此时即便getter方法名为get$Ref,Jackson序列化时也会优先使用注解指定的字段名,不会出现$Ref冗余字段。
若上述配置无法满足需求,还可自定义Velocity模板修正getter/setter命名规则:
- 复制插件默认的
model.mustache模板文件到项目目录 - 修改模板中生成getter/setter的逻辑,将
$ref对应的方法名改为getRef()/setRef(),同时保留@JsonProperty("$ref")注解 - 在插件配置中指定自定义模板路径:
<configuration> <templateDirectory>${project.basedir}/src/main/resources/openapi-templates</templateDirectory> </configuration>
方案2:使用Jackson Mixin动态添加注解(无需修改生成类)
无法调整插件配置时,可借助Jackson的Mixin特性,在不修改生成类的前提下修正序列化规则:
- 创建对应生成模型类的Mixin抽象类:
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonIgnore; public abstract class YourModelMixin { @JsonProperty("$ref") private String $ref; @JsonIgnore public abstract String get$Ref(); @JsonIgnore public abstract void set$Ref(String ref); }
- 在Spring Boot项目中注册Mixin到ObjectMapper:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); // 替换为实际的生成模型类 module.setMixInAnnotation(YourGeneratedModel.class, YourModelMixin.class); mapper.registerModule(module); return mapper; } }
Jackson序列化时会遵循Mixin定义的规则,只输出$ref字段,忽略get$Ref方法对应的$Ref字段。
方案3:全局配置Jackson序列化策略(批量处理)
若多个生成类存在相同问题,可自定义序列化策略统一处理:
- 实现自定义PropertyNamingStrategy:
import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; public class RefPropertyNamingStrategy extends PropertyNamingStrategy { @Override public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { if ("$Ref".equals(defaultName)) { return "$ref"; } return super.nameForGetterMethod(config, method, defaultName); } }
- 在Spring Boot中全局配置该策略:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.setPropertyNamingStrategy(new RefPropertyNamingStrategy()); return mapper; } }
该策略会将所有get$Ref方法映射为$ref字段,避免出现大小写不同的冗余字段。
内容的提问来源于stack exchange,提问作者Rind
相关产品推荐
相关产品推荐

