使用POJO播放框架验证绑定无效输入值

时间:2013-07-17 09:20:54

标签: validation playframework-1.x pojo

我有一个模型TestModel.java,它包含一个声明如下

的字段
@Required
@IntegerAnnotation
@Column (length = 4, nullable = false)
public Integer sort;

对于Play的默认验证注释不支持整数检查,所以我创建了一个注释验证,用于检查输入值是否为整数。

IntegerAnnotation.java:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Constraint(checkWith = IntegerCheck.class)
public @interface IntegerAnnotation {
    String message() default IntegerCheck.message;}
}

并且此注释引用IntegerCheck.java

的实现
public class IntegerCheck extends AbstractAnnotationCheck<IntegerAnnotation>{

final static String message = "validation.integer";

@Override
public boolean isSatisfied(Object validatedObject, Object value, OValContext context, Validator validator) throws OValException {
    // TODO Auto-generated method stub

    if(value == null) return false;
    return isInteger(value.toString());
}

private static boolean isInteger(String s) {
    return isInteger(s,10);
}

private static boolean isInteger(String s, int radix) {
    if(s.isEmpty()) return false;
    for(int i = 0; i < s.length(); i++) {
        if(i == 0 && s.charAt(i) == '-') {
            if(s.length() == 1) return false;
            else continue;
        }
        if(Character.digit(s.charAt(i), radix) < 0) return false;
    }
    return true;
}
}

控制器中有两个动作用于创建或更新TestModel,方法创建和方法更新。

public static void create(@Valid TestModel testModel){
    if(validation.hasErrors()) {
        params.flash();
        validation.keep();
        blank();
    }
}

public static void update(@Valid TestModel testModel) {

    if(validation.hasErrors()) {
        params.flash();
        validation.keep();
    }
    else{
        testModel.save();
        show(sys5000.id);
    }
}

我发现当没有使用整数值输入字段排序时,create方法中的值将为null,这就是我在IntegerCheck.class中放入if null条件的原因。

因此,如果字段排序的值输入错误,则会检测到null并返回false。 虽然它不是我所期望的,但它会使用错误的类型值进行验证,但它的确有效......等等。

问题在于更新方法。 对于更新TestModel实例时,它不会显示错误的类型值,而是显示来自数据库的原始检索值。 这确实是一个问题,因为如果从数据库中检索的数据已经是整数,它将始终返回true。然后验证将无法完成工作。

问题是:

  1. 对此验证策略有何建议?我想也许我不同于验证Integer值验证的正确方法。

  2. 如何从操作中检索错误的类型值,或者这是不可能的,因为它已经不是该字段的有效数据类型。

1 个答案:

答案 0 :(得分:0)

您在更新方法中看到的行为是Play的工作方式!

以下是文档中的relevant section

  

...当Play找到id字段时,它会从中加载匹配的实例   数据库在编辑之前。其他参数由。提供   然后应用HTTP请求。

因此,在您的情况下,当更新期间 sort 属性为null时,将使用数据库中的值。

现在,如果我要努力实现你想要做的事情,我可以这样做:

在我的模特中

@Required
@CheckWith(IntegerCheck.class)
public int sort; // using primitive here to avoid null values.

static class IntegerCheck extends Check {

    public boolean isSatisfied(Object model, Object sort) {
        int fieldValue = (int) sort; // here you have the value as int

        // Here you would check whatever you want and return true or false.

        return ... 
    }

}