坦白说,我已经厌倦了介绍常规JSF引擎是如何实现用户输入校验的,无非就是在页面中加入: <f:validateLength minimum="5" maximum="6" />诸如此类的代码。在我看来,倘若你了解了 AOM 是如何实现校验机制的,那么,你肯定无法再忍受传统的校验方式。现在,就让我们来体验一下吧!
我们依然围绕计算器这个例子。首先,我们希望用户输入的数值不能为空,那么, 我们只需要在CalcBean中做如下更改:
@Bind
Requiredprivate double first = 22.0;
@Bind
@Requiredprivate double second = 7.0;
请注意,我们只是在 first 及 second 这两个成员变量上增加了一个新的annotation:@Required,那么,运行结果是怎样的呢?
中文环境下:
英文环境下:
是不是非常简单?
再做个稍微复杂些的,我们希望:第一个参数必须位于 10 至 100 之间,如果输入参数不合法,则显示给用户我们的自定义异常信息,如何做?将 CalcBean 改成这样:
@Bind
@Required
@ValidateDoubleRange(minimum=10, maximum=100, message="This number must be between 10 to 100 ")
private double first = 22.0;
运行效果如下:
“等等,我希望这个错误信息也是多语言的,怎么办?”
首先,我们修改一下properties文件
#demo.LocalStrings_zh_CN.properties
CalcBean.firstRangeErrMessage=该数值必须位于10至100之间
#demo.LocalStrings_en_US.properties
CalcBean.firstRangeErrMessage=This number must be between 10 to 100
然后,我们修改一下CalcBean:
@LocalString
private Map<String,String> messages;
@Bind
@Required
@ValidateDoubleRange(minimum=10, maximum=100, message="
#{this.messages.firstRangeErrMessage}")
private double first = 22.0;
请注意,在message中,我们也可以嵌入 EL表达式的。现在,让我们看一下中文的运行效果:
好像非常简单的就实现了用户校验的功能,但你可能又有新的疑问了:“以前我在做这种输入校验时, 我可以在页面中嵌入一些 javascript,虽然我的开发工作量较大,但是这种校验是放在客户端的,性能及用户体验都很好。AOM 虽然可以方便我完成校验功能,但每一次校验,都要与服务器端交互,这岂非对性能造成很大的影响?”。
你说的对,我完全明白你的意思,而且,我负责任的告诉你: AOM 能够满意你的所有要求!请在页面中加入如下代码:
<w:form id="calc"
clientValidate="true">
<layout:panelGrid columns="3">
...
</layout:panelGrid>
</w:form>
请注意,我只是加入一个属性:clientValidate="true",那么,运行效果是怎样的呢?
执行效果完全达到我们的预期目的,并且,当你点击“加”、“减”、“乘”、“除”这些按钮时,浏览器根本就没有和服务器端交互,我建议你可以装个 Firebug 监控一下,以证实我说的是真是假。
AOM 是怎么做到的呢?又是在变魔术?我们不妨打开页面生成的源代码看一下,其中包含这样一些代码片断:
<script type="text/javascript" language="Javascript">
document.forms['calc']._validators=[ new RequiredValidator('calc:first','数值一:: 校验错误,输入不能为空。','calc:j_id3'),
new FloatValidator('calc:first','该数值必须位于10至100之间','calc:j_id3',10.0,100.0),
new RequiredValidator('calc:second','数值二:: 校验错误,输入不能为空。','calc:j_id5')];
</script>
明白了吗?AOM 自动帮你生成了客户端的校验代码,而这一切,对你而言都是透明的,这就是 AOM 神奇魔力的其中之一!
但你可能又会问了:“你举的这些例子太简单了,有时候我需要在客户端完成非常复杂的逻辑,譬如,我这个人好吉利, 我希望第一个参数不能是514,该怎么办?”。
你逼我出狠招了!你可以在页面中嵌入一个<ajax:clientValidator/>,将页面修订成这样:
<w:textField id="first">
<ajax:clientValidator message="数值不能等于514">
if(value == 514) return false;
return true;
</ajax:clientValidator>
</w:textField>
我们在<ajax:clientValidator/>标签中嵌入任意的 JavaScript 代码,并且,在这段 JavaScript 代码中,可以直接引用 "value" 这个变量,该变量就是控件传递给你需要进行校验的值,然后你可以通过 JavaScript 完成你想要完成的任何逻辑。上述示例的效果如下:
“但是,那个 message 能否以 IoVC 的思想放到CalcBean呢?”
唉,你已经在页面中嵌入 JavaScript 代码了,你还指望什么 IoVC呢?
回顾刚才介绍的校验方式,我们可能会有一些疑问:上文所列的校验方式都是基于Annotation的,但毕竟Annotation 的表述能力是有限的,而有时候,我们需要进行的校验逻辑是非常复杂的,那么,这个问题如何解决?
可惜,由于我所举的 Calculator 例子过于简单,要描述复杂的校验逻辑,无法举出一个适合的场景,我只能把客户端校验那个比较“委琐”的校验逻辑拿过来做以示意: 我们不希望用户输入的第一个参数为514,那么,我们该怎么做?最简单的做法是通过基于正则表达式的@ValidateRegexp的 Annotation,但你还可以定义自己的校验方法:
@Validate
private boolean validateFirst(double value) {
return Double.compare(514, value) != 0;
}
为什么 AOM 会自动调用此方法?第一,它有一个 @Validate 的 annotation 声明,其次,它的名称为:validateFirst 。哦,又是“约定优于配置”这一原则的体现。
执行效果如下:
事实上,这个方法签名可以有很多种,除了直接返回boolean值的这种最简单形式,你还可以:
1) 标准写法: public void validate(FacesContext context, UIComponent component, Object value); 这是javax.faces.validator.Validator接口所定义的标准方法,采用这种写法可以得到当前正在校验的UI组件, 以获得更多的控制。
2) 简略写法 public boolean validate(Object value); 对输入值进行校验,如果成功则返回true,否则返回false。当采用这种写法时最好设置 @Validate 标注的message属性,用于提供出错信息。
3) 返回不同出错信息的简略写法 public String validate(Object value); 当需要根据不同的校验结果显示不同的出错信息时可以采用这种写法,当方法返回null时表示校验成功, 否则将返回值作为出错信息。注意在返回的字符串中可以包含EL表达式,因此可以很容易地实现国际化 而不是硬编码的固定字符串。
4) 抛出ValidatorException的简略写法 public void validate(Object value) throws ValidatorException; 同第三种方式类似,只不过将出错信息包含在ValidatorException中抛出。
你可能又提出一个新的问题:“刚才所有的验证,无论是基于 Annotation的,还是用自定义方法的,无论是服务器端校验,还是客户端校验,都是对单个控件的值进行校验,但有时候, 我需要在完整上下文中进行校验,这种情况又该如何实现呢?”
这种情况下,你可以在某个具体的 Action 中进行校验。举个简单的例子,众所周知,除数是不能为零的。在这种场景下,你需要知道完整的上下文:即需要知道 second 的具体数值,还需要知道用户点击的是哪个operator,那么,这种逻辑如何实现?你可以对 CalcBean 进行这样的修订:
@Action
public void divide() {
if (second == 0) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Divide by zero", null);
FacesContext.getCurrentInstance().addMessage("calc:second", message);
return;
}
result = first / second;
}
上述第1条语句无非是先 new 一个 FacesMessage,但 addMessage 方法中的 "calc:second" 是怎么回事呢?还记得我们的页面吗?
<w:form id="calc" clientValidate="true">
......
<h:outputLabel for="second"/>
<w:textField id="second"/>
<h:message for="second"/>
......
</w:form>
哦,原来calc指的是 form的id,而second,指的是 message的id。
相关推荐
《深入理解OperaMasks UI 2.0:前端框架与应用实践》 OperaMasks UI 2.0是一款由金蝶公司推出的高效、易用的前端界面库,它旨在为开发者提供一套完整的用户界面解决方案,以提升Web应用程序的用户体验和开发效率。...
"Operamasks UI 2.0 Doc"是一个针对 Operamasks 用户界面的开发文档,它提供了详尽的指导和信息,帮助开发者理解和构建基于Operamasks的Web应用程序。这个离线版文档对于开发者来说尤其珍贵,因为在线寻找这类资源...
operamasks-ui-2.0 这个帮助文档很难才找到的,感谢CSDN,其中的说明真的是很详细了,维护旧代码用到的这个框架,相比easyui和bootstrap这个框架简单一些,不过用起来还是不错的,除了文档太少,不过有这个就基本...
"Operamasks UI 2.0 Demo"是一个与JavaScript相关的压缩包,包含了对Opera Masks用户界面新版本的演示。这个项目可能是一个Web应用程序框架或库,专为开发人员设计,以便在Opera浏览器或其他支持JavaScript的环境中...
"Operamasks UI 2.0 Demo" 是一个专门针对Opera浏览器的扩展或应用界面设计的开发套件,主要用于创建和定制用户界面。这个压缩包文件 "operamasks-ui-2.0-demo--.zip" 包含了用于演示和实践如何使用Opera Masks UI ...
IoVC是OperaMasks2.0引入的概念,旨在解决传统MVC模式中控制逻辑与展现逻辑难以完全解耦的问题。在IoVC模型中,控制逻辑不再由展现层触发,而是由后台业务逻辑控制,这样开发者可以通过绑定ID来实现展现层与业务逻辑...
只是我在网上找的 operamasks-ui api 文档 , 希望对你们有帮助
OperaMasks-UI-Guide帮助文档
**Operamasks SDK 3.2:金蝶中间件的创新解决方案** Operamasks SDK 3.2 是金蝶中间件公司推出的一款重要的软件开发工具包,专为开发者设计,旨在简化与金蝶产品集成的过程,提高开发效率,并增强应用程序的功能。...
描述中连续出现了三次"operamasks-ui-2.0.zip",这可能是用户在强调这个特定版本的重要性,或者是在提示这是一个重复备份。 【标签】"operamasks-ui" 直接关联了这个框架的名字,它是这个压缩包的核心内容,是一个...
**OperaMasks安装包详解** OperaMasks 是一个专为Opera浏览器设计的扩展程序,它提供了丰富的功能,旨在提升用户的浏览体验。这个安装包包含了多个核心组件,让我们逐一解析: 1. **operamasks-comp.jar**:这个...
#### 三、operaMasks_studio的安装与配置 - **系统要求**:在安装operaMasks_studio之前,确保计算机满足最低系统要求,包括操作系统版本、JDK版本等。 - **下载与安装**:访问金山公司的官方网站或官方提供的...
**OperaMasks** 是一个专为Opera浏览器设计的JSF组件库,它扩展了JSF的功能,使得在Opera中使用JSF应用更加顺畅。 **教程概述:** "operamasks官方jsf教程"是针对初学者的一个资源,旨在介绍如何使用JSF和...
【标题】"OperaMasks查询、模糊查询、源码"涉及的是一个基于OperaMasks前端框架和后端servlet+bean技术实现的查询系统。在这个Demo中,开发者展示了如何运用这些技术来创建一个具备模糊查询功能的应用。让我们深入...
"Operamasks UI 2.1 Demo"是一个专注于前端用户界面的项目,主要基于流行的开源浏览器扩展框架——OperaMasks。这个项目的目的是提供一个演示版本,让用户和开发者能够体验和理解OperaMasks UI 2.1版本的功能和设计...
示例中定义了三个静态方法`close(Connection)`、`close(PreparedStatement)`和`close(ResultSet)`,用于关闭数据库连接、预处理语句和结果集。这是良好的编程习惯,能有效防止资源泄漏。 7. **查询操作**: 在`...