您的位置:首页 > Web前端 > JavaScript

简化 Ajax 和 Java 开发,第 3 部分: 基于 DOM、JavaScript 和 JSP 标记文件构建 UI 特性

2013-02-26 23:26 726 查看
http://www.ibm.com/developerworks/cn/web/wa-aj-simplejava3.html

简介: 在本系列的第 1 部分,您了解了如何生成用来发送 Ajax 请求和处理 Ajax 响应的 JavaScript 代码。第 2 部分展示了如何使用约定和 JSP 标记文件创建 HTML 表单以最小化设置和配置。在本系列的第 3 部分中,您将了解如何开发基于 JavaScript 的客户端验证器和服务端验证器,后者被实现为支持 JavaScript 客户端验证器的 JSP 标记文件。此外,您还将了解如何使用资源包,它们会在更改后自动重载,而不需要重启应用程序。

客户端验证十分有用,因为它减少,甚至不需要将表单返回给用户以改正错误。但是,基于 JavaScript 的验证还不够,因为如果数据通过程序提交给服务器,或用户浏览器禁用了 JavaScript,这种验证都会被绕开。本文展示如何实现客户端和服务器端验证。

创建客户端验证器的层次结构

本节展示如何使用构造函数和 JavaScript 中的原型来构建对象层次结构,用于验证用户在 Web 浏览器中的输入。本节的所有代码都可以在示例应用程序的(参见 下载 部分)
valid.js
文件中找到。

开发基础验证器

在 JavaScript 中,可以结合使用函数和
new
操作符来创建对象。“构造函数” 必须使用
this
来恰当地初始化对象属性。清单
1 给出了
Validator()
函数,该函数有 4 个参数:表单名称、元素名称、ID 和消息。这些参数的值作为属性存储在当前对象中。

同一个构造函数创建的对象可以共享属性,这些属性存储在
prototype
对象中。在清单 1 中,
defaultMsgIndex
是所有实例共享的一个属性,这些实例由
new
Validator(...)
创建。当您试图访问属性或对象的方法时,JavaScript 引擎首先在对象的成员中查看。如果没有找到,引擎就会验证对象的原型(对象可能具有自己的原型)。因此,该原型链可用于实现继承(在后面讨论)。在本文的示例中,
Validator
是对象层次结构的基础。

清单 1. Validator() 构造函数

function Validator(formName, elemName, outId, msg) {
if (formName)
this.formName = formName;
if (elemName)
this.elemName = elemName;
if (outId)
this.outId = outId;
if (msg)
this.msgList = ["", msg];
}

Validator.prototype.defaultMsgIndex = 0;

任何 JavaScript 函数都可以成为对象的方法。只需在对象构造函数中使用
this.methodName = functionName
。由于方法通常可以被同一个构造函数创建的所有实例共享,所以可以将该方法与构造函数的原型进行关联。在这里可以通过使用
constructorName.prototype.methodName
实现,如清单
2 所示:

清单 2. 验证器的 getFormValues() 方法

Validator.prototype.getFormValues = function() {
var elemValues = new Array();
var form = document.forms[this.formName];
var formElements = form.elements;
for (var i = 0; i < formElements.length; i++) {
var element = formElements[i];
if (element.name == this.elemName) {
var elemType = element.type.toLowerCase();
if (elemType == "text" || elemType == "textarea"
|| elemType == "password" || elemType == "hidden")
elemValues[elemValues.length] = element.value;
else if (elemType == "checkbox" && element.checked)
elemValues[elemValues.length]
= element.value ? element.value : "On";
else if (elemType == "radio" && element.checked)
elemValues[elemValues.length] = element.value;
else if (elemType.indexOf("select") != -1)
for (var j = 0; j < element.options.length; j++) {
var option = element.options[j];
if (option.selected) {
elemValues[elemValues.length]
= option.value ? option.value : option.text;
}
}
}
}
return elemValues;
}

