Skip to content

Commit 691c768

Browse files
authored
Merge pull request #3380 from swagger-api/ticket-3365
refs #3365 - fix schema example resolving edge case strings
2 parents 0af0bca + 8e59b75 commit 691c768

File tree

4 files changed

+90
-2
lines changed

4 files changed

+90
-2
lines changed

modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import io.swagger.v3.core.util.AnnotationsUtils;
3131
import io.swagger.v3.core.util.Constants;
3232
import io.swagger.v3.core.util.Json;
33+
import io.swagger.v3.core.util.ObjectMapperFactory;
3334
import io.swagger.v3.core.util.PrimitiveType;
3435
import io.swagger.v3.core.util.ReflectionUtils;
3536
import io.swagger.v3.oas.annotations.media.DiscriminatorMapping;
@@ -1424,7 +1425,8 @@ protected Object resolveExample(Annotated a, Annotation[] annotations, io.swagge
14241425
if (schema != null) {
14251426
if (!schema.example().isEmpty()) {
14261427
try {
1427-
return Json.mapper().readTree(schema.example());
1428+
ObjectMapper mapper = ObjectMapperFactory.buildStrictGenericObjectMapper();
1429+
return mapper.readTree(schema.example());
14281430
} catch (IOException e) {
14291431
return schema.example();
14301432
}

modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.fasterxml.jackson.annotation.JsonView;
44
import com.fasterxml.jackson.databind.JavaType;
55
import com.fasterxml.jackson.databind.JsonNode;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
67
import com.fasterxml.jackson.databind.introspect.Annotated;
78
import io.swagger.v3.core.converter.AnnotatedType;
89
import io.swagger.v3.core.converter.ModelConverters;
@@ -347,7 +348,8 @@ private static boolean resolveExample(Example exampleObject, ExampleObject examp
347348
if (StringUtils.isNotBlank(example.value())) {
348349
isEmpty = false;
349350
try {
350-
exampleObject.setValue(Json.mapper().readTree(example.value()));
351+
ObjectMapper mapper = ObjectMapperFactory.buildStrictGenericObjectMapper();
352+
exampleObject.setValue(mapper.readTree(example.value()));
351353
} catch (IOException e) {
352354
exampleObject.setValue(example.value());
353355
}
@@ -1895,4 +1897,5 @@ public Extension[] extensions() {
18951897

18961898
return (io.swagger.v3.oas.annotations.media.ArraySchema)newArraySchema;
18971899
}
1900+
18981901
}

modules/swagger-core/src/main/java/io/swagger/v3/core/util/ObjectMapperFactory.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,17 @@ public JsonSerializer<?> modifySerializer(
143143

144144
return mapper;
145145
}
146+
147+
public static ObjectMapper buildStrictGenericObjectMapper() {
148+
ObjectMapper mapper = new ObjectMapper();
149+
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
150+
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
151+
mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
152+
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
153+
mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
154+
mapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true);
155+
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
156+
return mapper;
157+
}
158+
146159
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package io.swagger.v3.core.resolving;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import io.swagger.v3.core.converter.AnnotatedType;
5+
import io.swagger.v3.core.converter.ModelConverterContextImpl;
6+
import io.swagger.v3.core.jackson.ModelResolver;
7+
import io.swagger.v3.core.matchers.SerializationMatchers;
8+
import io.swagger.v3.oas.models.media.Schema;
9+
import org.testng.annotations.BeforeMethod;
10+
import org.testng.annotations.Test;
11+
12+
import static org.testng.Assert.assertNotNull;
13+
14+
public class Ticket3365Test extends SwaggerTestBase {
15+
16+
private ModelResolver modelResolver;
17+
private ModelConverterContextImpl context;
18+
19+
@BeforeMethod
20+
public void beforeMethod() {
21+
modelResolver = new ModelResolver(new ObjectMapper());
22+
context = new ModelConverterContextImpl(modelResolver);
23+
}
24+
25+
@Test
26+
public void testTicket3365() {
27+
Schema model = context.resolve(new AnnotatedType(ExampleWithJson.class));
28+
assertNotNull(model);
29+
SerializationMatchers.assertEqualsToYaml(model, "required:\n" +
30+
"- param1\n" +
31+
"type: object\n" +
32+
"properties:\n" +
33+
" param1:\n" +
34+
" title: Cron formatted invoice schedule\n" +
35+
" type: object\n" +
36+
" example:\n" +
37+
" type: array\n" +
38+
" items:\n" +
39+
" type: string\n" +
40+
" format: byte");
41+
42+
model = context.resolve(new AnnotatedType(ExampleStartingWithInteger.class));
43+
assertNotNull(model);
44+
SerializationMatchers.assertEqualsToYaml(model, "required:\n" +
45+
"- param1\n" +
46+
"type: object\n" +
47+
"properties:\n" +
48+
" param1:\n" +
49+
" title: Cron formatted invoice schedule\n" +
50+
" type: string\n" +
51+
" example: 0 0 5 * *\n");
52+
}
53+
54+
static class ExampleStartingWithInteger {
55+
@io.swagger.v3.oas.annotations.media.Schema(
56+
required = true,
57+
title = "Cron formatted invoice schedule",
58+
example = "0 0 5 * *"
59+
)
60+
public String param1;
61+
}
62+
static class ExampleWithJson {
63+
@io.swagger.v3.oas.annotations.media.Schema(
64+
required = true,
65+
title = "Cron formatted invoice schedule",
66+
example = "{\"type\": \"array\", \"items\": {\"type\" : \"string\", \"format\": \"byte\"}}"
67+
)
68+
public Object param1;
69+
}
70+
}

0 commit comments

Comments
 (0)