|
26 | 26 |
|
27 | 27 | package org.springdoc.core.service;
|
28 | 28 |
|
| 29 | +import java.io.InputStream; |
| 30 | +import java.io.OutputStream; |
| 31 | +import java.io.Reader; |
| 32 | +import java.io.Writer; |
29 | 33 | import java.lang.annotation.Annotation;
|
30 | 34 | import java.lang.reflect.Method;
|
31 | 35 | import java.math.BigDecimal;
|
| 36 | +import java.security.Principal; |
| 37 | +import java.time.ZoneId; |
32 | 38 | import java.util.ArrayList;
|
33 | 39 | import java.util.Arrays;
|
34 | 40 | import java.util.Collection;
|
|
37 | 43 | import java.util.Iterator;
|
38 | 44 | import java.util.LinkedHashMap;
|
39 | 45 | import java.util.List;
|
| 46 | +import java.util.Locale; |
40 | 47 | import java.util.Map;
|
41 | 48 | import java.util.Map.Entry;
|
42 | 49 | import java.util.Objects;
|
43 | 50 | import java.util.Optional;
|
44 | 51 | import java.util.Set;
|
| 52 | +import java.util.TimeZone; |
45 | 53 | import java.util.stream.Collectors;
|
46 | 54 | import java.util.stream.Stream;
|
47 | 55 |
|
48 | 56 | import com.fasterxml.jackson.annotation.JsonView;
|
49 | 57 | import io.swagger.v3.core.util.PrimitiveType;
|
| 58 | +import io.swagger.v3.oas.annotations.Parameters; |
50 | 59 | import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
51 | 60 | import io.swagger.v3.oas.models.Components;
|
52 | 61 | import io.swagger.v3.oas.models.OpenAPI;
|
53 | 62 | import io.swagger.v3.oas.models.Operation;
|
54 |
| -import io.swagger.v3.oas.models.media.Content; |
55 |
| -import io.swagger.v3.oas.models.media.MediaType; |
56 | 63 | import io.swagger.v3.oas.models.media.Schema;
|
57 | 64 | import io.swagger.v3.oas.models.media.StringSchema;
|
58 | 65 | import io.swagger.v3.oas.models.parameters.Parameter;
|
|
78 | 85 | import org.springframework.core.MethodParameter;
|
79 | 86 | import org.springframework.core.annotation.AnnotatedElementUtils;
|
80 | 87 | import org.springframework.http.HttpMethod;
|
| 88 | +import org.springframework.ui.Model; |
| 89 | +import org.springframework.ui.ModelMap; |
81 | 90 | import org.springframework.util.CollectionUtils;
|
82 | 91 | import org.springframework.validation.BindingResult;
|
83 | 92 | import org.springframework.validation.Errors;
|
84 | 93 | import org.springframework.web.bind.annotation.PathVariable;
|
85 | 94 | import org.springframework.web.bind.annotation.RequestAttribute;
|
86 | 95 | import org.springframework.web.bind.annotation.RequestMethod;
|
87 | 96 | import org.springframework.web.bind.annotation.RequestParam;
|
| 97 | +import org.springframework.web.bind.annotation.RequestPart; |
88 | 98 | import org.springframework.web.bind.annotation.ValueConstants;
|
89 | 99 | import org.springframework.web.bind.support.SessionStatus;
|
90 | 100 | import org.springframework.web.context.request.NativeWebRequest;
|
|
97 | 107 | import static org.springdoc.core.utils.Constants.OPENAPI_ARRAY_TYPE;
|
98 | 108 | import static org.springdoc.core.utils.Constants.OPENAPI_STRING_TYPE;
|
99 | 109 | import static org.springdoc.core.utils.SpringDocUtils.getParameterAnnotations;
|
| 110 | +import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE; |
100 | 111 | import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE;
|
101 | 112 |
|
102 | 113 | /**
|
@@ -130,18 +141,18 @@ public abstract class AbstractRequestService {
|
130 | 141 | static {
|
131 | 142 | PARAM_TYPES_TO_IGNORE.add(WebRequest.class);
|
132 | 143 | PARAM_TYPES_TO_IGNORE.add(NativeWebRequest.class);
|
133 |
| - PARAM_TYPES_TO_IGNORE.add(java.security.Principal.class); |
| 144 | + PARAM_TYPES_TO_IGNORE.add(Principal.class); |
134 | 145 | PARAM_TYPES_TO_IGNORE.add(HttpMethod.class);
|
135 |
| - PARAM_TYPES_TO_IGNORE.add(java.util.Locale.class); |
136 |
| - PARAM_TYPES_TO_IGNORE.add(java.util.TimeZone.class); |
137 |
| - PARAM_TYPES_TO_IGNORE.add(java.io.InputStream.class); |
138 |
| - PARAM_TYPES_TO_IGNORE.add(java.time.ZoneId.class); |
139 |
| - PARAM_TYPES_TO_IGNORE.add(java.io.Reader.class); |
140 |
| - PARAM_TYPES_TO_IGNORE.add(java.io.OutputStream.class); |
141 |
| - PARAM_TYPES_TO_IGNORE.add(java.io.Writer.class); |
142 |
| - PARAM_TYPES_TO_IGNORE.add(java.util.Map.class); |
143 |
| - PARAM_TYPES_TO_IGNORE.add(org.springframework.ui.Model.class); |
144 |
| - PARAM_TYPES_TO_IGNORE.add(org.springframework.ui.ModelMap.class); |
| 146 | + PARAM_TYPES_TO_IGNORE.add(Locale.class); |
| 147 | + PARAM_TYPES_TO_IGNORE.add(TimeZone.class); |
| 148 | + PARAM_TYPES_TO_IGNORE.add(InputStream.class); |
| 149 | + PARAM_TYPES_TO_IGNORE.add(ZoneId.class); |
| 150 | + PARAM_TYPES_TO_IGNORE.add(Reader.class); |
| 151 | + PARAM_TYPES_TO_IGNORE.add(OutputStream.class); |
| 152 | + PARAM_TYPES_TO_IGNORE.add(Writer.class); |
| 153 | + PARAM_TYPES_TO_IGNORE.add(Map.class); |
| 154 | + PARAM_TYPES_TO_IGNORE.add(Model.class); |
| 155 | + PARAM_TYPES_TO_IGNORE.add(ModelMap.class); |
145 | 156 | PARAM_TYPES_TO_IGNORE.add(Errors.class);
|
146 | 157 | PARAM_TYPES_TO_IGNORE.add(BindingResult.class);
|
147 | 158 | PARAM_TYPES_TO_IGNORE.add(SessionStatus.class);
|
@@ -240,7 +251,7 @@ public static boolean isRequestTypeToIgnore(Class<?> rawClass) {
|
240 | 251 | */
|
241 | 252 | @SuppressWarnings("unchecked")
|
242 | 253 | public static Collection<Parameter> getHeaders(MethodAttributes methodAttributes, Map<ParameterId, Parameter> map) {
|
243 |
| - for (Map.Entry<String, String> entry : methodAttributes.getHeaders().entrySet()) { |
| 254 | + for (Entry<String, String> entry : methodAttributes.getHeaders().entrySet()) { |
244 | 255 | StringSchema schema = new StringSchema();
|
245 | 256 | if (StringUtils.isNotEmpty(entry.getValue()))
|
246 | 257 | schema.addEnumItem(entry.getValue());
|
@@ -291,7 +302,7 @@ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod,
|
291 | 302 |
|
292 | 303 | for (MethodParameter methodParameter : parameters) {
|
293 | 304 | // check if query param
|
294 |
| - Parameter parameter; |
| 305 | + Parameter parameter = null; |
295 | 306 | io.swagger.v3.oas.annotations.Parameter parameterDoc = AnnotatedElementUtils.findMergedAnnotation(
|
296 | 307 | AnnotatedElementUtils.forAnnotations(methodParameter.getParameterAnnotations()),
|
297 | 308 | io.swagger.v3.oas.annotations.Parameter.class);
|
@@ -321,12 +332,10 @@ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod,
|
321 | 332 |
|
322 | 333 | if (!isParamToIgnore(methodParameter)) {
|
323 | 334 | parameter = buildParams(parameterInfo, components, requestMethod, methodAttributes, openAPI.getOpenapi());
|
324 |
| - // Merge with the operation parameters |
325 |
| - parameter = GenericParameterService.mergeParameter(operationParameters, parameter); |
326 |
| - |
327 | 335 | List<Annotation> parameterAnnotations = List.of(getParameterAnnotations(methodParameter));
|
328 |
| - |
329 |
| - if (isValidParameter(parameter)) { |
| 336 | + if (isValidParameter(parameter,methodAttributes)) { |
| 337 | + // Merge with the operation parameters |
| 338 | + parameter = GenericParameterService.mergeParameter(operationParameters, parameter); |
330 | 339 | // Add param javadoc
|
331 | 340 | if (StringUtils.isBlank(parameter.getDescription()) && javadocProvider != null) {
|
332 | 341 | String paramJavadocDescription = parameterBuilder.getParamJavadoc(javadocProvider, methodParameter);
|
@@ -359,7 +368,7 @@ else if (!RequestMethod.GET.equals(requestMethod) || OpenApiVersion.OPENAPI_3_1.
|
359 | 368 | Parameter parameter = entry.getValue();
|
360 | 369 | if (!ParameterIn.PATH.toString().equals(parameter.getIn()) && !ParameterIn.HEADER.toString().equals(parameter.getIn())
|
361 | 370 | && !ParameterIn.COOKIE.toString().equals(parameter.getIn())) {
|
362 |
| - io.swagger.v3.oas.models.media.Schema<?> itemSchema = new io.swagger.v3.oas.models.media.Schema<>(); |
| 371 | + Schema<?> itemSchema = new Schema<>(); |
363 | 372 | itemSchema.setName(entry.getKey().getpName());
|
364 | 373 | itemSchema.setDescription(parameter.getDescription());
|
365 | 374 | itemSchema.setDeprecated(parameter.getDeprecated());
|
@@ -388,7 +397,7 @@ private LinkedHashMap<ParameterId, Parameter> getParameterLinkedHashMap(Componen
|
388 | 397 | throw new IllegalStateException(String.format("Duplicate key %s", u));
|
389 | 398 | }, LinkedHashMap::new));
|
390 | 399 |
|
391 |
| - for (Map.Entry<ParameterId, io.swagger.v3.oas.annotations.Parameter> entry : parametersDocMap.entrySet()) { |
| 400 | + for (Entry<ParameterId, io.swagger.v3.oas.annotations.Parameter> entry : parametersDocMap.entrySet()) { |
392 | 401 | ParameterId parameterId = entry.getKey();
|
393 | 402 | if (parameterId != null && !map.containsKey(parameterId) && !entry.getValue().hidden()) {
|
394 | 403 | Parameter parameter = parameterBuilder.buildParameterFromDoc(entry.getValue(), components, methodAttributes.getJsonViewAnnotation(), methodAttributes.getLocale());
|
@@ -512,11 +521,12 @@ private void setParams(Operation operation, List<Parameter> operationParameters,
|
512 | 521 | /**
|
513 | 522 | * Is valid parameter boolean.
|
514 | 523 | *
|
515 |
| - * @param parameter the parameter |
| 524 | + * @param parameter the parameter |
| 525 | + * @param methodAttributes the method attributes |
516 | 526 | * @return the boolean
|
517 | 527 | */
|
518 |
| - public boolean isValidParameter(Parameter parameter) { |
519 |
| - return parameter != null && (parameter.getName() != null || parameter.get$ref() != null); |
| 528 | + public boolean isValidParameter(Parameter parameter, MethodAttributes methodAttributes ) { |
| 529 | + return parameter != null && (parameter.getName() != null || parameter.get$ref() != null) && !(Arrays.asList(methodAttributes.getMethodConsumes()).contains(APPLICATION_FORM_URLENCODED_VALUE) && ParameterIn.QUERY.toString().equals(parameter.getIn())); |
520 | 530 | }
|
521 | 531 |
|
522 | 532 | /**
|
@@ -640,11 +650,6 @@ public void applyBeanValidatorAnnotations(final RequestBody requestBody, final L
|
640 | 650 |
|
641 | 651 | if (validationExists || (!isOptional && (springRequestBodyRequired || swaggerRequestBodyRequired)))
|
642 | 652 | requestBody.setRequired(true);
|
643 |
| - Content content = requestBody.getContent(); |
644 |
| - for (MediaType mediaType : content.values()) { |
645 |
| - Schema<?> schema = mediaType.getSchema(); |
646 |
| - applyValidationsToSchema(annos, schema); |
647 |
| - } |
648 | 653 | }
|
649 | 654 |
|
650 | 655 | /**
|
@@ -703,10 +708,10 @@ else if (OPENAPI_STRING_TYPE.equals(schema.getType())) {
|
703 | 708 | private Map<ParameterId, io.swagger.v3.oas.annotations.Parameter> getApiParameters(Method method) {
|
704 | 709 | Class<?> declaringClass = method.getDeclaringClass();
|
705 | 710 |
|
706 |
| - Set<io.swagger.v3.oas.annotations.Parameters> apiParametersDoc = AnnotatedElementUtils.findAllMergedAnnotations(method, io.swagger.v3.oas.annotations.Parameters.class); |
| 711 | + Set<Parameters> apiParametersDoc = AnnotatedElementUtils.findAllMergedAnnotations(method, Parameters.class); |
707 | 712 | LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParametersMap = apiParametersDoc.stream().flatMap(x -> Stream.of(x.value())).collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
|
708 | 713 |
|
709 |
| - Set<io.swagger.v3.oas.annotations.Parameters> apiParametersDocDeclaringClass = AnnotatedElementUtils.findAllMergedAnnotations(declaringClass, io.swagger.v3.oas.annotations.Parameters.class); |
| 714 | + Set<Parameters> apiParametersDocDeclaringClass = AnnotatedElementUtils.findAllMergedAnnotations(declaringClass, Parameters.class); |
710 | 715 | LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParametersDocDeclaringClassMap = apiParametersDocDeclaringClass.stream().flatMap(x -> Stream.of(x.value())).collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
|
711 | 716 | apiParametersMap.putAll(apiParametersDocDeclaringClassMap);
|
712 | 717 |
|
@@ -803,9 +808,9 @@ private boolean checkRequestBodyAnnotation(MethodParameter methodParameter) {
|
803 | 808 | * @return the boolean
|
804 | 809 | */
|
805 | 810 | private boolean checkFile(MethodParameter methodParameter) {
|
806 |
| - if (methodParameter.getParameterAnnotation(org.springframework.web.bind.annotation.RequestPart.class) != null) |
| 811 | + if (methodParameter.getParameterAnnotation(RequestPart.class) != null) |
807 | 812 | return true;
|
808 |
| - else if (methodParameter.getParameterAnnotation(org.springframework.web.bind.annotation.RequestParam.class) != null) { |
| 813 | + else if (methodParameter.getParameterAnnotation(RequestParam.class) != null) { |
809 | 814 | return isFile(methodParameter.getParameterType());
|
810 | 815 | }
|
811 | 816 | return false;
|
|
0 commit comments