清单 2 中的
getFormValues()
方法返回表单元素(它的名称恰好与
elemName
属性的值相同)的值。代表
Web 浏览器中的 HTML 表单的 DOM 对象通过
document.forms[this.formName]
获得。然后,
getFormValues()
遍历表单的
elements
,根据
HTML 的类型处理每一个元素。

如果是文本、密码或隐藏字段,
getFormValues()
方法只将元素的值添加给所返回的数组。如果元素的类型为复选框或单选框,只有选中 HTML 元素时,才会添加值。最后,如果元素是一个列表,选中项的值就会存储到返回的数组中。

层次结构中的每个验证器都需要一个方法来验证单个值。对于基础的
Validator
verify()
方法(如清单 3 所示)返回
0
,但其他验证器将用其自身方法代替这个方法。由
verify()
返回的值用来在
msgList
内查找消息。

清单 3. 验证器的 verify() 方法

Validator.prototype.verify = function(value) {
return 0;
}

showMsg()
方法(参见清单 4)通过
innerHTML
属性向 HTML 元素插入一个消息。代表 HTML 元素的对象通过
document.getElementById(this.outId)
获得。消息用
htmlEncode()
函数进行编码,该函数在本系列的 第
1 部分 介绍过。这个辅助函数的代码可以在
encode.js
中找到。

清单 4. 验证器的 showMsg() 方法

Validator.prototype.showMsg = function(index) {
document.getElementById(this.outId).innerHTML
= htmlEncode(this.msgList[index]);
}

清单 5 包含
execute()
方法,它遍历由
getFormValues()
返回的值,并为每个值调用
verify()
。如果
execute()
方法结束时
msgIndex
0
,那么用户输入就是有效的。在本例中,
showMsg()
通过将空白字符串存储到输出元素的
innerHTML
属性,清除以前的所有消息。否则,调用
showMsg()
之后会在
Web 页面上出现错误消息。

清单 5. 验证器的 execute() 方法

Validator.prototype.execute = function() {
var msgIndex = this.defaultMsgIndex;
var elemValues = this.getFormValues();
for (var i = 0; i < elemValues.length; i++)
if (elemValues[i]) {
msgIndex = this.verify(elemValues[i]);
if (msgIndex != 0)
break;
}
this.showMsg(msgIndex);
return msgIndex == 0;
}

实现具体的验证器

valid.js
文件包含一个针对所需字段的验证器。
RequiredValidator()
构造函数(参见清单 6)的参数与
Validator()
函数相同。为了用
Validator()
初始化对象属性,
RequiredValidator()
构造函数设置一个名为
base()
的方法。在
base()
的协助下调用
Validator()
之后,
RequiredValidator()
从当前对象删除
base()
方法,因为不再需要它。

清单 6. RequiredValidator() 构造函数及其原型设置

function RequiredValidator(formName, elemName, outId, msg) {
this.base = Validator;
this.base(formName, elemName, outId, msg);
delete this.base;
}

RequiredValidator.prototype = new Validator();

RequiredValidator.prototype.defaultMsgIndex = 1;

RequiredValidator.prototype.verify = function(value) {
return value.length > 0 ? 0 : 1;
}

所有
RequiredValidator
对象的原型都是一个
Validator
实例,该实例没有任何属性,因为没有参数传递给
Validator()
构造函数。通过设置这一原型,
RequiredValidator
“继承”
了为
Validator
的原型定义的属性和方法。

例如,当调用
RequiredValidator
对象的
execute()
方法时,JavaScript 引擎首先在对象的方法中查找。由于对象没有
execute()
方法,下一个将查找对象的原型,然后是原型的原型,依此类推。在本例中,
RequiredValidator
的原型是
Validator
实例,这个实例的原型具有
execute()
方法。

RequiredValidator
原型的
defaultMsgIndex
属性设置为
1
,因为如果元素值丢失,就应该报告错误。如果值不为空,
verify()
方法返回
0
,如果需要的字段的值没有输入,就返回
1


