使用枚举值和注释进行Java字符串验证

时间:2011-06-09 14:37:51

标签: java enums annotations

我想使用注释针对一组值验证字符串。 我想要的基本上就是这个

@ValidateString(enumClass=com.co.enum)
String dataType;

int maxValue;
int minValue;
int precision;

@ValidateString(values={"String","Boolean", "Integer"})
String dataType;

int maxValue;
int minValue;
int precision;

我还想对其他变量进行一些验证,具体取决于dataType中设置的值

如果(的dataType = “字符串”)     maxValue,minValue,precision all应为null或零。

我想不出通过自定义注释实现这一目标的方法。  。  

有人请帮帮我

8 个答案:

答案 0 :(得分:22)

所以这里是使用Spring验证的代码,对我来说很有用。 完整代码如下。

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.NotNull;

@Documented
@Constraint(validatedBy = EnumValidatorImpl.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@NotNull(message = "Value cannot be null")
@ReportAsSingleViolation
public @interface EnumValidator {

  Class<? extends Enum<?>> enumClazz();

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

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

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

}

上述课程的实施:

import java.util.ArrayList;
import java.util.List;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, String> {

  List<String> valueList = null;

  @Override
  public boolean isValid(String value, ConstraintValidatorContext context) {
    if(!valueList.contains(value.toUpperCase())) {
      return false;
    }
    return true;
  }

  @Override
  public void initialize(EnumValidator constraintAnnotation) {
    valueList = new ArrayList<String>();
    Class<? extends Enum<?>> enumClass = constraintAnnotation.enumClazz();

    @SuppressWarnings("rawtypes")
    Enum[] enumValArr = enumClass.getEnumConstants();

    for(@SuppressWarnings("rawtypes")
    Enum enumVal : enumValArr) {
      valueList.add(enumVal.toString().toUpperCase());
    }

  }

}

上述注释的使用非常简单

 @JsonProperty("lead_id")
  @EnumValidator( enumClazz=DefaultEnum.class,message="This error is coming from the enum class", groups = {Group1.class })
  private String leadId;

答案 1 :(得分:21)

这就是我所做的。

注释

public @interface ValidateString {

    String[] acceptedValues();

    String message() default "{uk.dds.ideskos.validator.ValidateString.message}";

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

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

验证类

public class StringValidator implements ConstraintValidator<ValidateString, String>{

    private List<String> valueList;

    @Override
    public void initialize(ValidateString constraintAnnotation) {
        valueList = new ArrayList<String>();
        for(String val : constraintAnnotation.acceptedValues()) {
            valueList.add(val.toUpperCase());
        }
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if(!valueList.contains(value.toUpperCase())) {
            return false;
        }
        return true;
    }

}

我用它就像

@ValidateString(acceptedValues={"Integer", "String"}, message="Invalid dataType")
String dataType;

Long maxValue;
Long minValue;

现在我需要弄清楚如何实现条件检查 即。如果是String,则maxValue和minValue应为null或Zero ..

有什么想法吗?

答案 2 :(得分:8)

抛弃String表示,然后做一个真正的枚举。

public enum DataType {
   STRING,
   BOOLEAN,
   INTEGER;
}

这样您就可以避免对先前的String dataType变量进行字符串比较,以确定它是否在枚举中。顺便说一句,它也使得无法为成员变量dataType分配无效值,并且因为枚举可以保证在类加载器中是单例,所以它也节省了内存占用。

值得努力改变您的代码以使用枚举。但是,假设您不能,您至少可以更改注释以使用枚举。

@ValidateString(DataType.STRING) String dataType;

这样你的ValidateString注释至少可以从枚举中受益,即使代码的其余部分没有。

现在根本无法使用枚举,您可以设置静态公共整数,映射每个可接受的值。

public class DataType {
  public static final int STRING = 1;
  public static final int BOOLEAN = 2;
  ...
}

但是,如果对注释参数使用String,则我们没有类型检查系统,该系统扩展到该类型以指定仅允许特定值。换句话说,Java缺乏这样的能力:

public int<values=[1,3,5,7..9]> oddInt; 

如果您尝试分配

,则会抛出错误
 oddInt = 4;

为什么这很重要?因为如果它不适用于常规Java,那么它不能应用于常规Java类中实现的枚举。

答案 3 :(得分:0)

我处理了Rajeev Singla的响应https://stackoverflow.com/a/21070806/8923905,只是为了优化代码并允许String参数为null,如果在您的应用程序中该参数不是必需的,则可以为空:

1-删除界面上的@NotNull批注

2-有关实现,请参见下面的修改代码。

public class EnumValidatorImpl implements ConstraintValidator <EnumValidator,String> {

    private List<String> valueList = null;

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return null == value || valueList.contains(value.toUpperCase());
    }

    @Override
    public void initialize(EnumValidator constraintAnnotation) {
        valueList = new ArrayList<>();
        Class<? extends Enum<?>> enumClass = constraintAnnotation.enumClass();

        Enum[] enumValArr = enumClass.getEnumConstants();

        for(Enum enumVal : enumValArr) {
            valueList.add(enumVal.toString().toUpperCase());
        }

    }
}

答案 4 :(得分:0)

答案 5 :(得分:0)

使用Java 8 Stream API即兴创作

import static java.util.stream.Collectors.toList;
import static java.util.stream.Stream.of;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, String> 
{
  private List<String> valueList = null;
  @Override
  public boolean isValid(String value, ConstraintValidatorContext context) {
    return valueList.contains(value.toUpperCase());
  }
  @Override
  public void initialize(EnumValidator constraintAnnotation) {
    valueList = of(constraintAnnotation.enumClazz().getEnumConstants()).map(e->e.toString()).collect(toList());
  }
}

答案 6 :(得分:0)

我尝试过一次科特林:

import javax.validation.Constraint
import javax.validation.ConstraintValidator
import javax.validation.ConstraintValidatorContext
import javax.validation.ReportAsSingleViolation
import javax.validation.constraints.NotNull
import kotlin.reflect.KClass

@Constraint(validatedBy = [EnumValidatorImpl::class])
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
@NotNull(message = "Value cannot be null")
@ReportAsSingleViolation
annotation class EnumValidator(val enumClazz: KClass<*>, val message: String = "Value is not valid")

class EnumValidatorImpl(private var valueList: List<String>? = null) : ConstraintValidator<EnumValidator, String> {
    override fun isValid(value: String?, context: ConstraintValidatorContext?): Boolean =
            valueList?.contains(value?.toUpperCase()) ?: false

    override fun initialize(constraintAnnotation: EnumValidator) {
        valueList = constraintAnnotation.enumClazz.java.enumConstants.map { it.toString().toUpperCase() }
    }
}

答案 7 :(得分:-3)

您可以将@NotNull注释与您的注释结合使用。 要使用它,您需要在@Target( { ANNOTATION_TYPE })中添加ValidateString注释。

http://docs.jboss.org/hibernate/validator/4.0.1/reference/en/html/validator-customconstraints.html