Validation of POJO with enum field POJO 枚举字段的验证

huangapple go评论82阅读模式
英文:

Validation of POJO with enum field

问题

我正在使用Spring和Spring验证来处理POJO。

在POJO内部,我有一些字段,它们的值将映射到特定的**ENUM**类。

如下面的代码所示,我有一个名为**CardType ENUM**的cardType字段。

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;

@Data
@SuperBuilder(toBuilder = true)
@RequiredArgsConstructor
@EqualsAndHashCode
class SamplePOJO {

    @NotNull
    private CardType cardType;

    @Length(max = 20)
    private String name;

    @Max(10)
    private int number;
}

public enum CardType {
    VISA, MASTER;
}

对于name和number,我可以使用**@Max和@Length来进行验证。如何为cardType应用验证,以确保它属于所述enum**呢?

我在cardType字段上添加了**@NotNull**注解,这将确保cardType的值不为空,并且必须是CardType枚举中的一个值。

如果以后需要检查**List**类型的值,您可以考虑使用自定义验证注解和Validator来实现更复杂的验证逻辑。

英文:

I am working with spring and spring validations for POJO.

Inside of POJO i have some of fields whose values will mapped to particular ENUM class.

As mentioned in below code, i have cardType field as CardType ENUM.

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.Max;

@Data
@SuperBuilder(toBuilder = true)
@RequiredArgsConstructor
@EqualsAndHashCode
class SamplePOJO {

    private String cardType;

    @Length(max = 20)
    private String name;

    @Max(10)
    private int number
}

public enum CardType {
VISA, MASTER;
}

For name and number i am able to do with @Max and @Length.
How can i apply validation for cardType that will belongs to mentioned enum.
Also in future, it may possible that i need to check with List of values as well.
So if anyone can guide me.

答案1

得分: 5

以下是翻译好的部分:

自定义注解用于枚举验证的一种方法。并在字段上使用它。

@EnumNamePattern
private CardType cardType;

自定义注解:

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = EnumNamePatternValidator.class)
public @interface EnumNamePattern {
    String message() default "invalid";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

自定义注解验证器:

public class EnumNamePatternValidator implements ConstraintValidator<EnumNamePattern, String> {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) return true; 
        return Arrays.stream(CardType.values()).anyMatch(e -> e.name().equals(value));
    }
}
英文:

A way is to write a custom annotation for enum validation. And use it on the field

@EnumNamePattern
private CardType cardType;

Custom Annotation

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = EnumNamePatternValidator.class)
public @interface EnumNamePattern {
    String message() default &quot;invalid&quot;;
    Class&lt;?&gt;[] groups() default {};
    Class&lt;? extends Payload&gt;[] payload() default {};
}

Custom annotation validator

public class EnumNamePatternValidator implements ConstraintValidator&lt;EnumNamePattern, String&gt; {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) return true; 
        return Arrays.stream(CardType.values()).anyMatch(e -&gt; e.name().equals(value));
    }
}

答案2

得分: 0

首先,您可以创建一个注解,用于检查字符串是否适用于特定的枚举类型。

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = ValueOfEnumValidator.class)
public @interface ValueOfEnum {
    Class<? extends Enum<?>> enumClass();
    String message() default "must be any of enum {enumClass}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

然后,您可以将此注解添加到一个字符串字段,并指定一个枚举类。

@ValueOfEnum(enumClass = CardType.class)
private String cardType;

注意:我在Baeldung网站上找到了这个示例,Validations for Enum Types。该页面上也有关于此的单元测试示例。

英文:

First you can create an annotation that checks if the String is valid for a specific enum.

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = ValueOfEnumValidator.class)
public @interface ValueOfEnum {
    Class&lt;? extends Enum&lt;?&gt;&gt; enumClass();
    String message() default &quot;must be any of enum {enumClass}&quot;;
    Class&lt;?&gt;[] groups() default {};
    Class&lt;? extends Payload&gt;[] payload() default {};
}

Then you can add this annotation a String field and specify an enum class.

@ValueOfEnum(enumClass = CardType.class)
private String cardType;

Note: I found this on Baeldung Validations for Enum Types. There are examples of unit tests for this on that page as well.

huangapple
  • 本文由 发表于 2020年7月29日 15:31:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63148494.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定