清单 7 给出了
LengthValidator
,与
RequiredValidator
十分类似。
LengthValidator()
构造函数有
7 个参数:表单名称、必须验证其值的元素的名称、用来输出错误消息的元素的 ID、已验证的值的最小和最大的长度,以及两个错误消息。
LengthValidator
的原型是一个新的
Validator
实例,与
RequiredValidator
中的情况类似。如果值有效,
verify()
方法返回
0
,如果值太短,则返回
1
,如果太长,则返回
2


清单 7. LengthValidator() 构造函数及其原型设置

function LengthValidator(formName, elemName, outId, min, max, msgMin, msgMax) {
this.base = Validator;
this.base(formName, elemName, outId);
delete this.base;
this.min = min;
this.max = max;
this.msgList = ["", msgMin, msgMax];
}

LengthValidator.prototype = new Validator();

LengthValidator.prototype.verify = function(value) {
if (value.length < this.min)
return 1;
if (value.length > this.max && this.max > 0)
return 2;
return 0;
}

为了轻松管理 Web 页面的验证器,
valid.js
文件定义了
ValidatorList()
构造函数(参见清单 8),它创建一个包含有验证器数组的对象。
add()
方法可将一个验证器实例追加到该数组。
execute()
方法遍历验证器列表,调用每个验证器的
execute()
方法,这些验证器的属性与给定表单的名称和可选元素的名称相匹配。因此,
ValidatorList
execute()
方法可以验证整个表单,也可只验证表单中的某个元素。

清单 8. ValidatorList() 构造函数及其原型设置

function ValidatorList() {
this.validatorArray = new Array();
}

ValidatorList.prototype.add = function(validator) {
this.validatorArray[this.validatorArray.length] = validator;
}

ValidatorList.prototype.execute = function(formName, elemName) {
var valid = true;
for (var i = 0; i < this.validatorArray.length; i++) {
var validator = this.validatorArray[i];
if (validator.formName == formName)
if (!elemName || validator.elemName == elemName)
if (!validator.execute())
valid = false;
}
return valid;
}

var pageValidators = new ValidatorList();

构建一个服务器端验证器库

前一节展示了如何在客户端用 JavaScript 验证用户输入。一旦表单数据提交,出于安全或为了防止用户浏览器禁用了 JavaScript,最好在服务器端重新验证用户输入。本节将讨论作为验证器的一组 JSP 标记文件。

由于使用 JSP 句法并且可跨页重用,标记文件很容易在服务器上实现验证。此外,用来验证用户输入的标记文件能够生成在 Web 浏览器中进行验证的 JavaScript 代码。由于只需在 Web 页面中一次性指定验证器的属性,因此这项技术减少了编码工作。

使用 JSP 标记文件实现验证器

在 Web 页面中,上一节的 JavaScript 验证器需要
<span>
元素和
innerHTML
的帮助来显示这些元素的消息。这些元素由
errMsg.tag
文件产生(如清单
9 所示):

清单 9. errMsg.tag 文件

<%@ attribute name="id" required="true" rtexprvalue="true" %>
<%@ tag body-content="scriptless" %>

<span id="${id}" class="ValidationError"><jsp:doBody/></span>

valid.css
文件(参见清单 10)定义了用于错误消息的
ValidationError
样式类:

清单 10. valid.css 文件

.ValidationError { color: red; }

required.tag
文件(参见清单 11)为必需字段实现服务器端验证,并生成用来在客户端设置
RequiredValidator
对象的 JavaScript
代码片段。这个标记文件定义两个属性:必需字段的名称和一个可选错误消息。

如果没有提供
msg
属性,则
required.tag
通过
<dvu:useDefaultMsg/>
调用另一个标记文件来设定
defaultValidMsg
映射,它包含了验证器的默认消息。然后,将
required
消息存储到
msg
变量。

接下来,
required.tag
文件使用
<dvu:errMsg>
生成
<span>
元素,如果有错误消息,它就会包装这些消息。如果具有给定名称的请求参数缺失,即用户没有填写必需字段,那么此标记文件将用
<c:out>
输出这个消息,并通过
<dfu:addError>
标记向映射添加这个错误,这在本系列的 第
2 部分 介绍过。

