Skip to content

Jakarta annotations NotEmpty and NotBlank are not handled correctly for properties #3152

@dbarvitsky

Description

@dbarvitsky

First off, thank you very much for your continued effort in maintaining spring-doc!

The following minor defect popped up for us during the recent round of upgrades.

Consider the following Java type:

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;

@Valid
public record StringConstraintsJsr380(
    @NotEmpty
    String nonEmpty,
    @NotBlank
    String notBlank) {
}

and a controller that accepts it as a POST payload body:

@RestController
@RequestMapping("/v1/types")
@Validated
public class SomeController {
  @PostMapping("string/jsr380")
  void doStringConstraintsJsr380(@Valid @RequestBody StringConstraintsJsr380 payload) {
  }
...
}

Discovered schema for SpringConstraintsJsr380 is as follows:

{
...
  "components": {
    "schemas": {
      "StringConstraintsJsr380": {
        "type": "object",
        "properties": {
          "nonEmpty": {
            "type": "string"
          },
          "notBlank": {
            "type": "string"
          }
        },
        "required": [
          "nonEmpty",
          "notBlank"
        ]
      }
    }
  }
}

This schema permits values of nonEmpty = "" and nonBlank = " ", while Java validation does not permit these values.

Per Jakarta, validation API:

  • NotEmpty applied to CharacterSequence requires at least one character, hence the nonEmpty must have minLength: 1
  • NotBlank requires at least one non-whitespace character, which probably is best expressed with pattern: "[^\\s]+".

To Reproduce
Steps to reproduce the behavior:

  • spring-boot version 3.5.7
  • springdoc-openapi-starter-common 2.8.14
  • actual JSON - see above
  • expected JSON:
{
...
  "components": {
    "schemas": {
      "StringConstraintsJsr380": {
        "type": "object",
        "properties": {
          "nonEmpty": {
            "type": "string",
            "minLength": 1
          },
          "notBlank": {
            "type": "string",
            "pattern": "[^\\s]+" // Better options?
          }
        },
        "required": [
          "nonEmpty",
          "notBlank"
        ]
      }
    }
  }
}

Thank you in advance for looking into this!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions