我有一个模型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。然后验证将无法完成工作。
问题是:
对此验证策略有何建议?我想也许我不同于验证Integer值验证的正确方法。
如何从操作中检索错误的类型值,或者这是不可能的,因为它已经不是该字段的有效数据类型。
答案 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 ...
}
}