浏览 2087 次
锁定老帖子 主题:RCP数据模型验证框架
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-11-26
最后修改:2008-11-26
http://struts4rcp.googlecode.com)发布了0.1版本,但还缺少一个重要元素,那就是数据模型验证框架,MVC框架总是少不了它。
Struts(for)RCP(验证框架需要实现哪些功能? 1. 对Action执行过程中的数据进行透明化检验,Action只需声明验证规则,而不参与验证过程。 2. 可以服务器端验证,也以可客户端验证,或者数据模型自验证。 3. 验证规则捆绑方便,可以使用注解,也可以使用XML配置,以及直接编码捆绑。 4. 验证规则可自定义,并且内置规则丰富。 5. 验证出错信息国际化。 现成的验证框架已经不少,像Struts, WebWork, Hibernate, JSF等都提供了验证框架,是否可以重用? 由于B/S开发的盛行,大多数已有验证框架都向B/S结构倾斜,虽然它们也能验证C/S结构应用。 而且验证框架众多,不易选择大众口味,所以还是由框架本身提供,然后适配到其它验证框架。 如果重新定义验证框架,它应该属于哪个包? 它并不是MVC控制器框架必需的,而且它需要在服务器端和客户端同时使用, 甚至给其它第三方包复用,所以,它应该放在util包内,与序列化器相似。 最后决定放在com.googlecode.struts4rcp.util.validator包下。 首先,需要定义验证器接口,它将作为验证框架的中心接口,如: /** * 数据验证器 */ public interface Validator { /** * 验证数据 * @param model 数据模型 * @throws ValidationException 数据验证失败时抛出 */ void validate(Object model) throws ValidationException; } 基本的验证器实现如: /** * 必需验证器 */ public class RequiredValidator implements Validator { public void validate(Object model) throws ValidationException { if (model == null) throw new ValidationException(); if (model instanceof String && ((String)model).trim().length() == 0) throw new ValidationException(); if (model instanceof Collection && ((Collection<?>)model).size() == 0) throw new ValidationException(); if (model instanceof Map && ((Map<?, ?>)model).size() == 0) throw new ValidationException(); } } /** * 正则表达式验证器 */ public class PatternValidator implements Validator { protected final String pattern; public PatternValidator(String pattern) { this.pattern = pattern; } public void validate(Object model) throws ValidationException { if (model == null) return; if (! (model instanceof String)) return; String str = (String)model; str = str.trim(); if (str.trim().length() == 0) return; if (! str.matches(pattern)) throw new ValidationException(); } } 还有Length, Range, Email, URL, Phone, ZipCode, CreditCard, IdentificationCard等等。 以上都是原子级验证器的实现,可通过组合,链,委托等方式,进行更复杂的验证规则处理,如: /** * 验证器链 */ public class ValidatorChain implements Validator { private Collection<Validator> validators; public ValidatorChain(Validator... validators) { this.validators = Arrays.asList(validators); } public void validate(Object model) throws ValidationException { if (validators != null && validators.size() > 0) { for (Validator validator : validators) { validator.validate(model); } } } } /** * 字段验证器 */ public class FieldValidator implements Validator { protected final String filedName; protected final Validator validator; public FieldValidator(String filedName, Validator validator) { this.filedName = filedName; this.validator = validator; } public void validate(Object model) throws ValidationException { if (model == null) validator.validate(null); else if (model instanceof Map) validator.validate(((Map)model).get(filedName)); else validator.validate(BeanUtils.getProperty(model, filedName)); } } 等等。 不管验证规则多复杂,最终得到的都是一个Validator总接口。 这样,服务器端可通过拦载器,实现验证框架的集成:(此集成拦截器属于server包) /** * 验证拦截器 */ public class ValidationInterceptor implements ActionInterceptor { public Serializable intercept(Action<Serializable, Serializable> action, Serializable model) throws Exception { Action<Serializable, Serializable> srcAction = ActionContext.getContext().getAction(); Validator validator = null; if (srcAction instanceof ValidationAction) { // Action自声明 ValidationAction<Serializable, Serializable> validationAction = (ValidationAction<Serializable, Serializable>)srcAction; validator = validationAction.getValidator(); } else { validator = ValidationManager.getValidator(srcAction); // 从配置读取 } if (validator != null) validator.validate(model); // 验证 return action.execute(model); } } 然后,就是绑定规则,框架应支持多种绑定方式,以适应不同应用情况: 第一种方式,使用注解: 在Action上声明,表示只对指定Action请求进行验证,如: public class LoginAction implements Action<Account, User> { @Required // 不带field属性,表示对整个model进行校验,这里表示传入model不能为null,如果需要对比多个字段时,也可能需要用到 @Required(field="username") @Length(field="username", min=3, max=20) @Required(field="password") @Length(field="password", min=6, max=20) public User execute(Account account) throws Exception { // ...... } } 在数据模型上声明,表示对所有该类型的数据模型进行验证,如: public class Account { @Required @Length(min=3, max=20) public String getUsername() { // ...... } @Required @Length(min=6, max=20) public String getPassword() { // ...... } } 第二种方式,使用XML配置: <validation> <!--定义验证器--> <validator name="required" class="com.googlecode.struts4rcp.util.validator.RequiredValidator" /> <validator name="length" class="com.googlecode.struts4rcp.util.validator.LengthValidator" /> <!--只对指定Action请求进行验证--> <action name="loginAction"> <required /> <!--放在field外面,表示对整个model进行校验,这里表示传入model不能为null,如果需要对比多个字段时,也可能需要用到--> <field name="username"> <required /> <length min="3" max="20" /> </field> <field name="password"> <required /> <length min="6" max="20" /> </field> </action> <!--对所有该类型的数据模型进行验证--> <model class="com.xxx.demo.domain.Account"> <field name="username"> <required /> <length min="3" max="20" /> </field> <field name="password"> <required /> <length min="6" max="20" /> </field> </model> </validation> 第三种方式,直接编码构建规则: public class LoginAction implements ValidationAction<Account, User> { public Validator getValidator() { return new ValidatorChain( new RequiredValidator(), // 传入model不能为null new FieldValidator("username", new ValidatorChain( new RequiredValidator(), // 用户名不能为空 new LengthValidator(3, 20))), // 用户名长度限制 new FieldValidator("password", new ValidatorChain( new RequiredValidator(), new LengthValidator(6, 20)))); } public User execute(Account account) throws Exception { // ...... } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |