`
javatar
  • 浏览: 1708234 次
  • 性别: Icon_minigender_1
  • 来自: 杭州699号
社区版块
存档分类
最新评论
阅读更多
Struts(for)RCP(http://struts4rcp.googlecode.com)发布了0.1版本,但还缺少一个重要元素,那就是数据模型验证框架,MVC框架总是少不了它。
验证框架需要实现哪些功能?
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 {
		// ......
	}

}

分享到:
评论

相关推荐

    RCP jface 数据绑定 例子和测试范例

    在IT行业中,RCP(Rich Client Platform)是Eclipse框架的一部分,它提供了一种构建桌面应用程序的强大工具。JFace则是Eclipse RCP中的一个高级用户界面(UI)库,简化了SWT(Standard Widget Toolkit)的使用,使得...

    基于RCP的仿windows计算器

    Eclipse RCP是Eclipse IDE的一部分,它提供了一种模型-视图-控制器(MVC)架构,允许开发者将应用程序的逻辑、界面和数据分离。在这个架构中,模型负责处理数据和业务逻辑,视图负责显示这些数据,而控制器则作为两者...

    rcp收集资料上传

    在IT行业中,RCP(Rich Client Platform)是Eclipse框架的一部分,它提供了一种构建桌面应用程序的强有力方式。"rcp收集资料上传"这个标题暗示了我们可能在讨论关于如何在RCP应用中实现数据的收集和上传功能。这篇...

    Eclipse RCP 插件开发指南

    在 Eclipse RCP 中,JUnit 可以用来验证插件的行为是否符合预期。编写良好的单元测试有助于确保代码的质量和稳定性。 ##### JFace Data Binding JFace 数据绑定提供了将 UI 控件与模型对象自动同步的能力。通过...

    RCP弹出日期控件

    在IT领域,特别是软件开发中,RCP(Rich Client Platform)是一种基于Eclipse框架的应用程序开发模型,它允许开发者创建功能丰富的桌面应用程序。RCP弹出日期控件是这种环境中用于用户界面交互的一个重要组件,它...

    rcp 开发档案管理系统

    rcp(Rich Client Platform)是一种基于Eclipse框架的客户端应用程序开发技术,它允许开发者创建功能丰富的桌面应用,同时保持与现有系统和服务的集成。本档案管理系统就是利用rcp技术构建的,旨在提供一个高效、...

    RCP自学文档

    RCP应用程序基于插件模型,允许组件化开发,使得开发者可以只关注他们的应用核心功能,而不必从零开始构建整个UI框架。 1.2. **Eclipse RCP 构建风格 - 插件、扩展和扩展点** RCP的核心是插件系统,插件之间通过...

    rcp editor实例的项目代码2

    2. **模型-视图-控制器(MVC)模式**:Eclipse RCP应用通常遵循MVC设计模式,其中模型表示数据,视图负责展示数据,而控制器处理用户交互。在编辑器开发中,模型可能包括解析和存储文件内容的对象,视图则负责渲染...

    Eclipse 4 RCP - Tutorial.pdf

    - **创建应用程序模型**:详细步骤指导如何为Eclipse RCP应用程序创建应用程序模型。 - **将模型元素添加到应用程序模型中**:解释了如何将之前定义的各种模型元素添加到应用程序模型中,以实现具体功能。 以上内容...

    使用RCP进行程序开发(学习篇)

    它维护着整个应用程序的数据模型。 3. **Help(帮助系统)**:帮助系统是可扩展的,允许通过HTML文档添加自定义的导航结构,为用户提供详细的应用指南。 4. **Team(团队支持系统)**:这一组件提供版本控制和配置...

    RCP开发,调用ActiveX控件

    在IT行业中,RCP(Rich Client Platform)是Eclipse框架提供的一种用于构建桌面应用程序的平台。它允许开发者创建可扩展且功能丰富的应用,而无需从零开始构建整个用户界面。RCP开发通常涉及到UI组件、插件系统、...

    基于RCP的学生管理系统实例

    RCP,全称Rich Client Platform,是Eclipse基金会推出的一种客户端应用程序开发框架。它允许开发者构建功能丰富的桌面应用程序,同时利用Eclipse强大的插件系统进行扩展。在这个"基于RCP的学生管理系统实例"中,我们...

    Spring RCP RichClient 开发参考手册

    - **表单模型**:用于处理复杂的输入验证和数据转换,提高数据完整性。 #### 表单与绑定 - **表单构建**:利用Spring RCP提供的表单构建工具,快速创建复杂表单界面。 - **表单验证**:确保用户输入的有效性,支持...

    Eclipse 4 RCP

    Eclipse 4 RCP是基于Eclipse 4应用程序模型开发的,此模型的实现围绕着依赖注入、声明式服务、CSS主题化和异步编程模型等概念。这些创新极大地提升了开发人员在创建大型企业级应用时的灵活性和效率。 首先,我们来...

    ssh.rar_rcp

    Eclipse RCP是一个框架,允许开发者构建桌面应用,它提供了类似于IDE的功能,包括工作台、视图、编辑器等组件。这里的“布局格式”可能指的是视图在用户界面中的展示方式,如分割视图、堆叠视图或者标签页视图。 ...

    Eclipse_RCP_应用(完整的例子)

    Eclipse RCP(Rich Client Platform)是Eclipse提供的一个框架,用于构建具有丰富客户端功能的应用程序。基于Eclipse RCP开发的应用程序不仅可以运行在Eclipse平台上,还可以独立于Eclipse环境之外,以独立的窗口...

Global site tag (gtag.js) - Google Analytics