[java] Use @JsonFormat instead of @JsonSerialize for bigDecimalAsString property (#19322)

* [java] Use @JsonFormat instead of @JsonSerialize so that JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN is respected and generates a String using BigDecimal#toPlainString instead of BigDecimal#toString

* Only add Jackson @JsonFormat if properties serializeBigDecimalAsString and jackson are enabled

* Do not verify if jackson is available when mapping imports as the property is not evaluated yet

* Removed unused JsonSerialize and ToStringSerializer
This commit is contained in:
Anderson de Borba 2024-08-28 09:22:13 +01:00 committed by GitHub
parent e69fb86957
commit 85763cdb08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 17 additions and 37 deletions

View File

@ -568,15 +568,16 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.sanitizeConfig();
// optional jackson mappings for BigDecimal support
importMapping.put("ToStringSerializer", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer");
importMapping.put("JsonSerialize", "com.fasterxml.jackson.databind.annotation.JsonSerialize");
importMapping.put("JsonDeserialize", "com.fasterxml.jackson.databind.annotation.JsonDeserialize");
if (serializeBigDecimalAsString) {
importMapping.put("JsonFormat", "com.fasterxml.jackson.annotation.JsonFormat");
}
// imports for pojos
importMapping.put("ApiModelProperty", "io.swagger.annotations.ApiModelProperty");
importMapping.put("ApiModel", "io.swagger.annotations.ApiModel");
importMapping.put("Schema", "io.swagger.v3.oas.annotations.media.Schema");
importMapping.put("BigDecimal", "java.math.BigDecimal");
importMapping.put("JsonDeserialize", "com.fasterxml.jackson.databind.annotation.JsonDeserialize");
importMapping.put("JsonProperty", "com.fasterxml.jackson.annotation.JsonProperty");
importMapping.put("JsonSubTypes", "com.fasterxml.jackson.annotation.JsonSubTypes");
importMapping.put("JsonTypeInfo", "com.fasterxml.jackson.annotation.JsonTypeInfo");
@ -1705,11 +1706,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
if (serializeBigDecimalAsString && jackson) {
if ("decimal".equals(property.baseType) || "bigdecimal".equalsIgnoreCase(property.baseType)) {
// we serialize BigDecimal as `string` to avoid precision loss
property.vendorExtensions.put("x-extra-annotation", "@JsonSerialize(using = ToStringSerializer.class)");
property.vendorExtensions.put("x-extra-annotation", "@JsonFormat(shape = JsonFormat.Shape.STRING)");
// this requires some more imports to be added for this model...
model.imports.add("ToStringSerializer");
model.imports.add("JsonSerialize");
model.imports.add("JsonFormat");
}
}
@ -1727,7 +1727,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
model.imports.add("Arrays");
} else if ("set".equals(property.containerType)) {
model.imports.add("LinkedHashSet");
if ((!openApiNullable || !property.isNullable) && jackson) { // cannot be wrapped to nullable
if ((!openApiNullable || !property.isNullable) && jackson) { // cannot be wrapped to nullable
model.imports.add("JsonDeserialize");
property.vendorExtensions.put("x-setter-extra-annotation", "@JsonDeserialize(as = LinkedHashSet.class)");
}

View File

@ -132,9 +132,6 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
super.postProcessModelProperty(model, property);
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
if (jackson) {
//Add jackson imports when model has inner enum

View File

@ -227,8 +227,7 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
super.postProcessModelProperty(model, property);
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
model.imports.remove("JsonFormat");
//Add imports for Jackson when model has inner enum
if (isJackson()) {

View File

@ -937,8 +937,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
if (MICROPROFILE.equals(getLibrary())) {
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
}
if (!BooleanUtils.toBoolean(model.isEnum)) {

View File

@ -371,14 +371,10 @@ public class JavaHelidonClientCodegen extends JavaHelidonCommonCodegen {
if (HELIDON_MP.equals(getLibrary())) {
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
} else if (HELIDON_SE.equals(getLibrary())) {
// TODO check for SE-specifics
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
}
if ("set".equals(property.containerType) && !JACKSON.equals(serializationLibrary)) {

View File

@ -250,8 +250,6 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
codegenModel.imports.remove("ApiModel");
}
if (!jackson) {
codegenModel.imports.remove("JsonSerialize");
codegenModel.imports.remove("ToStringSerializer");
codegenModel.imports.remove("JsonValue");
codegenModel.imports.remove("JsonProperty");
}

View File

@ -435,10 +435,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
typeMapping.put("map", "kotlin.collections.MutableMap");
}
// optional jackson mappings for BigDecimal support
importMapping.put("ToStringSerializer", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer");
importMapping.put("JsonSerialize", "com.fasterxml.jackson.databind.annotation.JsonSerialize");
// Swagger import mappings
importMapping.put("ApiModel", "io.swagger.annotations.ApiModel");
importMapping.put("ApiModelProperty", "io.swagger.annotations.ApiModelProperty");

View File

@ -2626,7 +2626,7 @@ public class JavaClientCodegenTest {
/**
* Regression test for <a href="https://github.com/OpenAPITools/openapi-generator/issues/6496">#6496</a>
*/
@Test void doesNotGenerateJacksonToStringSerializerAnnotation_whenLibraryIsGson_andSerializeBigDecimalAsStringIsTrue() {
@Test void doesNotGenerateJacksonJsonFormatAnnotation_whenLibraryIsGson_andSerializeBigDecimalAsStringIsTrue() {
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setLibrary(JavaClientCodegen.OKHTTP_GSON)
@ -2643,10 +2643,8 @@ public class JavaClientCodegenTest {
assertThat(files).hasSize(1).first(FILE).content()
.doesNotContain(
"@JsonDeserialize(as = LinkedHashSet.class)",
"@JsonSerialize(using = ToStringSerializer.class)",
"com.fasterxml.jackson.databind.ser.std.ToStringSerializer",
"com.fasterxml.jackson.databind.annotation.JsonDeserialize",
"com.fasterxml.jackson.databind.annotation.JsonSerialize"
"@JsonFormat(shape = JsonFormat.Shape.STRING)",
"com.fasterxml.jackson.databind.annotation.JsonDeserialize"
);
}
@ -2654,7 +2652,7 @@ public class JavaClientCodegenTest {
* Test that fix for <a href="https://github.com/OpenAPITools/openapi-generator/issues/6496">#6496</a> has
* no unwanted side effects on the existing feature (Jackson + bigDecimalAsString)
*/
@Test void generatesJacksonToStringSerializerAnnotation_whenLibraryIsJackson_andSerializeBigDecimalAsStringIsTrue() {
@Test void generatesJacksonJsonFormatAnnotation_whenLibraryIsJackson_andSerializeBigDecimalAsStringIsTrue() {
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setLibrary(JavaClientCodegen.NATIVE)
@ -2672,10 +2670,8 @@ public class JavaClientCodegenTest {
assertThat(files).hasSize(1).first(FILE).content()
.contains(
"@JsonDeserialize(as = LinkedHashSet.class)",
"@JsonSerialize(using = ToStringSerializer.class)",
"com.fasterxml.jackson.databind.ser.std.ToStringSerializer",
"com.fasterxml.jackson.databind.annotation.JsonDeserialize",
"com.fasterxml.jackson.databind.annotation.JsonSerialize"
"@JsonFormat(shape = JsonFormat.Shape.STRING)",
"com.fasterxml.jackson.databind.annotation.JsonDeserialize"
);
}

View File

@ -2478,11 +2478,11 @@ public class SpringCodegenTest {
Map<String, File> files = generateFiles(codegen, "src/test/resources/bugs/issue_14252.yaml");
JavaFileAssert.assertThat(files.get("MyResponse.java"))
.hasImports("com.fasterxml.jackson.databind.annotation.JsonSerialize", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer")
.hasImports("com.fasterxml.jackson.annotation.JsonFormat")
.assertMethod("getMyPropTypeNumber")
.assertMethodAnnotations()
.containsWithNameAndAttributes("JsonSerialize", ImmutableMap.of(
"using", "ToStringSerializer.class"
.containsWithNameAndAttributes("JsonFormat", ImmutableMap.of(
"shape", "JsonFormat.Shape.STRING"
));
}