@ISBN // 此注解表示该属性必须作为 ISBN 进行验证
String isbn;
只需将 @ISBN 添加到您的属性,它将在实体保存到数据库之前进行验证。问题是 @ISBN 并没有作为内置验证器包含在 Bean Validation 框架中。但这没什么大不了的,如果想要一个 @ISBN 注解,就创建它吧!我们现在将创建 @ISBN 验证注解。@Column(length=13)
String isbn;
使用浏览器运行您的 Product 模块。会看到 isbn 属性已经存在。现在,可以添加验证。
package com.yourcompany.invoicing.annotations; // 在注解包
import java.lang.annotation.*;
import javax.validation.*;
@Constraint(validatedBy = com.yourcompany.invoicing.validators.ISBNValidator.class)
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ISBN { // 一个常规 Java 注解的定义
Class<?>[] groups() default{};
Class<? extends Payload>[] payload() default{};
String message() default "isbn_invalid"; // i18n 文件消息的 id
}
如您所见,这是一个常规注解的定义。 message 属性是在验证失败时向用户显示的消息,您可以直接编写消息或输入 i18n id。虽然我们提供一个默认消息:isbn_invalid。但开发者在使用注解时也可以指定自己的消息,这必须在 invoicing-messages_zh.properties 中添加:
isbn_invalid=ISBN 无效或不存在
package com.yourcompany.invoicing.validators; // 在验证器包中
import javax.validation.*;
import com.yourcompany.invoicing.annotations.*;
import org.openxava.util.*;
public class ISBNValidator implements ConstraintValidator<ISBN, Object> { // 必须实现 ConstraintValidator
private static org.apache.commons.validator.routines.ISBNValidator
validator = // 来自Commons Validator 框架
new org.apache.commons.validator.routines.ISBNValidator();
public void initialize(ISBN isbn) {
}
// 包含验证逻辑
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (Is.empty(value)) return true;
return validator.isValid(value.toString()); // 使用“Commons Validator”
}
}
如您所见,验证器类必须实现 javax.validation 包中的 ConstraintValidator。这会强制您的验证器实现 initialize() 和 isValid()。 isValid() 方法包含验证逻辑。要注意的是,如果要验证的值为空,我们假定它是有效的。验证一个值何时存在是 @Required 等其他注解的责任。@Column(length=13) @ISBN
String isbn;
在这情况,当您将类的代码保存时,@ISBN 的导入不会自动添加。这是因为还有另一个@ISBN 可用(来自OpenXava 包含的Hibernate Validator 库),所以OpenXava Studio 不知道该选择哪一个。不用担心,只需将鼠标放在@ISBN 注解上,将显示一个弹出窗口,其中包含几种可能的解决方案,选择 Import 'ISBN' (com.yourcompany.invoicing.annotations),以便将正确的导入添加到 Product 类: