我想使用注释针对一组值验证字符串。 我想要的基本上就是这个
@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或零。
我想不出通过自定义注释实现这一目标的方法。 。
有人请帮帮我
答案 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)
这里是带有动态错误消息功能的详细示例 通过Hibernate Documentation
答案 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