Skip to content

Commit 56d233b

Browse files
twobiersfrantuma
authored andcommitted
Resolves #3879
Fix @JsonUnwrapped does not copy required properties
1 parent ea4db2c commit 56d233b

File tree

4 files changed

+78
-2
lines changed

4 files changed

+78
-2
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
124124

125125
boolean isPrimitive = false;
126126
Schema model = null;
127+
List<String> requiredProps = new ArrayList<>();
127128

128129
if (annotatedType == null) {
129130
return null;
@@ -644,7 +645,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
644645
.ctxAnnotations(null)
645646
.jsonUnwrappedHandler(null)
646647
.resolveAsRef(false);
647-
handleUnwrapped(props, context.resolve(t), uw.prefix(), uw.suffix());
648+
handleUnwrapped(props, context.resolve(t), uw.prefix(), uw.suffix(), requiredProps);
648649
return null;
649650
} else {
650651
return new Schema();
@@ -709,6 +710,9 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
709710
}
710711
if (modelProps.size() > 0) {
711712
model.setProperties(modelProps);
713+
for(String propName : requiredProps) {
714+
addRequiredItem(model, propName);
715+
}
712716
}
713717

714718
/**
@@ -1021,10 +1025,14 @@ protected boolean ignore(final Annotated member, final XmlAccessorType xmlAccess
10211025
return false;
10221026
}
10231027

1024-
private void handleUnwrapped(List<Schema> props, Schema innerModel, String prefix, String suffix) {
1028+
private void handleUnwrapped(List<Schema> props, Schema innerModel, String prefix, String suffix, List<String> requiredProps) {
10251029
if (StringUtils.isBlank(suffix) && StringUtils.isBlank(prefix)) {
10261030
if (innerModel.getProperties() != null) {
10271031
props.addAll(innerModel.getProperties().values());
1032+
if(innerModel.getRequired() != null) {
1033+
requiredProps.addAll(innerModel.getRequired());
1034+
}
1035+
10281036
}
10291037
} else {
10301038
if (prefix == null) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package io.swagger.v3.core.resolving;
2+
3+
import io.swagger.v3.core.converter.ModelConverters;
4+
import io.swagger.v3.core.matchers.SerializationMatchers;
5+
import io.swagger.v3.core.resolving.resources.JacksonUnwrappedRequiredProperty;
6+
import org.testng.annotations.Test;
7+
8+
public class JacksonJsonUnwrappedTest {
9+
10+
@Test(description = "test the @JsonUnwrapped behaviour when required Properties")
11+
public void jacksonJsonUnwrappedTest() {
12+
13+
SerializationMatchers
14+
.assertEqualsToYaml(ModelConverters.getInstance().read(
15+
JacksonUnwrappedRequiredProperty.class), "InnerTypeRequired:\n" +
16+
" required:\n" +
17+
" - name\n" +
18+
" type: object\n" +
19+
" properties:\n" +
20+
" foo:\n" +
21+
" type: integer\n" +
22+
" format: int32\n" +
23+
" name:\n" +
24+
" type: string\n" +
25+
"JacksonUnwrappedRequiredProperty:\n" +
26+
" required:\n" +
27+
" - name\n" +
28+
" type: object\n" +
29+
" properties:\n" +
30+
" foo:\n" +
31+
" type: integer\n" +
32+
" format: int32\n" +
33+
" name:\n" +
34+
" type: string\n");
35+
}
36+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.swagger.v3.core.resolving.resources;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
public class InnerTypeRequired {
6+
public int foo;
7+
@Schema(required = true)
8+
public String name;
9+
10+
public String getName() {
11+
return name;
12+
}
13+
14+
public void setName(String name) {
15+
this.name = name;
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.swagger.v3.core.resolving.resources;
2+
3+
import com.fasterxml.jackson.annotation.JsonUnwrapped;
4+
5+
public class JacksonUnwrappedRequiredProperty {
6+
@JsonUnwrapped private final InnerTypeRequired innerType;
7+
8+
public JacksonUnwrappedRequiredProperty(InnerTypeRequired innerType) {
9+
this.innerType = innerType;
10+
}
11+
12+
public InnerTypeRequired getInnerType() {
13+
return innerType;
14+
}
15+
}

0 commit comments

Comments
 (0)