随后,
required.tag
文件生成一小段 JavaScript 代码,它将在 Web 浏览器中执行。此代码创建一个
RequiredValidator
对象并将其添加到名为
pageValidators

JavaScript 验证器列表中。本文前面的部分描述了
RequiredValidator
。传递给
RequiredValidator()
构造函数的字符串参数用
<da:jstring>
标记编码,这在本系列的 第
1 部分 部分介绍过。

清单 11. required.tag 文件

<%@ attribute name="name" required="true" rtexprvalue="true" %>
<%@ attribute name="msg" required="false" rtexprvalue="true" %>
<%@ tag body-content="empty" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="da" tagdir="/WEB-INF/tags/dynamic/ajax" %>
<%@ taglib prefix="dfu" tagdir="/WEB-INF/tags/dynamic/forms/util" %>
<%@ taglib prefix="dvu" tagdir="/WEB-INF/tags/dynamic/valid/util" %>

<c:if test="${empty msg}">
<dvu:useDefaultMsg/>
<c:set var="msg" value="${defaultValidMsg.required}"/>
</c:if>

<c:set var="outId" value="${name}Required"/>
<dvu:errMsg id="${outId}">
<c:if test="${formPost && empty param[name]}">
<c:out value="${msg}"/>
<dfu:addError name="${name}" msg="${msg}"/>
</c:if>
</dvu:errMsg>

<script type="text/javascript">
pageValidators.add(new RequiredValidator(
<da:jstring value="${formName}"/>, <da:jstring value="${name}"/>,
<da:jstring value="${outId}"/>, <da:jstring value="${msg}"/>));
</script>

length.tag
文件(如清单 12 所示)是另外一个验证器,可用来验证请求参数的长度。已验证的参数通常是表单元素的提交值。此标记文件接受 5 个属性:元素名称、最小和最大长度,以及两个可选错误消息。此标记文件会输出由
<dvu:errMsg>
生成的
<span>
元素中的所有错误消息,与
required.tag
的情况十分相似。由
length.tag
生成的
JavaScript 代码在客户端创建一个
LengthValidator
对象。

清单 12. length.tag 文件

<%@ attribute name="name" required="true" rtexprvalue="true" %>
<%@ attribute name="min" required="false" rtexprvalue="true"
type="java.lang.Long" %>
<%@ attribute name="max" required="false" rtexprvalue="true"
type="java.lang.Long" %>
<%@ attribute name="msgMin" required="false" rtexprvalue="true" %>
<%@ attribute name="msgMax" required="false" rtexprvalue="true" %>
<%@ tag body-content="empty" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="da" tagdir="/WEB-INF/tags/dynamic/ajax" %>
<%@ taglib prefix="dfu" tagdir="/WEB-INF/tags/dynamic/forms/util" %>
<%@ taglib prefix="dvu" tagdir="/WEB-INF/tags/dynamic/valid/util" %>

<dvu:useDefaultMsg/>
<c:if test="${empty msgMin}">
<c:set var="msgMin" value="${defaultValidMsg.too_short}"/>
</c:if>
<c:if test="${empty msgMax}">
<c:set var="msgMax" value="${defaultValidMsg.too_long}"/>
</c:if>

<c:set var="outId" value="${name}Length"/>
<dvu:errMsg id="${outId}">
<c:if test="${formPost && !empty param[name]}">
<c:if test="${min != null && fn:length(param[name]) < min}">
<c:out value="${msgMin}"/>
<dfu:addError name="${name}" msg="${msgMin}"/>
</c:if>
<c:if test="${max != null && fn:length(param[name]) > max}">
<c:out value="${msgMax}"/>
<dfu:addError name="${name}" msg="${msgMax}"/>
</c:if>
</c:if>
</dvu:errMsg>

