springmvc服务端数据验证的自定义验证与扩展使用
前面讲了基本的使用,现在讲一下扩展使用,
例如在注册时需要实现注册登录名的唯一性验证,这时可如下 实现:
1.创建一个验证登录名的限制注解。
/**
* 验证登录名是否已被使用的限制注解
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=LoginNameOnlyValidator.class)
public @interface LoginNameOnly {
String message() default"登录名已被使用";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2.建立这个注解的验证执行类:
注意:@Autowired
private RegisterManager registerManager; 这是通过spring依赖注入,因为这里spring已经实现了对jsr-303的支持
/**
* 登录名是否已被使用的注解验证的执行类
*/
public class LoginNameOnlyValidator implements ConstraintValidator<LoginNameOnly, String> {
@Autowired
private RegisterManager registerManager;
@Override
public void initialize(LoginNameOnly arg0) {}
@Override
public boolean isValid(String loginName, ConstraintValidatorContext arg1) {
if(StringUtils.isBlank(loginName))
return true;
return registerManager.getloginNameIsUsed(loginName);
}
}
3.在验证模型中使用:
@LoginNameOnly
public String getLoginName() {
return this.loginName;
}
就这样就可以了。不过如果是在修改过程中,则这个方法不能满足,恐怕只能结合采用编程式验证了。
二,这里要说另一种情况:就是对允许空的字段的验证,在界面传过来的值为这样的“”空字符串时,就是界面没有输入,在后台接受值后为“”,这时如果直接加一些验证,会出现验证无法通过。实际需要此时不验证或验证通过。
如字符如果有输入,则长度应为2-10,但可以为空,
我的解决办法是:重写一下长度验证的限制注解及长度验证的验证执行类。
2.1 先写长度的限制注解类
@Documented
@Constraint(validatedBy={LengthBValidator.class})
@Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.ANNOTATION_TYPE, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface LengthB
{
public abstract int min();
public abstract int max();
public String message();
public Class<?>[] groups()default {};
public Class<? extends Payload>[] payload()default {};
@Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.ANNOTATION_TYPE, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public static @interface List
{
public abstract Length[] value();
}
}
2.2 再重写执行类,
public class LengthBValidator implements ConstraintValidator<LengthB, CharSequence>
{
private static final Log log = LoggerFactory.make();
private int min;
private int max;
public void initialize(LengthB parameters)
{
this.min = parameters.min();
this.max = parameters.max();
validateParameters();
}
public boolean isValid(CharSequence value, ConstraintValidatorContext constraintValidatorContext) {
if (value == null) {
return true;
}
int length = value.length();
if (length == 0) {
return true;
}
return (length >= this.min) && (length <= this.max);
}
private void validateParameters() {
if (this.min < 0) {
throw log.getMinCannotBeNegativeException();
}
if (this.max < 0) {
throw log.getMaxCannotBeNegativeException();
}
if (this.max < this.min)
throw log.getLengthCannotBeNegativeException();
}
}
实质上加了这两行代码:
if (length == 0) {
return true;
}就这样,为空字符串时,就能跳过验证了。
大家如果有更好的解决方式,希望能指教。