|
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