Skip to content

Commit c4935b8

Browse files
committed
Null vendor extensions are excluded from Json/Yaml. Fixes #1525
1 parent 63d43a1 commit c4935b8

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/api/mixins/SortedOpenAPIMixin.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
import com.fasterxml.jackson.annotation.JsonAnyGetter;
2626
import com.fasterxml.jackson.annotation.JsonAnySetter;
27+
import com.fasterxml.jackson.annotation.JsonInclude;
28+
import com.fasterxml.jackson.annotation.JsonInclude.Include;
2729
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
2830
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
2931
import io.swagger.v3.core.jackson.PathsSerializer;
@@ -36,6 +38,7 @@
3638
public interface SortedOpenAPIMixin {
3739

3840
@JsonAnyGetter
41+
@JsonInclude(value = Include.ALWAYS)
3942
@JsonPropertyOrder(alphabetic = true)
4043
Map<String, Object> getExtensions();
4144

springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIService.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@
3939
import java.util.stream.Stream;
4040

4141
import com.fasterxml.jackson.core.JsonProcessingException;
42+
import com.fasterxml.jackson.databind.ObjectMapper;
4243
import io.swagger.v3.core.jackson.TypeNameResolver;
4344
import io.swagger.v3.core.util.AnnotationsUtils;
44-
import io.swagger.v3.core.util.Json;
4545
import io.swagger.v3.oas.annotations.Hidden;
4646
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
4747
import io.swagger.v3.oas.annotations.security.SecuritySchemes;
@@ -187,7 +187,7 @@ public class OpenAPIService implements ApplicationContextAware {
187187
* @param openApiBuilderCustomisers the open api builder customisers
188188
*/
189189
OpenAPIService(Optional<OpenAPI> openAPI, SecurityService securityParser,
190-
SpringDocConfigProperties springDocConfigProperties,PropertyResolverUtils propertyResolverUtils,
190+
SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils,
191191
Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers) {
192192
if (openAPI.isPresent()) {
193193
this.openAPI = openAPI.get();
@@ -198,7 +198,7 @@ public class OpenAPIService implements ApplicationContextAware {
198198
if (!CollectionUtils.isEmpty(this.openAPI.getServers()))
199199
this.isServersPresent = true;
200200
}
201-
this.propertyResolverUtils=propertyResolverUtils;
201+
this.propertyResolverUtils = propertyResolverUtils;
202202
this.securityParser = securityParser;
203203
this.springDocConfigProperties = springDocConfigProperties;
204204
this.openApiBuilderCustomisers = openApiBuilderCustomisers;
@@ -237,8 +237,8 @@ public void build(Locale locale) {
237237
}
238238
else {
239239
try {
240-
this.calculatedOpenAPI = Json.mapper()
241-
.readValue(Json.mapper().writeValueAsString(openAPI), OpenAPI.class);
240+
ObjectMapper objectMapper = new ObjectMapper();
241+
this.calculatedOpenAPI = objectMapper.readValue(objectMapper.writeValueAsString(openAPI), OpenAPI.class );
242242
}
243243
catch (JsonProcessingException e) {
244244
LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage());
@@ -336,10 +336,9 @@ public Operation buildTags(HandlerMethod handlerMethod, Operation operation, Ope
336336
}
337337

338338
if (!CollectionUtils.isEmpty(tagsStr)) {
339-
if(CollectionUtils.isEmpty(operation.getTags()))
339+
if (CollectionUtils.isEmpty(operation.getTags()))
340340
operation.setTags(new ArrayList<>(tagsStr));
341-
else
342-
{
341+
else {
343342
Set<String> operationTagsSet = new HashSet<>(operation.getTags());
344343
operationTagsSet.addAll(tagsStr);
345344
operation.getTags().clear();

springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app138/SpringDocApp138Test.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,18 @@
2222
*/
2323
package test.org.springdoc.api.app138;
2424

25+
import java.util.HashMap;
26+
import java.util.LinkedHashMap;
27+
import java.util.Map;
28+
29+
import io.swagger.v3.oas.models.OpenAPI;
2530
import org.junit.jupiter.api.Assertions;
2631
import org.junit.jupiter.api.Test;
2732
import org.springdoc.core.Constants;
2833
import test.org.springdoc.api.AbstractSpringDocTest;
2934

3035
import org.springframework.boot.autoconfigure.SpringBootApplication;
36+
import org.springframework.context.annotation.Bean;
3137
import org.springframework.test.context.TestPropertySource;
3238
import org.springframework.test.web.servlet.MvcResult;
3339
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@@ -44,8 +50,24 @@
4450
public class SpringDocApp138Test extends AbstractSpringDocTest {
4551

4652
@SpringBootApplication
47-
static class SpringDocTestApp {}
53+
static class SpringDocTestApp {
54+
@Bean
55+
public OpenAPI api() {
56+
return new OpenAPI()
57+
.extensions(apiExtensions());
58+
}
59+
}
60+
61+
private static Map<String, Object> apiExtensions() {
62+
Map extensions = new HashMap<String, Object>();
4863

64+
Map linkedMap = new LinkedHashMap<String, String>();
65+
linkedMap.put("property1", "value1");
66+
linkedMap.put("property2", null);
67+
68+
extensions.put("x-my-vendor-extensions", linkedMap);
69+
return extensions;
70+
}
4971
@Test
5072
public void testApp() throws Exception {
5173
MvcResult mockMvcResult = mockMvc.perform(MockMvcRequestBuilders.get(Constants.DEFAULT_API_DOCS_URL)).andExpect(status().isOk())
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://localhost","description":"Generated server url"}],"paths":{"/testA":{"get":{"tags":["hello-controller"],"operationId":"testA","parameters":[{"name":"hello","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/testB":{"get":{"tags":["hello-controller"],"operationId":"testB","parameters":[{"name":"hello","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}}},"components":{}}
1+
{"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://localhost","description":"Generated server url"}],"paths":{"/testA":{"get":{"operationId":"testA","parameters":[{"in":"query","name":"hello","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}},"tags":["hello-controller"]}},"/testB":{"get":{"operationId":"testB","parameters":[{"in":"query","name":"hello","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}},"tags":["hello-controller"]}}},"components":{},"x-my-vendor-extensions":{"property1":"value1","property2":null}}

0 commit comments

Comments
 (0)