<script type="text/javascript">
pageValidators.add(new LengthValidator(<da:jstring value="${formName}"/>,
<da:jstring value="${name}"/>, <da:jstring value="${outId}"/>,
${min != null ? min : 0}, ${max != null ? max : 0},
<da:jstring value="${msgMin}"/>, <da:jstring value="${msgMax}"/>));
</script>

用 JSP 标记文件创建资源包

在 Java™ 应用程序中,消息通常被存储在资源包中,这些资源包一般被编码为置于
CLASSPATH
中的
.properties
文件。当对资源包做了更改后,必须重启应用程序确保刷新
.properties
文件。如果想避免重启应用程序,可以将消息和其他文本资源放到
JSP 标记文件中。当标记文件被更改后,应用服务器会自动重载标记文件。

清单 13 给出了
useDefaultMsg.tag
文件,它定义了验证器的默认消息,并在
java.util.HashMap
对象中将它们分组,这些对象在
JSP
request
作用域中由
<jsp:useBean>
创建。消息通过 JSTL 的
<c:set>
标记放置到映射中。对于每个请求,
useDefaultMsg.tag
文件会根据用户偏好的区域选择验证器将要使用的消息映射,用户区域通过
${pageContext.request.locale}
获取。

清单 13. useDefaultMsg.tag 文件

<%@ tag body-content="scriptless" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<c:if test="${defaultValidMsg_en == null}">
<jsp:useBean id="defaultValidMsg_en" scope="request" class="java.util.HashMap">
<c:set target="${defaultValidMsg_en}" property="required"  value="Required"/>
<c:set target="${defaultValidMsg_en}" property="too_short" value="Too short"/>
<c:set target="${defaultValidMsg_en}" property="too_long"  value="Too long"/>
</jsp:useBean>
<c:if test="${!initParam.debug}">
<c:set var="defaultValidMsg_en" scope="application"
value="${requestScope.defaultValidMsg_en}"/>
</c:if>
</c:if>
...
<c:if test="${defaultValidMsg == null}">
<c:choose>
<c:when test="${fn:startsWith(pageContext.request.locale, 'en')}">
<c:set var="defaultValidMsg" scope="request"
value="${defaultValidMsg_en}"/>
</c:when>
...
</c:choose>
</c:if>

此示例展示了如何实现可自动重载的资源。对于现实中的应用程序,可以增强这个机制,以便使用更简单的语法定义资源。例如,可以使用一个定制标记,而不是
<c:set>
,避免必须为每个消息指定
target
属性。此外,还也可以将不同区域的资源放置在不同的文件中,简化转换过程。

在开发过程中,应该在
web.xml
文件中将
debug
参数设为
true
(参见清单
14),以便为每个请求重新创建所有的消息映射,这让您可以进行更改而不需重启 Web 应用程序。但在生成环境中,就应将
debug
切换为
false
,在
application
作用域中启用映射缓存。

清单 14. web.xml 文件

<web-app ...>

<context-param>
<param-name>skin</param-name>
<param-value>default</param-value>
</context-param>

<context-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</context-param>

</web-app>

为 Web 表单启用 JavaScript 验证器

至此,您已经知道如何在客户端及服务器端验证用户输入。接下来,将学习如何在 Web 浏览器中激活基于 JavaScript 的验证。表单元素的
onblur
属性允许在元素丢失键盘焦点时执行某些 JavaScript 代码,这是验证用户刚输入的值的好时机。此外,
<form>
标记的
onsubmit
属性允许在单击
Submit 按钮后立即调用一个 JavaScript 函数,如果用户输入无效,甚至可以通过返回
false
来取消表单的发布。

本系列的 第 2 部分 展示了如何用一组 JSP 标记文件生成 HTML 表单。您不必为增加验证支持而更改它们,因为表单标记文件使用
attrList.tag
文件(如清单
15 所示)生成表单元素的动态属性。在 第 2 部分 中,您已经看到如何在
attrList.tag
中添加默认样式。在这里我们修改这个文件,增加
onblur
onsubmit
属性,它们包含了用来执行
JavaScript 验证器的函数调用。

