Skip to content

Commit 9f1a5a0

Browse files
author
bnasslahsen
committed
Improve @parameter annotation support for header. Fixes springdoc#544.
1 parent a351fa4 commit 9f1a5a0

File tree

6 files changed

+155
-26
lines changed

6 files changed

+155
-26
lines changed

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

+16-19
Original file line numberDiff line numberDiff line change
@@ -172,22 +172,22 @@ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod,
172172
for (MethodParameter methodParameter : parameters) {
173173
// check if query param
174174
Parameter parameter = null;
175-
final String pName = methodParameter.getParameterName();
176175
io.swagger.v3.oas.annotations.Parameter parameterDoc = methodParameter.getParameterAnnotation(io.swagger.v3.oas.annotations.Parameter.class);
176+
final String pName = methodParameter.getParameterName();
177+
ParameterInfo parameterInfo = new ParameterInfo(pName, methodParameter);
178+
177179
if (parameterDoc == null)
178-
parameterDoc = parametersDocMap.get(pName);
180+
parameterDoc = parametersDocMap.get(parameterInfo.getpName());
179181
// use documentation as reference
180182
if (parameterDoc != null) {
181183
if (parameterDoc.hidden())
182184
continue;
183-
parameter = parameterBuilder.buildParameterFromDoc(parameterDoc, null,
184-
methodAttributes.getJsonViewAnnotation());
185+
parameter = parameterBuilder.buildParameterFromDoc(parameterDoc, null, methodAttributes.getJsonViewAnnotation());
186+
parameterInfo.setParameterModel(parameter);
185187
}
186188

187189
if (!isParamToIgnore(methodParameter)) {
188-
ParameterInfo parameterInfo = new ParameterInfo(pName, methodParameter, parameter);
189-
parameter = buildParams(parameterInfo, components, requestMethod,
190-
methodAttributes.getJsonViewAnnotation());
190+
parameter = buildParams(parameterInfo, components, requestMethod, methodAttributes.getJsonViewAnnotation());
191191
// Merge with the operation parameters
192192
parameter = parameterBuilder.mergeParameter(operationParameters, parameter);
193193
List<Annotation> parameterAnnotations = Arrays.asList(methodParameter.getParameterAnnotations());
@@ -279,34 +279,31 @@ private boolean isValidParameter(Parameter parameter) {
279279
private Parameter buildParams(ParameterInfo parameterInfo, Components components,
280280
RequestMethod requestMethod, JsonView jsonView) {
281281
MethodParameter methodParameter = parameterInfo.getMethodParameter();
282-
RequestHeader requestHeader = methodParameter.getParameterAnnotation(RequestHeader.class);
283-
RequestParam requestParam = methodParameter.getParameterAnnotation(RequestParam.class);
284-
PathVariable pathVar = methodParameter.getParameterAnnotation(PathVariable.class);
285-
CookieValue cookieValue = methodParameter.getParameterAnnotation(CookieValue.class);
282+
RequestHeader requestHeader = parameterInfo.getRequestHeader();
283+
RequestParam requestParam = parameterInfo.getRequestParam();
284+
PathVariable pathVar = parameterInfo.getPathVar();
285+
CookieValue cookieValue = parameterInfo.getCookieValue();
286+
286287
Parameter parameter = null;
287288
RequestInfo requestInfo;
288289

289290
if (requestHeader != null) {
290-
requestInfo = new RequestInfo(ParameterIn.HEADER.toString(), requestHeader.value(), requestHeader.required(),
291+
requestInfo = new RequestInfo(ParameterIn.HEADER.toString(), parameterInfo.getpName(), requestHeader.required(),
291292
requestHeader.defaultValue());
292293
parameter = buildParam(parameterInfo, components, requestInfo, jsonView);
293294

294295
}
295296
else if (requestParam != null && !parameterBuilder.isFile(parameterInfo.getMethodParameter())) {
296-
requestInfo = new RequestInfo(ParameterIn.QUERY.toString(), requestParam.value(), requestParam.required() && !methodParameter.isOptional(),
297+
requestInfo = new RequestInfo(ParameterIn.QUERY.toString(), parameterInfo.getpName(), requestParam.required() && !methodParameter.isOptional(),
297298
requestParam.defaultValue());
298299
parameter = buildParam(parameterInfo, components, requestInfo, jsonView);
299300
}
300301
else if (pathVar != null) {
301-
String pName = parameterInfo.getpName();
302-
String name = StringUtils.isBlank(pathVar.value()) ? pName : pathVar.value();
303-
parameterInfo.setpName(name);
304-
// check if PATH PARAM
305-
requestInfo = new RequestInfo(ParameterIn.PATH.toString(), pathVar.value(), !methodParameter.isOptional(), null);
302+
requestInfo = new RequestInfo(ParameterIn.PATH.toString(), parameterInfo.getpName(), !methodParameter.isOptional(), null);
306303
parameter = buildParam(parameterInfo, components, requestInfo, jsonView);
307304
}
308305
else if (cookieValue != null) {
309-
requestInfo = new RequestInfo(ParameterIn.COOKIE.toString(), cookieValue.value(), cookieValue.required(),
306+
requestInfo = new RequestInfo(ParameterIn.COOKIE.toString(), parameterInfo.getpName(), cookieValue.required(),
310307
cookieValue.defaultValue());
311308
parameter = buildParam(parameterInfo, components, requestInfo, jsonView);
312309
}

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

+48-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@
2020

2121
import java.lang.reflect.Parameter;
2222

23+
import org.apache.commons.lang3.StringUtils;
24+
2325
import org.springframework.core.MethodParameter;
26+
import org.springframework.web.bind.annotation.CookieValue;
27+
import org.springframework.web.bind.annotation.PathVariable;
28+
import org.springframework.web.bind.annotation.RequestHeader;
29+
import org.springframework.web.bind.annotation.RequestParam;
2430

2531
class ParameterInfo {
2632

@@ -30,12 +36,21 @@ class ParameterInfo {
3036

3137
private io.swagger.v3.oas.models.parameters.Parameter parameterModel;
3238

33-
public ParameterInfo(String pName, MethodParameter methodParameter,
34-
io.swagger.v3.oas.models.parameters.Parameter parameterModel) {
35-
super();
36-
this.pName = pName;
39+
private RequestHeader requestHeader;
40+
41+
private RequestParam requestParam;
42+
43+
private PathVariable pathVar;
44+
45+
private CookieValue cookieValue;
46+
47+
public ParameterInfo(String pName, MethodParameter methodParameter) {
3748
this.methodParameter = methodParameter;
38-
this.parameterModel = parameterModel;
49+
this.requestHeader = methodParameter.getParameterAnnotation(RequestHeader.class);
50+
this.requestParam = methodParameter.getParameterAnnotation(RequestParam.class);
51+
this.pathVar = methodParameter.getParameterAnnotation(PathVariable.class);
52+
this.cookieValue = methodParameter.getParameterAnnotation(CookieValue.class);
53+
this.pName = calculateName(pName, requestHeader, requestParam, pathVar, cookieValue);
3954
}
4055

4156
public String getpName() {
@@ -62,4 +77,32 @@ public void setParameterModel(io.swagger.v3.oas.models.parameters.Parameter para
6277
this.parameterModel = parameterModel;
6378
}
6479

80+
public RequestHeader getRequestHeader() {
81+
return requestHeader;
82+
}
83+
84+
public RequestParam getRequestParam() {
85+
return requestParam;
86+
}
87+
88+
public PathVariable getPathVar() {
89+
return pathVar;
90+
}
91+
92+
public CookieValue getCookieValue() {
93+
return cookieValue;
94+
}
95+
96+
private String calculateName(String pName, RequestHeader requestHeader, RequestParam requestParam, PathVariable pathVar, CookieValue cookieValue) {
97+
String name = pName;
98+
if (requestHeader != null && StringUtils.isNotEmpty(requestHeader.value()))
99+
name = requestHeader.value();
100+
else if (requestParam != null && StringUtils.isNotEmpty(requestParam.value()))
101+
name = requestParam.value();
102+
else if (pathVar != null && StringUtils.isNotEmpty(pathVar.value()))
103+
name = pathVar.value();
104+
else if (cookieValue != null && StringUtils.isNotEmpty(cookieValue.value()))
105+
name = cookieValue.value();
106+
return name;
107+
}
65108
}

springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/converters/Pageable.java

-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
import io.swagger.v3.oas.annotations.media.ArraySchema;
3030
import io.swagger.v3.oas.annotations.media.Schema;
3131

32-
import org.springframework.lang.Nullable;
33-
3432
@NotNull
3533
public class Pageable {
3634

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package test.org.springdoc.api.app106;
2+
3+
import java.time.Instant;
4+
5+
import io.swagger.v3.oas.annotations.Operation;
6+
import io.swagger.v3.oas.annotations.Parameter;
7+
import io.swagger.v3.oas.annotations.enums.ParameterIn;
8+
import io.swagger.v3.oas.annotations.media.Schema;
9+
10+
import org.springframework.http.HttpHeaders;
11+
import org.springframework.http.ResponseEntity;
12+
import org.springframework.web.bind.annotation.GetMapping;
13+
import org.springframework.web.bind.annotation.RequestHeader;
14+
import org.springframework.web.bind.annotation.RestController;
15+
16+
@RestController
17+
public class HelloController {
18+
19+
@Operation(summary = "find-articles")
20+
@GetMapping
21+
@Parameter(name = HttpHeaders.IF_MODIFIED_SINCE,
22+
description = "DateTime",
23+
in = ParameterIn.HEADER,
24+
schema = @Schema(type = "string", format = "date-time"),
25+
example = "2020-01-01T00:00:00.000Z"
26+
)
27+
public ResponseEntity<String> findArticles(@RequestHeader(value = HttpHeaders.IF_MODIFIED_SINCE, required = false) Instant modifiedSince) {
28+
return null;
29+
}
30+
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package test.org.springdoc.api.app106;
2+
3+
import test.org.springdoc.api.AbstractSpringDocTest;
4+
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
7+
public class SpringDocApp106Test extends AbstractSpringDocTest {
8+
@SpringBootApplication
9+
static class SpringDocTestApp {}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
"/": {
15+
"get": {
16+
"tags": [
17+
"hello-controller"
18+
],
19+
"summary": "find-articles",
20+
"operationId": "findArticles",
21+
"parameters": [
22+
{
23+
"name": "If-Modified-Since",
24+
"in": "header",
25+
"description": "DateTime",
26+
"required": false,
27+
"schema": {
28+
"type": "string",
29+
"format": "date-time"
30+
},
31+
"example": "2020-01-01T00:00:00.000Z"
32+
}
33+
],
34+
"responses": {
35+
"200": {
36+
"description": "default response",
37+
"content": {
38+
"*/*": {
39+
"schema": {
40+
"type": "string"
41+
}
42+
}
43+
}
44+
}
45+
}
46+
}
47+
}
48+
},
49+
"components": {}
50+
}

0 commit comments

Comments
 (0)