根据其他字段 javax.validation 的条件进行选项的字段验证

2024-04-20

如果存在另一个字段,我需要执行字段验证(它可以是值之一)。

import javax.validation.*;

class Person {

    @NotBlank
    private String name;

    private Long groupId;

    @Valid // if group id is not null, select one from available.
    private String specialization;

    // getters, setters.
}

class PersonValidaionLogic {

    @Autowired
    private SpecializationService specializationService;

    public void validatePerson(final Person person) {
        Long groupId = person.getGroupId();
        if (groupId != null) {
            Set<String> availableSpecializations = specializationService.getByGroupId(groupId);
            if (!availableSpecializations.contains(specialization)) {
                addValidationError("specialization is not valid");
            }
        }
    }
}

有一个关于如何验证类中的多个字段具有相互条件的很好的答案 https://stackoverflow.com/questions/1972933/cross-field-validation-with-hibernate-validator-jsr-303.

我该如何通过specializationService and groupId给验证器。


欢迎分享您的解决方案或想法!这就是我解决这个问题的方法。

我使用了问题中链接中的想法,但以更简单的方式。

首先我解决了一个问题如何将 Spring 组件或服务传递给验证器 https://stackoverflow.com/questions/55635585/javax-validator-with-spring-component。我使用了一个包含服务静态引用的组件。

其次,我按照链接中的描述验证了整个对象。

这是代码!

1)创建注释@PersonConstraint并穿上Person班级。 这可能有帮助https://www.baeldung.com/javax-validation-method-constraints https://www.baeldung.com/javax-validation-method-constraints

@Target({ TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = PersonValidator.class)
public @interface PersonConstraint {

    String message() default "Specialization is not valid";

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

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

    CaseMode value();
}

2) 保存对服务的静态引用的组件。

@Component // Spring component.
class ServiceHolderComponent {

    private static SpecializationService SPECIALIZATION_SERVICE;

    @Autowired
    public ServiceHolderComponent(final SpecializationService specializationService) {
        GROUP_SERVICE = Validate.notNull(groupService); //apache lib
    }

    public static SpecializationService getSpecializationService() {
        return SPECIALIZATION_SERVICE;
    }
}

3)和个人验证器

public class PersonValidator implements ConstraintValidator<PersonConstraint, Person> {

    private final SpecializationService specializationService;

    public UserDynamicEnumValidator() {
        this(ServiceHolderComponent.getSpecializationService());
    }

    public UserDynamicEnumValidator(final SpecializationService specializationService) {
        this.specializationService = specializationService;
    }

    @Override
    public boolean isValid(final Person person, final ConstraintValidatorContext context) {
        final Long groupId = person.getGroupId();
        if (groupId == null) {
            return true; // We consider it valid.
        }

        final String specialization = person.getSpecializat();
        if (StringUtils.isEmpty(specialization)) {
            return true; // We consider it valid.
        }

        // I changed the code of the service, so it returns a set of strings - projection query and collectors to set.
        final Set<String> availableSpecializationValuesByGroup = specializationService.findByValue(groupId);

        if (!availableSpecializationValuesByGroup.contains(specialization)) {
            // To display custom message
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("Specialization is not valid").addConstraintViolation();
            return false;
        }

        return true;
    }
}

要显示一个验证器中的自定义消息 https://docs.jboss.org/hibernate/validator/5.0/reference/en-US/html/validator-customconstraints.html#example-implementing-classlevel-constraint检查这个

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据其他字段 javax.validation 的条件进行选项的字段验证 的相关文章

随机推荐