必须添加到 HTML 元素的
class
onblur
onsubmit
属性放置在名为
addMap
java.util.HashMap
实例中。然后,
attrList.tag
遍历
map
addMap
集的元素,生成元素的
HTML 属性。

清单 15. attrList.tag 文件

<%@ attribute name="tag" required="true" rtexprvalue="true" %>
<%@ attribute name="map" required="true" rtexprvalue="true"
type="java.util.Map" %>
<%@ tag body-content="empty" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<jsp:useBean id="addMap" class="java.util.HashMap"/>
<c:if test="${!empty initParam.skin}">
<c:set target="${addMap}" property="class"
value="${initParam.skin}_${tag}"/>
</c:if>
<c:if test="${tag=='input_text' || tag=='input_password' || tag=='input_radio'
|| tag=='textarea' || tag=='select'}">
<c:set target="${addMap}" property="onblur"
value="pageValidators.execute('${formName}', this.name)"/>
</c:if>
<c:if test="${tag=='form'}">
<c:set target="${addMap}" property="onsubmit"
value="return pageValidators.execute('${formName}')"/>
</c:if>

<c:forEach var="attr" items="${map}">
<c:if test="${addMap[attr.key] == null}">
${attr.key}="${fn:escapeXml(attr.value)}"
</c:if>
<c:if test="${addMap[attr.key] != null}">
<c:set var="sep" value="${fn:startsWith(attr.key, 'on') ? ';' : ' '}"/>
<c:set target="${addMap}" property="${attr.key}"
value="${attr.value}${sep}${addMap[attr.key]}"/>
</c:if>
</c:forEach>

<c:forEach var="attr" items="${addMap}">
${attr.key}="${fn:escapeXml(attr.value)}"
</c:forEach>

向示例应用程序添加验证

本系列的 第 2 部分 给出了一个基于表单标记文件的简单 JSP 示例。本节将展示如何向 Web 表单添加验证。

更新 Web 表单

清单 16 包含
SupportForm.jsp
页面的修改版本。注意,第一个变化是
<%@page%>
指令,它有
autoFlush="false"
buffer="64kb"
属性。默认状态下,JSP
页面具有一个
8kb
的缓冲区,满载动态生成的 HTML 后,它会自动刷新。缓冲区刷新后,页面将不能再使用
<jsp:forward>


当用户输入无效时,
form.tag
文件(用来实现
SupportForm.jsp
页面中的
<df:form>
标记)会使用
<jsp:forward>

HTTP 请求分配给另一个页面
SupportConfirm.jsp
。添加了验证代码后,由
SupportForm.jsp
生成的 HTML 的将大于
8kb
。因此,这个页面的缓冲区也相应增加,确保转发能正确进行。此外,也禁用了
autoFlush
,目的是在缓冲区不足以容纳
Web 页面生成的整个 HTML 时,方便调试工作。

您还会发现
SupportForm.jsp
页面的头也发生了变化,它声明验证器标记库(前缀是
dv
)、
valid.css
文件和两个
JavaScript 文件(
encode.js
valid.js
),它们包含用于 HTML 编码和客户端验证的 JavaScript 函数。在整个
SupportForm.jsp
页面,绝大多数表单元素的前面都带有
<dv:required>
,而一些表单元素则使用
<dv:length>
来验证所输入字符串的长度。

清单 16. SupportForm.jsp 示例

<%@ page autoFlush="false" buffer="64kb"%>
<%@ taglib prefix="df" tagdir="/WEB-INF/tags/dynamic/forms" %>
<%@ taglib prefix="dv" tagdir="/WEB-INF/tags/dynamic/valid" %>

<jsp:useBean id="supportBean" scope="request" class="formsdemo.SupportBean"/>

<html>
<head>
<title>Support Form</title>
<link rel="stylesheet" href="forms.css" type="text/css">
<link rel="stylesheet" href="valid.css" type="text/css">
<script src="encode.js" type="text/javascript">
</script>
<script src="valid.js" type="text/javascript">
</script>
</head>
<body>

