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

本文介绍了如何使用JavaScript构建客户端表单验证器,并通过JSP标记文件实现服务器端验证。包括客户端验证器层次结构的设计、具体验证器的实现,以及如何在Web页面中启用这些验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 元素时,才会添加值。最后,如果元素是一个列表,选中项的值就会存储到返回的数组中。

层次结构中的每个验证器都需要一个方法来验证单个值。对于基础的 Validatorverify() 方法(如清单 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 元素的 classonblur 和 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"
            οnsubmit="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"
            οnblur="pageValidators.execute('supportForm', this.name)">
        ...
    </form>

</body>
</html>


 

结束语

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

代码下载地址:

http://download.youkuaiyun.com/detail/mr__fang/5091091

 

JFM7VX690T型SRAM型现场可编程门阵列技术手册主要介绍的是上海复旦微电子集团股份有限公司(简称复旦微电子)生产的高性能FPGA产品JFM7VX690T。该产品属于JFM7系列,具有现场可编程特性,集成了功能强大且可以灵活配置组合的可编程资源,适用于实现多种功能,如输入输出接口、通用数字逻辑、存储器、数字信号处理时钟管理等。JFM7VX690T型FPGA适用于复杂、高速的数字逻辑电路,广泛应用于通讯、信息处理、工业控制、数据中心、仪表测量、医疗仪器、人工智能、自动驾驶等领域。 产品特点包括: 1. 可配置逻辑资源(CLB),使用LUT6结构。 2. 包含CLB模块,可用于实现常规数字逻辑分布式RAM。 3. 含有I/O、BlockRAM、DSP、MMCM、GTH等可编程模块。 4. 提供不同的封装规格工作温度范围的产品,便于满足不同的使用环境。 JFM7VX690T产品系列中,有多种型号可供选择。例如: - JFM7VX690T80采用FCBGA1927封装,尺寸为45x45mm,使用锡银焊球,工作温度范围为-40°C到+100°C。 - JFM7VX690T80-AS同样采用FCBGA1927封装,但工作温度范围更广,为-55°C到+125°C,同样使用锡银焊球。 - JFM7VX690T80-N采用FCBGA1927封装铅锡焊球,工作温度范围与JFM7VX690T80-AS相同。 - JFM7VX690T36的封装规格为FCBGA1761,尺寸为42.5x42.5mm,使用锡银焊球,工作温度范围为-40°C到+100°C。 - JFM7VX690T36-AS使用锡银焊球,工作温度范围为-55°C到+125°C。 - JFM7VX690T36-N使用铅锡焊球,工作温度范围与JFM7VX690T36-AS相同。 技术手册中还包含了一系列详细的技术参数,包括极限参数、推荐工作条件、电特性参数、ESD等级、MSL等级、重量等。在产品参数章节中,还特别强调了封装类型,包括外形图尺寸、引出端定义等。引出端定义是指对FPGA芯片上的各个引脚的功能接线规则进行说明,这对于FPGA的正确应用电路设计至关重要。 应用指南章节涉及了FPGA在不同应用场景下的推荐使用方法。其中差异说明部分可能涉及产品之间的性能差异;关键性能对比可能包括功耗与速度对比、上电浪涌电流测试情况说明、GTH Channel Loss性能差异说明、GTH电源性能差异说明等。此外,手册可能还提供了其他推荐应用方案,例如不使用的BANK接法推荐、CCLK信号PCB布线推荐、JTAG级联PCB布线推荐、系统工作的复位方案推荐等,这些内容对于提高系统性能稳定性有着重要作用。 焊接及注意事项章节则针对产品的焊接过程提供了指导,强调焊接过程中的注意事项,以确保产品在组装过程中的稳定性可靠性。手册还明确指出,未经复旦微电子的许可,不得翻印或者复制全部或部分本资料的内容,且不承担采购方选择与使用本文描述的产品服务的责任。 上海复旦微电子集团股份有限公司拥有相关的商标知识产权。该公司在中国发布的技术手册,版权为上海复旦微电子集团股份有限公司所有,未经许可不得进行复制或传播。 技术手册提供了上海复旦微电子集团股份有限公司销售及服务网点的信息,方便用户在需要时能够联系到相应的服务机构,获取最新信息必要的支持。同时,用户可以访问复旦微电子的官方网站(***以获取更多产品信息公司动态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值