Validator对象校验工具

公冶森
2023-12-01

通常在dubbo或者http接口中,需要对上游服务的参数请求进行判空等一系列校验,与其去对多个字段进行 StringUtils.isNotBlank() 这种判空操作,不如在请求的request dto中使用注解针对某个字段进行校验。
推荐引入依赖

        <!-- hibernate validator-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.5.Final</version>
        </dependency>

使用方式
具体注解介绍 https://www.jianshu.com/p/67d3637493c7
一、针对dto中字段进行逐一设置

    @NotNull(message = "渠道id不能为空")
    @Size(min = 1, message = "渠道id数量不可为0")
    private List<String> channelId;

	Set<ConstraintViolation<DataStatisticsQueryDTO>> checkSet = validator.validate(queryDTO);
	if (CollectionUtils.isNotEmpty(checkSet)) {
		String errorMsg = StringUtils.joinWith(";", checkSet.stream().map(ConstraintViolation::getMessage).collect(toList()));
		return Result.fail("params_is_empty", errorMsg);
	}

二、校验几个参数中至少一个不为空
注解:

@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = AtLeastOneNotEmptyValidator.class)
@Documented
public @interface AtLeastOneNotEmpty {
    String message() default "{至少有一个属性不可为空}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    String[] fields();
}

实现

public class AtLeastOneNotEmptyValidator implements ConstraintValidator<AtLeastOneNotEmpty, Object> {

    private String[] fields;

    @Override
    public void initialize(AtLeastOneNotEmpty atLeastOneNotEmpty) {
        this.fields = atLeastOneNotEmpty.fields();
    }

    @Override
    public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
        if (object == null) {
            return true;
        }
        try {
            for (String fieldName : fields) {
                Object property = getField(object, fieldName);

                if (property != null && !"".equals(property)) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    private Object getField(Object object, String fieldName) throws IllegalAccessException {
        if (object == null) {
            return null;
        }
        Class clazz = object.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.getName().equals(fieldName)) {
                field.setAccessible(true);
                return field.get(object);
            }
        }
        return null;
    }
}

调用:

@AtLeastOneNotEmpty(fields = {"tenantId", "channelId", "namespace"}, message = "tenantId,channelId,namespace 不能同时为空")

 类似资料: