Skip to content

Commit 7bb5fc2

Browse files
committed
@JsonUnwrapped is ignored when PolymorphicConverter is enabled. Fixes #2640
1 parent 1fc8f9d commit 7bb5fc2

File tree

6 files changed

+151
-0
lines changed

6 files changed

+151
-0
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java

+8
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@
2424

2525
package org.springdoc.core.converters;
2626

27+
import java.lang.reflect.Field;
2728
import java.lang.reflect.Modifier;
2829
import java.util.ArrayList;
2930
import java.util.Collection;
3031
import java.util.Collections;
3132
import java.util.Iterator;
3233
import java.util.List;
3334

35+
import com.fasterxml.jackson.annotation.JsonUnwrapped;
3436
import com.fasterxml.jackson.databind.JavaType;
3537
import io.swagger.v3.core.converter.AnnotatedType;
3638
import io.swagger.v3.core.converter.ModelConverter;
@@ -39,6 +41,7 @@
3941
import io.swagger.v3.oas.models.media.ComposedSchema;
4042
import io.swagger.v3.oas.models.media.ObjectSchema;
4143
import io.swagger.v3.oas.models.media.Schema;
44+
import org.apache.commons.lang3.reflect.FieldUtils;
4245
import org.springdoc.core.providers.ObjectMapperProvider;
4346

4447
/**
@@ -98,6 +101,11 @@ else if (resolvedSchema.getProperties().containsKey(javaType.getRawClass().getSi
98101
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
99102
JavaType javaType = springDocObjectMapper.jsonMapper().constructType(type.getType());
100103
if (javaType != null) {
104+
for (Field field : FieldUtils.getAllFields(javaType.getRawClass())) {
105+
if (field.isAnnotationPresent(JsonUnwrapped.class)) {
106+
PARENT_TYPES_TO_IGNORE.add(javaType.getRawClass().getSimpleName());
107+
}
108+
}
101109
if (chain.hasNext()) {
102110
if (!type.isResolveAsRef() && type.getParent() != null
103111
&& PARENT_TYPES_TO_IGNORE.stream().noneMatch(ignore -> type.getParent().getName().startsWith(ignore)))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package test.org.springdoc.api.v30.app224;
2+
3+
import com.fasterxml.jackson.annotation.JsonUnwrapped;
4+
5+
public class RootModel {
6+
7+
private Integer rootProperty;
8+
9+
@JsonUnwrapped
10+
private UnwrappedModel unwrappedModel;
11+
12+
public Integer getRootProperty() {
13+
return rootProperty;
14+
}
15+
16+
public void setRootProperty(Integer rootProperty) {
17+
this.rootProperty = rootProperty;
18+
}
19+
20+
public UnwrappedModel getUnwrappedModel() {
21+
return unwrappedModel;
22+
}
23+
24+
public void setUnwrappedModel(UnwrappedModel unwrappedModel) {
25+
this.unwrappedModel = unwrappedModel;
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * * Copyright 2019-2022 the original author or authors.
7+
* * * * *
8+
* * * * * Licensed under the Apache License, Version 2.0 (the "License");
9+
* * * * * you may not use this file except in compliance with the License.
10+
* * * * * You may obtain a copy of the License at
11+
* * * * *
12+
* * * * * https://www.apache.org/licenses/LICENSE-2.0
13+
* * * * *
14+
* * * * * Unless required by applicable law or agreed to in writing, software
15+
* * * * * distributed under the License is distributed on an "AS IS" BASIS,
16+
* * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* * * * * See the License for the specific language governing permissions and
18+
* * * * * limitations under the License.
19+
* * * *
20+
* * *
21+
* *
22+
*
23+
*/
24+
25+
package test.org.springdoc.api.v30.app224;
26+
27+
import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
28+
29+
import org.springframework.boot.autoconfigure.SpringBootApplication;
30+
31+
public class SpringDocApp224Test extends AbstractSpringDocV30Test {
32+
33+
@SpringBootApplication
34+
static class SpringDocTestApp {}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package test.org.springdoc.api.v30.app224;
2+
3+
import org.springframework.web.bind.annotation.GetMapping;
4+
import org.springframework.web.bind.annotation.RequestMapping;
5+
import org.springframework.web.bind.annotation.RestController;
6+
7+
@RestController
8+
@RequestMapping("/api")
9+
public class TestController {
10+
11+
@GetMapping
12+
public RootModel getRootModel() {
13+
return new RootModel();
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package test.org.springdoc.api.v30.app224;
2+
3+
public class UnwrappedModel {
4+
5+
private Integer unwrappedProperty;
6+
7+
public Integer getUnwrappedProperty() {
8+
return unwrappedProperty;
9+
}
10+
11+
public void setUnwrappedProperty(Integer unwrappedProperty) {
12+
this.unwrappedProperty = unwrappedProperty;
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "OpenAPI definition",
5+
"version": "v0"
6+
},
7+
"servers": [
8+
{
9+
"url": "http://localhost",
10+
"description": "Generated server url"
11+
}
12+
],
13+
"paths": {
14+
"/api": {
15+
"get": {
16+
"tags": [
17+
"test-controller"
18+
],
19+
"operationId": "getRootModel",
20+
"responses": {
21+
"200": {
22+
"description": "OK",
23+
"content": {
24+
"*/*": {
25+
"schema": {
26+
"$ref": "#/components/schemas/RootModel"
27+
}
28+
}
29+
}
30+
}
31+
}
32+
}
33+
}
34+
},
35+
"components": {
36+
"schemas": {
37+
"RootModel": {
38+
"type": "object",
39+
"properties": {
40+
"rootProperty": {
41+
"type": "integer",
42+
"format": "int32"
43+
},
44+
"unwrappedProperty": {
45+
"type": "integer",
46+
"format": "int32"
47+
}
48+
}
49+
}
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)