|
46 | 46 | import io.swagger.v3.oas.models.Components;
|
47 | 47 | import io.swagger.v3.oas.models.OpenAPI;
|
48 | 48 | import io.swagger.v3.oas.models.Operation;
|
| 49 | +import io.swagger.v3.oas.models.media.Content; |
| 50 | +import io.swagger.v3.oas.models.media.MediaType; |
49 | 51 | import io.swagger.v3.oas.models.media.Schema;
|
50 | 52 | import io.swagger.v3.oas.models.parameters.Parameter;
|
| 53 | +import io.swagger.v3.oas.models.parameters.RequestBody; |
51 | 54 | import org.apache.commons.lang3.StringUtils;
|
52 | 55 | import org.springdoc.core.customizers.OperationCustomizer;
|
53 | 56 | import org.springdoc.core.customizers.ParameterCustomizer;
|
@@ -81,7 +84,7 @@ public abstract class AbstractRequestBuilder {
|
81 | 84 | private static final List<Class> PARAM_TYPES_TO_IGNORE = new ArrayList<>();
|
82 | 85 |
|
83 | 86 | // using string litterals to support both validation-api v1 and v2
|
84 |
| - private static final String[] ANNOTATIONS_FOR_REQUIRED = { NotNull.class.getName(), "javax.validation.constraints.NotBlank", "javax.validation.constraints.NotEmpty" }; |
| 87 | + private static final String[] ANNOTATIONS_FOR_REQUIRED = { NotNull.class.getName(), org.springframework.web.bind.annotation.RequestBody.class.getName(),"javax.validation.constraints.NotBlank", "javax.validation.constraints.NotEmpty" }; |
85 | 88 |
|
86 | 89 | private static final String POSITIVE_OR_ZERO = "javax.validation.constraints.PositiveOrZero";
|
87 | 90 |
|
@@ -183,6 +186,7 @@ else if (!RequestMethod.GET.equals(requestMethod)) {
|
183 | 186 | requestBodyInfo.setRequestBody(operation.getRequestBody());
|
184 | 187 | requestBodyBuilder.calculateRequestBodyInfo(components, handlerMethod, methodAttributes, i,
|
185 | 188 | parameterInfo, requestBodyInfo);
|
| 189 | + applyBeanValidatorAnnotations(requestBodyInfo.getRequestBody(), Arrays.asList(parameters[i].getAnnotations())); |
186 | 190 | }
|
187 | 191 | customiseParameter(parameter, parameterInfo, handlerMethod);
|
188 | 192 | }
|
@@ -349,54 +353,26 @@ private Parameter buildParam(String in, Components components, ParameterInfo par
|
349 | 353 |
|
350 | 354 | private void applyBeanValidatorAnnotations(final Parameter parameter, final List<Annotation> annotations) {
|
351 | 355 | Map<String, Annotation> annos = new HashMap<>();
|
352 |
| - if (annotations != null) { |
| 356 | + if (annotations != null) |
353 | 357 | annotations.forEach(annotation -> annos.put(annotation.annotationType().getName(), annotation));
|
354 |
| - } |
355 |
| - |
356 | 358 | boolean annotationExists = Arrays.stream(ANNOTATIONS_FOR_REQUIRED).anyMatch(annos::containsKey);
|
357 |
| - |
358 |
| - if (annotationExists) { |
| 359 | + if (annotationExists) |
359 | 360 | parameter.setRequired(true);
|
360 |
| - } |
361 |
| - |
362 | 361 | Schema<?> schema = parameter.getSchema();
|
| 362 | + applyValidationsToSchema(annos, schema); |
| 363 | + } |
363 | 364 |
|
364 |
| - if (annos.containsKey(Min.class.getName())) { |
365 |
| - Min min = (Min) annos.get(Min.class.getName()); |
366 |
| - schema.setMinimum(BigDecimal.valueOf(min.value())); |
367 |
| - } |
368 |
| - if (annos.containsKey(Max.class.getName())) { |
369 |
| - Max max = (Max) annos.get(Max.class.getName()); |
370 |
| - schema.setMaximum(BigDecimal.valueOf(max.value())); |
371 |
| - } |
372 |
| - calculateSize(annos, schema); |
373 |
| - if (annos.containsKey(DecimalMin.class.getName())) { |
374 |
| - DecimalMin min = (DecimalMin) annos.get(DecimalMin.class.getName()); |
375 |
| - if (min.inclusive()) { |
376 |
| - schema.setMinimum(BigDecimal.valueOf(Double.parseDouble(min.value()))); |
377 |
| - } |
378 |
| - else { |
379 |
| - schema.setExclusiveMinimum(!min.inclusive()); |
380 |
| - } |
381 |
| - } |
382 |
| - if (annos.containsKey(DecimalMax.class.getName())) { |
383 |
| - DecimalMax max = (DecimalMax) annos.get(DecimalMax.class.getName()); |
384 |
| - if (max.inclusive()) { |
385 |
| - schema.setMaximum(BigDecimal.valueOf(Double.parseDouble(max.value()))); |
386 |
| - } |
387 |
| - else { |
388 |
| - schema.setExclusiveMaximum(!max.inclusive()); |
389 |
| - } |
390 |
| - } |
391 |
| - if (annos.containsKey(POSITIVE_OR_ZERO)) { |
392 |
| - schema.setMinimum(BigDecimal.ZERO); |
393 |
| - } |
394 |
| - if (annos.containsKey(NEGATIVE_OR_ZERO)) { |
395 |
| - schema.setMaximum(BigDecimal.ZERO); |
396 |
| - } |
397 |
| - if (annos.containsKey(Pattern.class.getName())) { |
398 |
| - Pattern pattern = (Pattern) annos.get(Pattern.class.getName()); |
399 |
| - schema.setPattern(pattern.regexp()); |
| 365 | + private void applyBeanValidatorAnnotations(final RequestBody requestBody, final List<Annotation> annotations) { |
| 366 | + Map<String, Annotation> annos = new HashMap<>(); |
| 367 | + if (annotations != null) |
| 368 | + annotations.forEach(annotation -> annos.put(annotation.annotationType().getName(), annotation)); |
| 369 | + boolean annotationExists = Arrays.stream(ANNOTATIONS_FOR_REQUIRED).anyMatch(annos::containsKey); |
| 370 | + if (annotationExists) |
| 371 | + requestBody.setRequired(true); |
| 372 | + Content content = requestBody.getContent(); |
| 373 | + for (MediaType mediaType : content.values()) { |
| 374 | + Schema schema = mediaType.getSchema(); |
| 375 | + applyValidationsToSchema(annos, schema); |
400 | 376 | }
|
401 | 377 | }
|
402 | 378 |
|
@@ -451,6 +427,46 @@ private Map<String, io.swagger.v3.oas.annotations.Parameter> getApiParameters(Me
|
451 | 427 | return apiParametersMap;
|
452 | 428 | }
|
453 | 429 |
|
| 430 | + private void applyValidationsToSchema(Map<String, Annotation> annos, Schema<?> schema) { |
| 431 | + if (annos.containsKey(Min.class.getName())) { |
| 432 | + Min min = (Min) annos.get(Min.class.getName()); |
| 433 | + schema.setMinimum(BigDecimal.valueOf(min.value())); |
| 434 | + } |
| 435 | + if (annos.containsKey(Max.class.getName())) { |
| 436 | + Max max = (Max) annos.get(Max.class.getName()); |
| 437 | + schema.setMaximum(BigDecimal.valueOf(max.value())); |
| 438 | + } |
| 439 | + calculateSize(annos, schema); |
| 440 | + if (annos.containsKey(DecimalMin.class.getName())) { |
| 441 | + DecimalMin min = (DecimalMin) annos.get(DecimalMin.class.getName()); |
| 442 | + if (min.inclusive()) { |
| 443 | + schema.setMinimum(BigDecimal.valueOf(Double.parseDouble(min.value()))); |
| 444 | + } |
| 445 | + else { |
| 446 | + schema.setExclusiveMinimum(!min.inclusive()); |
| 447 | + } |
| 448 | + } |
| 449 | + if (annos.containsKey(DecimalMax.class.getName())) { |
| 450 | + DecimalMax max = (DecimalMax) annos.get(DecimalMax.class.getName()); |
| 451 | + if (max.inclusive()) { |
| 452 | + schema.setMaximum(BigDecimal.valueOf(Double.parseDouble(max.value()))); |
| 453 | + } |
| 454 | + else { |
| 455 | + schema.setExclusiveMaximum(!max.inclusive()); |
| 456 | + } |
| 457 | + } |
| 458 | + if (annos.containsKey(POSITIVE_OR_ZERO)) { |
| 459 | + schema.setMinimum(BigDecimal.ZERO); |
| 460 | + } |
| 461 | + if (annos.containsKey(NEGATIVE_OR_ZERO)) { |
| 462 | + schema.setMaximum(BigDecimal.ZERO); |
| 463 | + } |
| 464 | + if (annos.containsKey(Pattern.class.getName())) { |
| 465 | + Pattern pattern = (Pattern) annos.get(Pattern.class.getName()); |
| 466 | + schema.setPattern(pattern.regexp()); |
| 467 | + } |
| 468 | + } |
| 469 | + |
454 | 470 | public static void addRequestWrapperToIgnore(Class<?>... classes) {
|
455 | 471 | PARAM_TYPES_TO_IGNORE.addAll(Arrays.asList(classes));
|
456 | 472 | }
|
|
0 commit comments