Skip to content

Commit e444dee

Browse files
committed
Changes report: Regression where content type from swagger @RequestBody does not take precedence #3133
1 parent 007977e commit e444dee

File tree

5 files changed

+267
-1
lines changed

5 files changed

+267
-1
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,15 @@ public void setJsonViewAnnotationForRequestBody(JsonView jsonViewAnnotationForRe
470470
this.jsonViewAnnotationForRequestBody = jsonViewAnnotationForRequestBody;
471471
}
472472

473+
/**
474+
* Is with response body schema doc boolean.
475+
*
476+
* @return the boolean
477+
*/
478+
public boolean isWithResponseBodySchemaDoc() {
479+
return withResponseBodySchemaDoc;
480+
}
481+
473482
/**
474483
* Gets headers.
475484
*

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/RequestBodyService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,9 @@ private RequestBody buildRequestBody(io.swagger.v3.oas.annotations.parameters.Re
299299
Schema<?> schema = parameterBuilder.calculateSchema(components, parameterInfo, requestBodyInfo,
300300
methodAttributes.getJsonViewAnnotationForRequestBody());
301301
Map<String, Encoding> parameterEncoding = getParameterEncoding(parameterInfo);
302-
buildContent(requestBody, methodAttributes, schema, parameterEncoding);
302+
// If a content type is explicitly stated with a @RequestBody annotation, yield to that content type
303+
if (!methodAttributes.isWithResponseBodySchemaDoc())
304+
buildContent(requestBody, methodAttributes, schema, parameterEncoding);
303305

304306
// Add requestBody javadoc
305307
if (StringUtils.isBlank(requestBody.getDescription()) && parameterBuilder.getJavadocProvider() != null
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * *
7+
* * * * * * Copyright 2019-2025 the original author or authors.
8+
* * * * * *
9+
* * * * * * Licensed under the Apache License, Version 2.0 (the "License");
10+
* * * * * * you may not use this file except in compliance with the License.
11+
* * * * * * You may obtain a copy of the License at
12+
* * * * * *
13+
* * * * * * https://www.apache.org/licenses/LICENSE-2.0
14+
* * * * * *
15+
* * * * * * Unless required by applicable law or agreed to in writing, software
16+
* * * * * * distributed under the License is distributed on an "AS IS" BASIS,
17+
* * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* * * * * * See the License for the specific language governing permissions and
19+
* * * * * * limitations under the License.
20+
* * * * *
21+
* * * *
22+
* * *
23+
* *
24+
*
25+
*/
26+
27+
package test.org.springdoc.api.v30.app244;
28+
29+
import io.swagger.v3.oas.annotations.Operation;
30+
import io.swagger.v3.oas.annotations.media.Content;
31+
import io.swagger.v3.oas.annotations.media.Schema;
32+
import io.swagger.v3.oas.annotations.parameters.RequestBody;
33+
import org.springdoc.core.annotations.ParameterObject;
34+
35+
import org.springframework.http.MediaType;
36+
import org.springframework.web.bind.annotation.ModelAttribute;
37+
import org.springframework.web.bind.annotation.PostMapping;
38+
import org.springframework.web.bind.annotation.RestController;
39+
40+
@RestController
41+
public class HelloController {
42+
43+
public record Greeting(String hi, String bye) {
44+
}
45+
46+
@PostMapping(value = "v1/greet", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
47+
public void endpoint(@RequestBody @ModelAttribute Greeting greeting) {
48+
49+
}
50+
51+
@PostMapping(value = "v2/greet")
52+
public void endpoint2(@ParameterObject @ModelAttribute Greeting greeting) {
53+
54+
}
55+
56+
@PostMapping(value = "v3/greet")
57+
@RequestBody(
58+
content = @Content(
59+
mediaType = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
60+
schema = @Schema(implementation = Greeting.class)
61+
))
62+
public void endpoint3(Greeting greeting) {
63+
64+
}
65+
66+
@PostMapping(value = "v4/greet")
67+
public void endpoint4(
68+
@RequestBody(content = @Content(
69+
mediaType = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
70+
schema = @Schema(implementation = Greeting.class)))
71+
@ModelAttribute Greeting greeting) {
72+
73+
}
74+
75+
@PostMapping(value = "v5/greet")
76+
@Operation(
77+
requestBody = @RequestBody(content = @Content(
78+
mediaType = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
79+
schema = @Schema(implementation = Greeting.class))
80+
))
81+
public void endpoint5(@ModelAttribute Greeting greeting) {
82+
83+
}
84+
85+
}
86+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * * Copyright 2025 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.app244;
26+
27+
import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
28+
29+
import org.springframework.boot.autoconfigure.SpringBootApplication;
30+
31+
public class SpringDocApp244Test extends AbstractSpringDocV30Test {
32+
33+
@SpringBootApplication
34+
static class SpringDocTestApp {}
35+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
{
2+
"openapi" : "3.0.1",
3+
"info" : {
4+
"title" : "OpenAPI definition",
5+
"version" : "v0"
6+
},
7+
"servers" : [ {
8+
"url" : "http://localhost",
9+
"description" : "Generated server url"
10+
} ],
11+
"paths" : {
12+
"/v5/greet" : {
13+
"post" : {
14+
"tags" : [ "hello-controller" ],
15+
"operationId" : "endpoint5",
16+
"requestBody" : {
17+
"content" : {
18+
"application/x-www-form-urlencoded" : {
19+
"schema" : {
20+
"$ref" : "#/components/schemas/Greeting"
21+
}
22+
}
23+
}
24+
},
25+
"responses" : {
26+
"200" : {
27+
"description" : "OK"
28+
}
29+
}
30+
}
31+
},
32+
"/v4/greet" : {
33+
"post" : {
34+
"tags" : [ "hello-controller" ],
35+
"operationId" : "endpoint4",
36+
"requestBody" : {
37+
"content" : {
38+
"application/x-www-form-urlencoded" : {
39+
"schema" : {
40+
"$ref" : "#/components/schemas/Greeting"
41+
}
42+
}
43+
}
44+
},
45+
"responses" : {
46+
"200" : {
47+
"description" : "OK"
48+
}
49+
}
50+
}
51+
},
52+
"/v3/greet" : {
53+
"post" : {
54+
"tags" : [ "hello-controller" ],
55+
"operationId" : "endpoint3",
56+
"requestBody" : {
57+
"content" : {
58+
"application/x-www-form-urlencoded" : {
59+
"schema" : {
60+
"$ref" : "#/components/schemas/Greeting"
61+
}
62+
}
63+
}
64+
},
65+
"responses" : {
66+
"200" : {
67+
"description" : "OK"
68+
}
69+
}
70+
}
71+
},
72+
"/v2/greet" : {
73+
"post" : {
74+
"tags" : [ "hello-controller" ],
75+
"operationId" : "endpoint2",
76+
"parameters" : [ {
77+
"name" : "hi",
78+
"in" : "query",
79+
"required" : false,
80+
"schema" : {
81+
"type" : "string"
82+
}
83+
}, {
84+
"name" : "bye",
85+
"in" : "query",
86+
"required" : false,
87+
"schema" : {
88+
"type" : "string"
89+
}
90+
} ],
91+
"responses" : {
92+
"200" : {
93+
"description" : "OK"
94+
}
95+
}
96+
}
97+
},
98+
"/v1/greet" : {
99+
"post" : {
100+
"tags" : [ "hello-controller" ],
101+
"operationId" : "endpoint",
102+
"requestBody" : {
103+
"content" : {
104+
"application/x-www-form-urlencoded" : {
105+
"schema" : {
106+
"$ref" : "#/components/schemas/Greeting"
107+
}
108+
}
109+
}
110+
},
111+
"responses" : {
112+
"200" : {
113+
"description" : "OK"
114+
}
115+
}
116+
}
117+
}
118+
},
119+
"components" : {
120+
"schemas" : {
121+
"Greeting" : {
122+
"type" : "object",
123+
"properties" : {
124+
"hi" : {
125+
"type" : "string"
126+
},
127+
"bye" : {
128+
"type" : "string"
129+
}
130+
}
131+
}
132+
}
133+
}
134+
}

0 commit comments

Comments
 (0)