Проверка общего унаследованного объекта JSR-303 - PullRequest
0 голосов
/ 13 февраля 2019

предположим, что у нас есть такая структура:

public class User {
   @NotNull(message = "not available")
   private String phoneNumber;
   //getter and setter
}

public class CEO extends User{}

public class TechManager extends User{}

public class Company {
   @Valid
   private CEO ceo;

   @Valid
   private TechManager techManager;
   //getters and setters
}

В приведенном выше примере phoneNumber является общим объектом как для CEO, так и для TechManager.

Как проверить это так, чтобы у генерального директора был дополнительный, а у TechManager - обязательный phoneNumber?

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Согласно спецификации Bean Validation 1.0 и Bean Validation 2.0 Specification вы можете использовать группы проверки.

Вы можете создать свою собственную иерархию групп.Например, одна группа на каждое поле и сбор одной для роли:

Сначала объявите группы, для которых вы хотите настроить проверку.

// Define group for which phoneNumber will be mandatory
interface PhoneNumberIsMandatory {}

// Define group for which Email will be mandatory
interface EmailIsMandatory {}

// Define a TechManagerValidation group with includes PhoneNumberIsMandatory and EmailIsMandatory groups
interface TechManagerValidation extends PhoneNumberIsMandatory, EmailIsMandatory {}

Давайте подготовим объявление родительского класса.Вы можете объявить одно или несколько полей с одной группой.Также вы можете объявить одну или несколько групп для одного поля.Или вообще не объявляет группу.

class User {

    @NotNull(message = "Name nust be set")
    public String name;

    @NotNull(groups = {PhoneNumberIsMandatory.class}, message = "Phone number must be set")
    public String phoneNumber;

    @Email
    @NotNull(groups = {EmailIsMandatory.class}, message = "Primary email must be set")
    String primaryEmail;

    @Email
    @NotNull(groups = {EmailIsMandatory.class}, message = "Secondary email must be not null")
    String secondaryEmail;
}

Переопределите группу проверки по умолчанию с аннотацией @GroupSequence.

@GroupSequence({TechManager.class, TechManagerValidation.class})
class TechManager extends User {

}

Теперь вы можете определить класс компании и проверить, как работает проверка

class CEO extends User {

}

class Company {

    @Valid
    public CEO ceo;

    @Valid
    public TechManager techManager;
}

public class DemoApplication {

    public static void main(String[] args) {

        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        Company company = new Company();
        company.ceo = new CEO();
        company.techManager = new TechManager();
        System.out.println("Company: " + validator.validate(company));
    }
}

Обратите внимание, что ограничения группы Default проверяются первыми, и в случае сбоя любого из них TechManagerValidation будет пропущено.При необходимости мы можем получить все ограничения, определив группу для всех полей класса User:

interface NameIsMandatory {}

interface PhoneNumberIsMandatory {}

interface EmailIsMandatory {}

interface TechManagerValidation extends NameIsMandatory, PhoneNumberIsMandatory, EmailIsMandatory {}

interface CeoValidation extends NameIsMandatory {}

class User {

    @NotNull(groups = {NameIsMandatory.class}, message = "Name nust be set")
    public String name;

    @NotNull(groups = {PhoneNumberIsMandatory.class}, message = "Phone number must be set")
    public String phoneNumber;

    @Email
    @NotNull(groups = {EmailIsMandatory.class}, message = "Primary email must be set")
    String primaryEmail;

    @Email
    @NotNull(groups = {EmailIsMandatory.class}, message = "Secondary email must be not null")
    String secondaryEmail;
}

@GroupSequence({TechManager.class, TechManagerValidation.class})
class TechManager extends User {

}

@GroupSequence({CEO.class, CeoValidation.class})
class CEO extends User {

}

class Company {

    @Valid
    public CEO ceo;

    @Valid
    public TechManager techManager;
}

public class DemoApplication {

    public static void main(String[] args) {

        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        Company company = new Company();
        company.ceo = new CEO();
        company.techManager = new TechManager();
        System.out.println("Company: " + validator.validate(company));
    }
}

Существует другой способ, но, на мой взгляд, он нарушает инкапсуляцию.Вы можете удалить группы NameIsMandatory, PhoneIsMandatory и EmailIsMandatory и определить ограничения класса User следующим образом:

class User {

    @NotNull(groups = {TechManagerValidation.class, CeoValidation.class}, message = "Name nust be set")
    public String name;

    @NotNull(groups = {TechManagerValidation.class}, message = "Phone number must be set")
    public String phoneNumber;

    @Email
    @NotNull(groups = {TechManagerValidation.class}, message = "Primary email must be set")
    String primaryEmail;

    @Email
    @NotNull(groups = {TechManagerValidation.class}, message = "Secondary email must be not null")
    String secondaryEmail;
}
0 голосов
/ 13 февраля 2019

Вы можете скрыть поле private String phoneNumber в подклассах и определить аннотации проверки так, как они вам нужны для каждого подкласса.В этом случае геттер и сеттер должны быть перезаписаны.

...