像必填、邮箱、最大值、不能重复、正则表达式等表单校验,我们前端都有做,其实后端也应该做的。利用@Valid等注解很容易实现,比如下面这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @PostMapping("save") public OtherCostVO save(@Valid @RequestBody OtherCostVO vo) { return StringUtils.isEmpty(vo.getId()) ? service.create(vo) : service.update(vo); }
public class OtherCostVO extends BillVO { @NotNull(message = "项目不能为空") private String projectId; private String projectName; @NotNull(message = "登记月份不能为空") private String periodId; private String period; @NotNull(message = "合计金额不能为空") private BigDecimal totalAmount; @SublistNotEmpty(message = "费用明细不能为空") @Valid private List<OtherCostDetailVO> costDetails; ... }
|
对于基本校验,spring都提供了相应注解,但有些特殊情况则需要我们自定义注解。比如我们系统中都是逻辑删除,这时我们如果要做子表非空校验,就不能再使用注解@NotEmpty了。那么如何创建自定义注解呢?
首先,创建注解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
@Constraint(validatedBy = SublistNotEmptyValidator.class) @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SublistNotEmpty {
String message() default "{org.hibernate.validator.constraints.NotEmpty.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {}; }
|
然后,创建注解解析器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public class SublistNotEmptyValidator implements ConstraintValidator<SublistNotEmpty, List<? extends LogicDeleteAware>> {
@Override public void initialize(SublistNotEmpty constraintAnnotation) {
}
@Override public boolean isValid(List<? extends LogicDeleteAware> value, ConstraintValidatorContext context) { return !CollectionUtils.isEmpty(value) && !value.stream().allMatch(LogicDeleteAware::isDeleted); } }
|
最后,只需要在要校验的字段上添加该注解就可以了,Spring会帮我们搞定的!(最上面的字段costDetails正是用到了该注解)
目前,除了子表非空@SublistNotEmpty注解,我还提供了子表不能重复注解@SublistNotRepeated。