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 的验证约束来验证对象。
你可以:
- 始终“手动”验证
hash
(没有 @NotEmpty
注释)
- 在调用
saveAndPublish
之前先调用supplier.setHash(messageDigester.digest(supplier));
并在saveAndPublish
的Supplier
参数中添加@Valid
注解
- 将验证器实例作为字段添加到您的服务中,并在要验证的供应商上手动调用它(当然,在设置哈希后
saveAndPublish
的情况下)
- 实现两种不同类型的
Supplier
,例如 AddSupplier
(未验证 hash
;由 saveAndPublish
使用)和 EditSupplier
(使用 hash
正在验证;由 persist
) 使用
(这可能是一个不完整的列表)
我目前正在为服务中的 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.
中绕过 BeanValidationConstraintViolationException
将由 Spring Validator
抛出,如果您“手动”调用 persist
,则不会使用它。如果从 Spring 上下文调用 persist
,@Valid
注释将告诉 Spring 根据 class 的验证约束来验证对象。
你可以:
- 始终“手动”验证
hash
(没有@NotEmpty
注释) - 在调用
saveAndPublish
之前先调用supplier.setHash(messageDigester.digest(supplier));
并在saveAndPublish
的 - 将验证器实例作为字段添加到您的服务中,并在要验证的供应商上手动调用它(当然,在设置哈希后
saveAndPublish
的情况下) - 实现两种不同类型的
Supplier
,例如AddSupplier
(未验证hash
;由saveAndPublish
使用)和EditSupplier
(使用hash
正在验证;由persist
) 使用
Supplier
参数中添加@Valid
注解
(这可能是一个不完整的列表)