我正在开发一个java spring mvc应用程序。我已经实现了一个自定义验证注释来验证一些字符串(例如)。这是我的注释机构:
@Documented
@Constraint(validatedBy = PhoneValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Phone {
String message() default "{validation.phone}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
这是我的PhoneValidator
课程:
public class PhoneValidator implements ConstraintValidator<Phone, String> {
@Override
public void initialize(Phone a) {
}
@Override
public boolean isValid(String phone, ConstraintValidatorContext cvc) {
//my logic for validating the phone
}
}
这是有效的,我可以将@Phone
放在模型上任何字段的顶部。但我的问题是开发人员可以将此注释放在“任何”模型字段之上,我不希望这个任何!实际上,我希望开发人员可以将此注释放在 String 字段上。无论如何这样做?
答案 0 :(得分:0)
目前,@Target
的数据类型没有编译时检查机制。但是,如果@Phone
注释放在除String
以外的数据类型之上,它将在运行时抛出异常(可能为ClassCastException
),因为遵循ConstraintValidator.isValid
方法严格要求一个String
电话。
@Override
public boolean isValid(String phone, ConstraintValidatorContext cvc) {
//my logic for validating the phone
}
答案 1 :(得分:0)
我已经制作了几个自定义验证器注释,希望它可以帮助你。
@Documented
@Constraint(validatedBy = EnumStringValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumString {
String message() default "{com.raycloud.supply.platform.validate.spec.EnumString.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<? extends Enum> enumClass();
}
public class EnumStringValidator implements ConstraintValidator<EnumString, CharSequence> {
private Class<? extends Enum> enumClass;
@Override
public void initialize(EnumString annotation) {
enumClass = annotation.enumClass();
}
@Override
public boolean isValid(CharSequence field, ConstraintValidatorContext ctx) {
if (field == null) {
return true;
}
int len = field.length();
if (len == 0) {
return false;
}
try {
Enum.valueOf(enumClass, field.toString());
} catch (RuntimeException re) {
return false;
}
return true;
}
-------------------------
@Documented
@Constraint(validatedBy = {
TrimmedValidatorForCharSequence.class,
TrimmedValidatorForIterable.class})
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Trimmed {
String message() default "{com.raycloud.supply.platform.validate.spec.Trimmed.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class TrimmedValidatorForCharSequence implements ConstraintValidator<Trimmed, CharSequence> {
@Override
public void initialize(Trimmed annotation) {
}
@Override
public boolean isValid(CharSequence field, ConstraintValidatorContext ctx) {
if (field == null) {
return true;
}
int len = field.length();
if (len == 0) {
return false;
}
if (Util.isWhiteSpace(field.charAt(0)) || Util.isWhiteSpace(field.charAt(len - 1))) {
return false;
}
return true;
}
public class EnumStringValidator implements ConstraintValidator<EnumString, CharSequence> {
private Class<? extends Enum> enumClass;
@Override
public void initialize(EnumString annotation) {
enumClass = annotation.enumClass();
}
@Override
public boolean isValid(CharSequence field, ConstraintValidatorContext ctx) {
if (field == null) {
return true;
}
int len = field.length();
if (len == 0) {
return false;
}
try {
Enum.valueOf(enumClass, field.toString());
} catch (RuntimeException re) {
return false;
}
return true;
}
-------------------------
@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = MethodVerifyValidator.class)
@Documented
public @interface MethodVerify {
/**
* validator class
*/
Class<?> verifyClass();
/**
* validator method name
*/
String methodName() default "verify";
/**
* method parameter types
*/
Class[] parameterTypes() default {};
String message() default "{com.raycloud.amazon.validate.MethodVerify.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@interface methods {
MethodVerify[] value();
}
}
public class MethodVerifyValidator
implements ConstraintValidator<MethodVerify, Object> {
private Method method;
@Override
public void initialize(final MethodVerify annotation) {
String name = annotation.methodName();
Class[] types = annotation.parameterTypes();
method = Util.findMethod(annotation.verifyClass(), name, types);
if (method == null) {
throw new IllegalStateException("none method found!");
}
Util.makeAccessible(method);
}
@Override
public boolean isValid(final Object value, final ConstraintValidatorContext ctx) {
//if(value == null)//value != null
try {
method.invoke(value);
} catch (Exception re) {
return false;
}
return true;
}
}