今天我正在寻找一种方法来验证我必须返回到 FE 的 DTO。 我认为使用
@Valid
包中的 jakarta.validation
注释创建构造函数可能是一个好主意,因为文档说它可以在构造函数上使用。
因此,我使用示例 DTO 和 @AllArgsConstructor
上的 Lombok 注释以这种方式创建了我的测试:
@AllArgsConstructor(onConstructor_ = {@Valid})
public class TestValidatedDto {
@NotNull
private String value1;
@NotBlank
private String value2;
@Min(2)
@NotNull
private Integer number;
}
这是Lombok生成的DTO:
public class TestValidatedDto {
private @NotNull String value1;
private @NotBlank String value2;
private @Min(2L) @NotNull Integer number;
public @Valid TestValidatedDto(final String value1, final String value2, final Integer number) {
this.value1 = value1;
this.value2 = value2;
this.number = number;
}
}
正如我所期望的,我在构造函数上有
@Valid
注释。
现在我创建了一个测试,但结果不是我需要的。
@SpringBootTest
@Slf4j
class TestValidationAnnotationApplicationTests {
@Autowired
private Validator validator;
@Test
void testValidation1(){
TestValidatedDto testValidatedDto = new TestValidatedDto(null, " ", 1);
log.info("Created dto: [{}]",testValidatedDto);
Set<ConstraintViolation<TestValidatedDto>> violations = validator.validate(testValidatedDto);
violations.forEach(v -> {
log.info("VIOLATION: field [{}] - value: [{}] - message: [{}]", v.getPropertyPath(), v.getInvalidValue(), v.getMessage());
});
}
}
我不明白为什么构造函数上的
@Valid
不起作用。我知道构造函数不是一种方法,但文档说它可以用于验证构造函数的返回。
有谁知道这个注释的正确工作原理吗?
https://jakarta.ee/specifications/bean-validation/3.0/jakarta-bean-validation-spec-3.0.html
如果这不是正确的方法,有人可以解释一些最佳实践来验证 Dto 您需要以简单的方式返回控制器吗?
我在使用你的测试用例时验证成功,你可以尝试我的用例。
DTO:
@Data
@AllArgsConstructor(onConstructor_ = {@Valid})
public class SimpleDTO {
@NotNull(message = "corpId is null")
private String corpId;
@NotNull(message = "userId is null")
private String userId;
@NotNull(message = "deptCode is null")
private String deptCode;
@NotBlank
private String notBlank;
}
测试用例:
@SpringBootTest(classes = SimpleDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ValidTest {
@Test
void testValid() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
SimpleDTO allArg = new SimpleDTO(null, null, null, " ");
Set<ConstraintViolation<Object>> checkResult = validator.validate(allArg);
if (!CollectionUtils.isEmpty(checkResult)) {
List<String> resultMsg =checkResult.stream().map(ConstraintViolation::getMessage).collect(Collectors.toList());
throw new RuntimeException(JSON.toJSONString(resultMsg));
}
}
@Autowired
private Validator validator;
private static final Logger LOG = getLogger(ValidTest.class);
@Test
@DisplayName("display injected validator SpringBean")
void displayInjectValidatorBean(){
LOG.info(validator.getClass().getName());
SimpleDTO allArg = new SimpleDTO(null, null, null, " ");
Set<ConstraintViolation<Object>> checkResult = validator.validate(allArg);
if (!CollectionUtils.isEmpty(checkResult)) {
List<String> resultMsg = checkResult.stream().map(ConstraintViolation::getMessage).collect(Collectors.toList());
throw new RuntimeException(JSON.toJSONString(resultMsg));
}
}
}