Spring Boot Bean Validation 注解

SpringBoot Bean Validation annotation

我目前正在为服务中的 bean 验证编写一些@SpringBootTest。

@Data
@Document
public final class Supplier {

    @Id
    @NotEmpty
    private String supplierId;
    ...
    @NotEmpty
    private String hash;
    ....
}

测试

注释:

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.MOCK)

 @Test
    void testValidation() {
        Supplier invalidSupplier = SupplierTestDataUtil.createSupplier("1234");
        invalidSupplier.setSupplierId(null);

        //works
        assertThrows(ConstraintViolationException.class, () -> supplierService.publish(invalidSupplier));

        //works
        assertThrows(ConstraintViolationException.class, () -> supplierService.persist(invalidSupplier));
        
        //works not
        assertThrows(ConstraintViolationException.class, () -> supplierService.saveAndPublish(invalidSupplier));

        //works
        assertThrows(ConstraintViolationException.class, () -> supplierService.delete(invalidSupplier));
    }

服务:

@Transactional
public Supplier saveAndPublish(@NotNull Supplier supplier) {
    supplier.setHash(messageDigester.digest(supplier));
    Supplier persisted = persist(supplier);
    publish(supplier);
    return persisted;
}

@Transactional
public Supplier persist(@Valid @NotNull Supplier supplier) {
    return repository.save(supplier);
}

此时 saveAndFlush 的供应商必须无效,因为将在该方法中生成并设置所需的哈希值。 尽管如此,我的期望是 ConstraintViolationException 也会被抛出,因为我还调用了 persist 和 publish 方法并传递了那个无效的文档。

我的意思是你可以在同一个 class.

中绕过 BeanValidation

ConstraintViolationException 将由 Spring Validator 抛出,如果您“手动”调用 persist,则不会使用它。如果从 Spring 上下文调用 persist@Valid 注释将告诉 Spring 根据 class 的验证约束来验证对象。

你可以:

  1. 始终“手动”验证 hash(没有 @NotEmpty 注释)
  2. 在调用saveAndPublish之前先调用supplier.setHash(messageDigester.digest(supplier));并在saveAndPublish
  3. Supplier参数中添加@Valid注解
  4. 将验证器实例作为字段添加到您的服务中,并在要验证的供应商上手动调用它(当然,在设置哈希后 saveAndPublish 的情况下)
  5. 实现两种不同类型的 Supplier,例如 AddSupplier(未验证 hash;由 saveAndPublish 使用)和 EditSupplier(使用 hash 正在验证;由 persist)
  6. 使用

(这可能是一个不完整的列表)