<h1>Support Form</h1>

<df:form name="supportForm" model="${supportBean}"
action="SupportConfirm.jsp">

<p>Name:
<dv:required name="name"/>
<dv:length name="name" max="60"/> <br>
<df:input name="name" type="text" size="40"/>

<p>Email:
<dv:required name="email"/>
<dv:length name="email" max="60"/> <br>
<df:input name="email" type="text" size="40"/>

<p>Versions:
<dv:required name="versions"/> <br>
<df:select name="versions" multiple="true" size="5">
<df:option>2.0.1</df:option>
<df:option>2.0.0</df:option>
<df:option>1.1.0</df:option>
<df:option>1.0.1</df:option>
<df:option>1.0.0</df:option>
</df:select>

<p>Platform:
<dv:required name="platform"/> <br>
<df:input name="platform" type="radio" value="Windows"/> Windows <br>
<df:input name="platform" type="radio" value="Linux"/> Linux <br>
<df:input name="platform" type="radio" value="Mac"/> Mac <br>

<p>Browser:
<dv:required name="browser"/> <br>
<df:select name="browser" size="1">
<df:option value=""></df:option>
<df:option value="IE">IE</df:option>
<df:option value="Firefox">Firefox</df:option>
<df:option value="Netscape">Netscape</df:option>
<df:option value="Mozilla">Mozilla</df:option>
<df:option value="Opera">Opera</df:option>
<df:option value="Safari">Safari</df:option>
</df:select>

<p><df:input name="crash" type="checkbox"/> Causes browser crash

<p>Problem:
<dv:required name="problem"/>
<dv:length name="problem" min="100" max="2000"
msgMin="Cannot have less than 100 characters"
msgMax="Cannot have more than 2000 characters"/> <br>
<df:textarea name="problem" rows="10" cols="40"/>

<p><df:input name="submit" type="submit" value="Submit"/>

</df:form>

</body>
</html>

分析生成的 HTML

查看由
SupportForm.jsp
页面生成的 HTML 时(清单 17 中显示了一部分),将会发现与客户端验证相关的属性和代码片段:

<form>
元素具有
onsubmit
属性,该属性包含一个 JavaScript 调用,在整个表单有效时,此调用才返回
true


当丢失键盘焦点时,
<input>
<textarea>
<select>
元素使用
onblur
属性来验证它们的值。

每个验证器标记生成:

一个
<span>
元素,错误消息将被插入其中。

一段用来创建验证器对象的 JavaScript 代码。

清单 17. 由 SupportForm.jsp 生成的 HTML

<html>
<head>
<title>Support Form</title>
<link rel="stylesheet" href="forms.css" type="text/css">
<link rel="stylesheet" href="valid.css" type="text/css">
<script src="encode.js" type="text/javascript">
</script>
<script src="valid.js" type="text/javascript">
</script>
</head>
<body>

<h1>Support Form</h1>

<form name="supportForm" method="POST" class="default_form"
onsubmit="return pageValidators.execute('supportForm')">
...
<p>Email:
<span id="emailRequired" class="ValidationError">
</span>
<script type="text/javascript">
pageValidators.add(new RequiredValidator(
"supportForm", "email", "emailRequired", "Required"));
</script>
<span id="emailLength" class="ValidationError">
</span>
<script type="text/javascript">
pageValidators.add(new LengthValidator(
"supportForm", "email", "emailLength", 0, 60,
"Too short", "Too long"));
</script>
<br>
<input name="email" type="text" size="40" class="default_input_text"
onblur="pageValidators.execute('supportForm', this.name)">
...
</form>

</body>
</html>

结束语

在本文,您学会了如何用 JavaScript 构造函数和原型构建一个客户端验证器的分层结构。此外,还学会了如何创建基于 JSP 标记文件的服务器端验证器和资源包。请继续关注本系列的下一篇文章,您将从中发现如何用 JSP 标记文件创建类似于 JSF 的组件。

代码下载地址:

http://download.csdn.net/detail/mr__fang/5091091
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