`

jstl 入门-------IBM

阅读更多

 
developerWorks 中国  >  Java technology  >

JSTL 入门: 表达式语言

通过避免使用脚本编制元素来简化对 JSP 应用程序的软件维护

developerWorks
文档选项
<noscript></noscript>
将此页作为电子邮件发送

将此页作为电子邮件发送

<!----><!---->
拓展 Tomcat 应用

下载 IBM 开源 J2EE 应用服务器 WAS CE 新版本 V1.1

<!---->

级别: 初级

Mark A. Kolb, 软件工程师

2003 年 5 月 27 日

JSP 标准标记库(JSP Standard Tag Library,JSTL)是一个实现 Web 应用程序中常见的通用功能的定制标记库集,这些功能包括迭代和条件判断、数据管理格式化、XML 操作以及数据库访问。在 developerWorks 上其新系列的第一篇文章中,软件工程师 Mark Kolb 向您展示了如何使用 JSTL 标记来避免在 JSP 页面中使用脚本编制元素。您还将了解如何通过从表示层删除源代码来简化软件维护。最后,您将了解 JSTL 经过简化的表达式语言,它允许在不必使用功能齐全的编程语言的情况下对 JSTL 操作指定动态属性值。
<!----><!----><!---->

JavaServer Pages(JSP)是用于 J2EE 平台的标准表示层技术。JSP 技术提供了用于执行计算(这些计算用来动态地生成页面内容)的脚本编制元素和操作。脚本编制元素允许在 JSP 页面中包括程序源代码,在为响应用户请求而呈现页面时可以执行这些源代码。操作将计算操作封装到很象 HTML 或 XML 标记的标记中,JSP 页面的模板文本通常包含这些标记。JSP 规范只将几种操作定义成了标准,但从 JSP 1.1 开始,开发人员已经能够以定制标记库的方式创建其自己的操作了。

JSP 标准标记库(JSTL)是 JSP 1.2 定制标记库集,这些标记库实现大量服务器端 Java 应用程序常用的基本功能。通过为典型表示层任务(如数据格式化和迭代或条件内容)提供标准实现,JSTL 使 JSP 作者可以专注于特定于应用程序的开发需求,而不是为这些通用操作“另起炉灶”。

当然,您可以使用 JSP 脚本编制元素(scriptlet、表达式和声明)来实现此类任务。例如,可以使用三个 scriptlet 实现条件内容,清单 1 中着重显示了这三个 scriptlet。但是,因为脚本编制元素依赖于在页面中嵌入程序源代码(通常是 Java 代码),所以对于使用这些脚本编制元素的 JSP 页面,其软件维护任务的复杂度大大增加了。例如,清单 1 中的 scriptlet 示例严格地依赖于花括号的正确匹配。如果不经意间引入了一个语法错误,则条件内容中的嵌套其它 scriptlet 可能会造成严重破坏,并且在 JSP 容器编译该页面时,要使所产生的错误信息有意义可能会很困难。


清单 1. 通过 scriptlet 实现条件内容
<% if (user.getRole() == "member")) { %>
    <p>Welcome, member!</p>
<% } else { %>
    <p>Welcome, guest!</p>
<% } %>

修正此类问题通常需要相当丰富的编程经验。尽管通常会由十分精通页面布局和图形设计的设计人员来开发和维护 JSP,但是同一页面中的脚本编制元素出现问题时,需要程序员的介入。这种状况将单个文件中代码的责任分担给多人,因而使得开发、调试和增强此类 JSP 页面成为很麻烦的任务。通过将常用功能包装到定制标记库的标准集合中,JSTL 使 JSP 作者可以减少对编制脚本元素的需求,甚至可以不需要它们,并避免了相关的维护成本。





回页首


JSTL 1.0

JSTL 1.0 发布于 2002 年 6 月,由四个定制标记库( coreformatxmlsql )和一对通用标记库验证器( ScriptFreeTLVPermittedTaglibsTLV )组成。 core 标记库提供了定制操作,通过限制了作用域的变量管理数据,以及执行页面内容的迭代和条件操作。它还提供了用来生成和操作 URL 的标记。顾名思义, format 标记库定义了用来格式化数据(尤其是数字和日期)的操作。它还支持使用本地化资源束进行 JSP 页面的国际化。 xml 库包含一些标记,这些标记用来操作通过 XML 表示的数据,而 sql 库定义了用来查询关系数据库的操作。

两个 JSTL 标记库验证器允许开发人员在其 JSP 应用程序中强制使用编码标准。可以配置 ScriptFreeTLV 验证器以在 JSP 页面中禁用各种类型的 JSP 脚本元素 ― scriptlet、表达式和声明。类似地, PermittedTaglibsTLV 验证器可以用来限制可能由应用程序的 JSP 页面访问的定制标记库集(包括 JSTL 标记库)。

尽管 JSTL 最终将会成为 J2EE 平台的必需组件,但目前只有少数应用程序服务器包括它。JSTL 1.0 的参考实现可作为 Apache 软件基金会(Apache Software Foundation)的 Jakarta Taglibs 项目(请参阅 参考资料)的一部分而获得。可以将该参考实现中的定制标记库合并到任何支持 JSP 1.2 和 Servlet 2.3 规范的服务器,以添加对 JSTL 的支持。





回页首


表达式语言

在 JSP 1.2 中,可以使用静态字符串或表达式(如果允许的话)指定 JSP 操作的属性。例如,在清单 2 中,对 <jsp:setProperty> 操作的 nameproperty 属性指定了静态值,而用表达式指定了其 value 属性。这个操作的效果是将请求参数的当前值赋予命名的 bean 特性。以这种形式使用的表达式被称为 请求时属性值(request-time attribute value),这是构建到 JSP 规范中的用于动态指定属性值的唯一机制。


清单 2. 合并请求时属性值的 JSP 操作
<jsp:setProperty name="user" property="timezonePref"
                 value='<%= request.getParameter("timezone") %>'/>

因为请求时属性值是用表达式指定的,所以它们往往有和其它脚本元素一样的软件维护问题。因此,JSTL 定制标记支持另一种用于指定动态属性值的机制。可以用简化的 表达式语言(EL)而不使用完整的 JSP 表达式来指定 JSTL 操作的属性值。EL 提供了一些标识符、存取器和运算符,用来检索和操作驻留在 JSP 容器中的数据。EL 在某种程度上以 EcmaScript(请参阅 参考资料)和 XML 路径语言(XML Path Language,XPath)为基础,因此页面设计人员和程序员都应该熟悉它的语法。EL 擅长寻找对象及其特性,然后对它们执行简单操作;它不是编程语言,甚至不是脚本编制语言。但是,与 JSTL 标记一起使用时,它就能使用简单而又方便的符号来表示复杂的行为。EL 表达式的格式是这样的:用美元符号($)定界,内容包括在花括号({})中,如清单 3 所示。


清单 3. 说明 EL 表达式定界符的 JSTL 操作
<c:out value="${user.firstName}"/>

此外,您可以将多个表达式与静态文本组合在一起以通过字符串并置来构造动态属性值,如清单 4 所示。单独的表达式由标识符、存取器、文字和运算符组成。标识符用来引用存储在数据中心中的数据对象。EL 有 11 个保留标识符,对应于 11 个 EL 隐式对象。假定所有其它标识符都引用 限制了作用域的变量。存取器用来检索对象的特性或集合的元素。文字表示固定的值 ― 数字、字符、字符串、布尔型或空值。运算符允许对数据和文字进行组合以及比较。


清单 4. 组合静态文本和多个 EL 表达式以指定动态属性值
<c:out value="Hello ${user.firstName} ${user.lastName}"/>





回页首


限制了作用域的变量

JSP API 通过 <jsp:useBean> 操作允许从 JSP 容器内的四个不同作用域中存储和检索数据。JSTL 通过提供用于指定和除去这些作用域中的对象的附加操作来扩展这一能力。此外,EL 提供将这些对象作为限制了作用域的变量进行检索的内置支持。特别地,任何出现在 EL 表达式中但不对应于任何 EL 隐式对象的标识符,都被自动假定为引用存储在四个 JSP 作用域的其中某个中的对象,这四个作用域是:

  • 页面作用域
  • 请求作用域
  • 会话作用域
  • 应用程序作用域

您可能还记得,只有在为特定请求处理页面期间才能检索存储在该页面作用域中的对象。如果对象是存储在请求作用域中的,可以在处理所有参与处理某请求的页面期间检索这些对象(譬如在对某个请求的处理中遇到了一个或多个 <jsp:include><jsp:forward> 操作)。如果对象是存储在会话作用域中的,则在与 Web 应用程序的交互式会话期间,可以由用户访问的任何页面检索它(即,直到与该用户交互相关联的 HttpSession 对象无效为止)。可以由任何用户从任何页面访问存储在应用程序作用域中的对象,直到卸载 Web 应用程序本身为止(通常是由于关闭 JSP 容器所致)。

通过将字符串映射为期望作用域中的对象来将对象存储到该作用域。然后,就可以通过提供相同字符串来从该作用域检索该对象。在作用域的映射中查找字符串,并返回被映射的对象。在 Servlet API 中,将此类对象称为相应作用域的 属性。但是,在 EL 的上下文中,也将与属性相关联的字符串看作变量的名称,该变量通过属性映射的方式获得特定的值。

在 EL 中,与隐式对象无关联的标识符被认为是存储在四个 JSP 作用域中的名称对象。首先对页面作用域检查是否存在这样的标识符,其次对请求作用域、然后对会话作用域、最后对应用程序作用域依次进行这样的检查,然后测试该标识符的名称是否与存储在该作用域中的某个对象的名称匹配。第一个这样的匹配作为 EL 标识符的值被返回。通过这种方法,可以将 EL 标识符看作引用限制了作用域的变量。

从更技术的方面来说,没有映射到隐式对象的标识符是用 PageContext 实例的 findAttribute() 方法求值的,该实例表示对页面的处理,在该页面上,当前正在处理用于请求的表达式。标识符的名称作为参数传递给这个方法,然后该方法依次在四个作用域中搜索具有相同名称的属性。并将所找到的第一个匹配项作为 findAttribute() 方法的值返回。如果未在这四个作用域中找到这样的属性,则返回 null

最终,限制了作用域的变量是四个 JSP 作用域的属性,这些属性具有可以用作 EL 标识符的名称。只要对限制了作用域的变量赋予由字母数字组成的名称,就可以通过 JSP 中提供的用于设置属性的任何机制来创建它们。这包括内置的 <jsp:useBean> 操作,以及由 Servlet API 中的几个类定义的 setAttribute() 方法。此外,四个 JSTL 库中定义的许多定制标记本身就能够设置作为限制了作用域的变量使用的属性值。





回页首


隐式对象

表 1 中列出了 11 个 EL 隐式对象的标识符。不要将这些对象与 JSP 隐式对象(一共只有九个)混淆,其中只有一个对象是它们所共有的。

表 1. EL 隐式对象

类别 标识符 描述
JSP pageContext PageContext 实例对应于当前页面的处理
作用域 pageScope 与页面作用域属性的名称和值相关联的 Map
requestScope 与请求作用域属性的名称和值相关联的 Map
sessionScope 与会话作用域属性的名称和值相关联的 Map
applicationScope 与应用程序作用域属性的名称和值相关联的 Map
请求参数 param 按名称存储请求参数的主要值的 Map
paramValues 将请求参数的所有值作为 String 数组存储的 Map
请求头 header 按名称存储请求头主要值的 Map
headerValues 将请求头的所有值作为 String 数组存储的 Map
Cookie cookie 按名称存储请求附带的 cookie 的 Map
初始化参数 initParam 按名称存储 Web 应用程序上下文初始化参数的 Map

尽管 JSP 和 EL 隐式对象中只有一个公共对象( pageContext ),但通过 EL 也可以访问其它 JSP 隐式对象。原因是 pageContext 拥有访问所有其它八个 JSP 隐式对象的特性。实际上,这是将它包括在 EL 隐式对象中的主要理由。

其余所有 EL 隐式对象都是映射,可以用来查找对应于名称的对象。前四个映射表示先前讨论的各种属性作用域。可以用它们来查找特定作用域中的标识符,而不用依赖于 EL 在缺省情况下使用的顺序查找过程。

接下来的四个映射用来获取请求参数和请求头的值。因为 HTTP 协议允许请求参数和请求头具有多个值,所以它们各有一对映射。每对中的第一个映射返回请求参数或头的主要值,通常是恰巧在实际请求中首先指定的那个值。每对中第二个映射允许检索参数或头的所有值。这些映射中的键是参数或头的名称,但这些值是 String 对象的数组,其中的每个元素都是单一参数值或头值。

cookie 隐式对象提供了对由请求设置的 cookie 名称的访问。这个对象将所有与请求相关联的 cookie 名称映射到表示那些 cookie 特性的 Cookie 对象。

最后一个 EL 隐式对象 initParam 是一个映射,它储存与 Web 应用程序相关联的所有上下文的初始化参数的名称和值。初始化参数是通过 web.xml 部署描述符文件指定的,该文件位于应用程序的 WEB-INF 目录中。





回页首


存取器

因为 EL 标识符是作为隐式对象或限制了作用域的变量(通过属性来实现)解析的,因此有必要将它们转换成 Java 对象。EL 可以自动包装和解包其相应的 Java 类中的基本类型(例如,可以在后台将 int 强制转换成 Integer 类,反之亦可),但大多数的标识符将成为指向完整的 Java 对象的指针。

结果是,对这些对象的特性或(在对象是数组和集合的情况下)对其元素的访问通常是令人满意的。就为了实现这种用途,EL 提供了两种不同的存取器(点运算符( . )和方括号运算符( [] )),也支持通过 EL 操作特性和元素。

点运算符通常用于访问对象的特性。例如,在表达式 ${user.firstName} 中,使用点运算符来访问 user 标识符所引用对象的名为 firstName 的特性。EL 使用 Java bean 约定访问对象特性,因此必须定义这个特性的 getter 方法(通常是名为 getFirstName() 的方法),以便表达式正确求值。当被访问的特性本身是对象时,可以递归地应用点运算符。例如,如果我们虚构的 user 对象有一个实现为 Java 对象的 address 特性,那么也可以用点运算符来访问这个对象的特性。例如,表达式 ${user.address.city} 将会返回这个地址对象嵌套的 city 特性。

方括号运算符用来检索数组和集合的元素。在数组和有序集合(也即,实现了 java.util.List 接口的集合)的情况下,把要检索的元素的下标放在方括号中。例如,表达式 ${urls[3]} 返回 urls 标识符所引用的数组或集合的第四个元素(和 Java 语言以及 JavaScript 中一样,EL 中的下标是从零开始的)。

对于实现 java.util.Map 接口的集合,方括号运算符使用关联的键查找存储在映射中的值。在方括号中指定键,并将相应的值作为表达式的值返回。例如,表达式 ${commands["dir"]} 返回与 commands 标识符所引用的 Map 中的 "dir" 键相关联的值。

对于上述两种情况,都可允许表达式出现在方括号中。对嵌套表达式求值的结果将被作为下标或键,用来检索集合或数组的适当元素。和点运算符一样,方括号运算符也可以递归应用。这使得 EL 能够从多维数组、嵌套集合或两者的任意组合中检索元素。此外,点运算符和方括号运算符还可以互操作。例如,如果数组的元素本身是对象,则可以使用方括号运算符来检索该数组的元素,并结合点运算符来检索该元素的一个特性(例如 ${urls[3].protocol} )。

假定 EL 充当指定动态属性值的简化语言,EL 存取器有一个有趣的功能(与 Java 语言的存取器不同),那就是它们在应用于 null 时不抛出异常。如果应用 EL 存取器的对象(例如, ${foo.bar}${foo["bar"]} 中的 foo 标识符)是 null ,那么应用存取器的结果也是 null 。事实证明,在大多数情况下,这是一个相当有用的行为,不久您就会了解这一点。

最后,点运算符和方括号运算符可能实现某种程度的互换。例如,也可以使用 ${user["firstName"]} 来检索 user 对象的 firstName 特性,正如可以用 ${commands.dir} 获取与 commands 映射中的 "dir" 键相关联的值一样。





回页首


运算符

EL 还可以通过使用标识符和存取器,遍历包含应用程序数据(通过限制了作用域的变量公开)或关于环境的信息(通过 EL 隐式对象)的对象层次结构。但是,只是访问这些数据,通常不足以实现许多 JSP 应用程序所需的表示逻辑。

最终,EL 还包括了几个用来操作和比较 EL 表达式所访问数据的运算符。表 2 中汇总了这些运算符。

表 2. EL 运算符

类别 运算符
算术运算符 +-*/ (或 div )和 % (或 mod
关系运算符 == (或 eq )、 != (或 ne )、 < (或 lt )、 > (或 gt )、 <= (或 le )和 >= (或 ge
逻辑运算符 && (或 and )、 || (或 or )和 ! (或 not
验证运算符 empty

算术运算符支持数值的加法、减法、乘法和除法。还提供了一个求余运算符。注:除法和求余运算符都有替代的、非符号的名称(为的是与 XPath 保持一致)。清单 5 中显示了一个演示算术运算符用法的示例表达式。对几个 EL 表达式应用算术运算符的结果是将该算术运算符应用于这些表达式返回的数值所得的结果。


清单 5. 利用算术运算符的 EL 表达式
${item.price * (1 + taxRate[user.address.zipcode])}

关系运算符允许比较数字或文本数据。比较的结果作为布尔值返回。逻辑运算符允许合并布尔值,返回新的布尔值。因此,可以将 EL 逻辑运算符应用于嵌套的关系或逻辑运算符的结果,如清单 6 所示。


清单 6. 利用关系和逻辑运算符的 EL 表达式
${(x >= min) && (x <= max)}

最后一种 EL 运算符是 empty ,它对于验证数据特别有用。 empty 运算符采用单个表达式作为其变量(也即, ${empty input} ),并返回一个布尔值,该布尔值表示对表达式求值的结果是不是“空”值。求值结果为 null 的表达式被认为是空,即无元素的集合或数组。如果参数是对长度为零的 String 求值所得的结果,则 empty 运算符也将返回 true

表 3 显示了 EL 运算符的优先级。正如清单 5 和 6 所示,可以用圆括号对表达式分组,高于普通的优先级规则。

表 3. EL 运算符优先级(自顶到底,从左到右)

[] , .
()
unary -not!empty
*/div%mod
+ 、binary -
() <</code>><=>=ltgtlege
==!=eqne
&&and
||or





回页首


文字

在 EL 表达式中,数字、字符串、布尔值和 null 都可以被指定为文字值。字符串可以用单引号或双引号定界。布尔值被指定为 truefalse





回页首


Taglib 伪指令

正如我们先前讨论的,JSTL 1.0 包括四个定制标记库。为了演示 JSTL 标记和表达式语言的交互,我们将研究几个来自 JSTL core 库的标记。和使用任何 JSP 定制标记库一样,必须在您想要使用这个库标记的任何页面中包括 taglib 伪指令。清单 7 显示了用于这个特定库的伪指令。


清单 7. 用于 JSTL core 库 EL 版本的 taglib 伪指令
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

实际上,对应于 JSTL core 库的 taglib 伪指令有两种,因为在 JSTL 1.0 中,EL 是可选的。所有四个 JSTL 1.0 定制标记库都有使用 JSP 表达式(而不是 EL)指定动态属性值的备用版本。因为这些备用库依赖于 JSP 的更传统的请求时属性值,所以它们被称为 RT库,而那些使用表达式语言的则被称为 EL 库。开发人员用不同的 taglib 伪指令来区分每个库的这两个版本。清单 8 显示了使用 core 库的 RT 版本的伪指令。但是,由于现在我们讨论的重点是 EL,所以首先需要这些伪指令。


清单 8. 用于 JSTL core 库 RT 版本的 taglib 伪指令
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c_rt" %>





回页首


变量标记

我们首先要考虑的 JSTL 定制标记是 <c:set> 操作。正如已经说明的,限制了作用域的变量在 JSTL 中起关键作用, <c:set> 操作提供基于标记的机制来创建和设置限制了作用域的变量。清单 9 中显示了该操作的语法,其中 var 属性指定了限制了作用域的变量的名称, scope 属性表明了该变量驻留在哪个作用域中, value 属性指定了分配给该变量的值。如果指定变量已经存在,则简单地将所指明的值赋给它。如果不存在,则创建新的限制了作用域的变量,并用该值初始化这个变量。


清单 9. <c:set> 操作的语法
<c:set var="
        name" scope="
        scope" value="
        expression"/>

      

scope 属性是可选的,其缺省值是 page

清单 10 中显示了 <c:set> 的两个示例。在第一个示例中,将会话作用域变量设置成 String 值。在第二个示例中,用表达式来设置数值:将页面作用域内名为 square 的变量赋值为名为 x 的请求参数的值的平方。


清单 10. <c:set> 操作示例
<c:set var="timezone" scope="session" value="CST"/>
<c:set var="square" value="${param['x'] * param['x']}"/>

您还可以将限制了作用域的变量的值指定为 <c:set> 操作的主体内容,而不是使用属性。使用这种方法,您可以重新编写清单 10 中的第一个示例,如清单 11 所示。此外,正如我们马上可以看到的, <c:set> 标记的主体内容本身也可以使用定制标记。 <c:set> 主体内生成的所有内容都将作为一个 String 值赋给指定变量。


清单 11. 通过主体内容指定 <c:set> 操作的值
<c:set var="timezone" scope="session">CST</c:set>

JSTL core 库包含第二个用于管理限制了作用域的变量的标记 ― <c:remove> 。顾名思义, <c:remove> 操作是用来删除限制了作用域的变量的,它获取两个属性。 var 属性指定待删除变量的名称, scope 属性是可选的,它表示待删除变量来自哪个作用域,缺省为 page ,如清单 12 所示。

清单 12. <c:remove> 操作示例
<c:remove var="timezone" scope="session"/>





回页首


输出

尽管 <c:set> 操作允许将表达式结果赋给限制了作用域的变量,但开发人员通常会希望只显示表达式的值,而不存储它。JSTL <c:out> 定制标记承担这一任务,其语法如清单 13 所示。该标记对由其 value 属性指定的表达式进行求值,然后打印结果。如果指定了可选属性 default ,那么,在对 value 属性的表达式求值所得结果为 null 或空 String 的情况下, <c:out> 将打印其值。


清单 13. <c:out> 操作的语法
<c:out value="
        expression" default="
        expression" escapeXml="
        boolean"/>

      

escapeXml 属性也是可选的。它控制当用 <c:out> 标记输出诸如“<”、“>”和“&”之类的字符(在 HTML 和 XML 中具有特殊意义)时是否应该进行转义。如果将 escapeXml 设置为 true,则会自动将这些字符转换成相应的 XML 实体(此处提到的字符分别转换成 <>& )。

例如,假定有一个名为 user 的会话作用域变量,它是一个类的实例,该类为用户定义了两个特性: usernamecompany 。每当用户访问站点时,这个对象被自动分配给会话,但直到用户实际登录后,才会设置这两个特性。假定是这种方案,请考虑清单 14 中的 JSP 片段。在用户登录之后,这个片段将显示单词“Hello”,其后是他/她的用户名和一个惊叹号。但是,在用户登录之前,由这个片段生成的内容则是短语“Hello Guest!”。在这种情况下,因为 username 特性还有待初始化,所以 <c:out> 标记将转而打印出 default 属性的值(即字符串“Guest”)。


清单 14. 带缺省内容的 <c:out> 操作示例
Hello <c:out value="${user.username}" default=="Guest"/>!

接下来,考虑清单 15,它使用了 <c:out> 标记的 escapeXml 属性。如果在这种情况下已经将 company 特性设置成 Java String"Flynn & Sons" ,那么,实际上该操作生成的内容将是 Flynn & Sons 。如果这个操作是生成 HTML 或 XML 内容的 JSP 页面的一部分,那么,这个字符串中间的“&”符号最终可能被解释为 HTML 或 XML 控制字符,从而妨碍了对该内容的显示或解析。但是,如果将 escapeXml 属性值设置成 true ,则所生成的内容将是 Flynn & Sons 。浏览器或解析器不会因在解释时遇到这种内容而出问题。假定 HTML 和 XML 是 JSP 应用程序中最常见的内容类型,所以 escapeXml 属性的缺省值是 true 就不足为奇了。


清单 15. 禁用转义的 <c:out> 操作示例
<c:out value="${user.company}" escapeXml=="false"/>





回页首


用缺省值设置变量

除了简化动态数据的显示之外,当通过 <c:set> 设置变量值时, <c:out> 指定缺省值的能力也很有用。正如 清单 11 所示,用来赋给限制了作用域的变量的值可以指定为 <c:set> 标记的主体内容,也可以通过其值属性来指定。通过将 <c:out> 操作嵌套在 <c:set> 标记的主体内容中,变量赋值就可以利用其缺省值能力。

清单 16 中说明了这种方法。外部 <c:set> 标记

分享到:
评论

相关推荐

    WPF框架在MES系统中的应用:涵盖AGV调度、多线程、数据库及工业组态技术

    内容概要:本文详细介绍了基于WPF框架构建MES(制造执行系统)的经验和技术要点。主要内容包括:使用C#和WPF进行AGV(自动导引车)调度的多线程编程,采用Entity Framework和Dapper进行数据库操作,以及通过TCP/IP Socket和OPC UA协议实现工业组态和数据通信。此外,还探讨了Excel数据导出、PLC通信、路径规划、缓存机制等具体应用场景的技术实现。 适合人群:对WPF框架、MES系统开发感兴趣的软件工程师,尤其是那些希望深入了解工业自动化领域的开发者。 使用场景及目标:适用于需要快速开发高效稳定的MES系统的团队。主要目标是提高生产效率,优化资源配置,增强系统的实时性和稳定性。文中提供的代码片段和实践经验可以帮助开发者更好地理解和解决实际开发中遇到的问题。 其他说明:文章不仅提供了详细的代码示例,还分享了许多实用的开发技巧和优化建议,如多线程处理、异步编程、内存管理和UI更新等。对于想要深入研究WPF框架及其在工业自动化领域应用的人来说,是一份宝贵的参考资料。

    3dmax插件020-一键橱柜.ms

    3dmax插件

    西门子Smart200 PLC与威伦触摸屏三轴螺丝机控制系统解析及应用

    内容概要:本文详细介绍了基于西门子Smart200 PLC和威伦触摸屏的三轴螺丝机控制系统。首先,阐述了系统的硬件配置,包括PLC型号、步进驱动器和触摸屏的选择。接着,深入讲解了核心控制流程,如原点回归、点动控制和任意坐标定位的具体实现方法。文中还展示了如何利用PLC自带的高速脉冲输出进行精确的运动控制,以及如何通过触摸屏实现坐标管理和实时监控。此外,文章分享了一些实用技巧,如状态机架构的应用、运动控制框架的设计思路和常见问题的解决方案。 适合人群:自动化控制领域的工程师和技术人员,尤其是对PLC编程和运动控制感兴趣的初学者和有一定经验的研发人员。 使用场景及目标:适用于工业自动化生产线中需要精密定位和控制的设备开发,如螺丝机、贴标机、点胶机等。目标是帮助读者掌握PLC编程技巧,提高运动控制系统的稳定性和效率。 其他说明:文中提供了详细的代码示例和调试建议,有助于读者快速理解和应用相关技术。同时,强调了系统设计中的注意事项,如脉冲当量计算、机械结构优化等,确保系统的可靠运行。

    宣宇-美团万亿级对象存储挑战和实践探索.pdf

    Con北京站聚焦技术落地与前沿趋势,核心方向包括: ​​AI工程化​​:端侧推理、RAG增强、多模态生成成为主流; ​​云原生深水区​​:混合云治理、湖仓一体架构、可观测性技术持续迭代; ​​安全与效能​​:大模型安全防御、研发流程标准化、平台工程价值凸显; ​​行业融合​​:物流、金融、社交等领域的技术跨界创新案例丰富。 大会为开发者提供了从理论到实践的全景视角,推动技术向生产力转化。

    电动汽车内置式永磁同步电机(MTPA/MTPV)查表控制算法及自动生成程序

    内容概要:本文详细介绍了用于电动汽车内置式永磁同步电机(IPMSM)的基于查询表的矢量控制算法及其自动生成程序。文章首先解释了IPMSM的凸极特性和MTPA(最大转矩每安培)、MTPV(最大功率每伏特)之间的关系,强调了电流分配表在两者间平滑切换的重要性。随后展示了核心代码结构,包括遍历转速-转矩工作点、求解最优dq轴电流、电压电流约束检查以及弱磁补偿策略。此外,文章还讨论了数据输出方式,提供了C语言二维数组和Excel两种格式,并分享了一些实战经验和常见问题解决方法。最后提到了弱磁仿真的重要性,特别是在应对电池电压波动时的表现。 适合人群:从事电动汽车电机控制系统开发的技术人员,尤其是熟悉MATLAB编程并有一定电机控制背景的研发人员。 使用场景及目标:适用于需要高效生成IPMSM电流参考值表的工程项目,旨在提高电机控制系统的性能和稳定性,减少手动计算带来的错误和时间成本。 其他说明:文中提供的MATLAB源码已开源,可在GitHub上获取。同时,作者提醒使用者根据实际情况调整电机参数,以确保生成的查表能够正确应用于具体项目。

    信号处理领域中小波降噪、小波包降噪与滤波降噪的Python实现及应用场景

    内容概要:本文详细介绍了三种常用的信号降噪方法:滤波降噪、小波降噪和小波包降噪。滤波降噪通过设计滤波器来分离信号和噪声,适用于频率特性明确的噪声。小波降噪基于小波变换,能够自适应地捕捉信号的局部特征,尤其适合非平稳信号。小波包降噪则进一步细化了信号的频率分解,提供了更好的降噪效果,尤其在处理复杂信号时表现出色。文中通过Python代码展示了每种方法的具体实现,并进行了效果对比。 适用人群:从事信号处理领域的研究人员和技术人员,以及对信号降噪感兴趣的开发者。 使用场景及目标:① 对于频率特性明确的噪声,可以选择滤波降噪;② 处理非平稳信号时,推荐使用小波降噪;③ 在追求极致降噪效果,特别是面对复杂信号时,优先考虑小波包降噪。 其他说明:文中提供的Python代码可以帮助读者更好地理解和实践这三种降噪方法。同时,强调了在实际应用中需要根据具体的信号特点和需求选择最适合的降噪方法。

    李志伟-端侧大模型的安全建设:如何在算力与保障之间找到平衡.pdf

    Con北京站聚焦技术落地与前沿趋势,核心方向包括: ​​AI工程化​​:端侧推理、RAG增强、多模态生成成为主流; ​​云原生深水区​​:混合云治理、湖仓一体架构、可观测性技术持续迭代; ​​安全与效能​​:大模型安全防御、研发流程标准化、平台工程价值凸显; ​​行业融合​​:物流、金融、社交等领域的技术跨界创新案例丰富。 大会为开发者提供了从理论到实践的全景视角,推动技术向生产力转化。

    三菱FX系列PLC模拟量输入输出转换FB功能块设计与应用

    内容概要:本文详细介绍了三菱FX系列PLC的模拟量输入输出转换功能块(FB)的设计与应用。作者将常见的模拟量处理逻辑封装成即插即用的功能块,极大提高了开发效率。文中详细解释了功能块的接口设计、核心转换逻辑、量程适配方法以及抗干扰措施。同时,提供了多个实际项目的应用案例,如注塑机温度控制、真空炉控制等,展示了功能块的稳定性和易用性。 适合人群:从事工业自动化控制系统的工程师和技术人员,特别是对三菱PLC有一定了解的从业者。 使用场景及目标:适用于需要快速实现模拟量处理的工程项目,如温度、压力、流量等物理量的测量与控制。主要目标是提高开发效率,减少重复劳动,确保系统稳定可靠。 其他说明:文中提到的功能块不仅简化了编程流程,还增加了错误检测和抗干扰能力,使得即使是新手也能轻松应对复杂的模拟量处理任务。此外,功能块支持多种量程和硬件版本,适应性强。

    基于深度学习的口罩佩戴检测,Keras-YOLOv3 实现.zip

    基于深度学习的系统

    前端开发_浏览器扩展_Vite框架_Vue3_模板_适配_M_1744167663.zip

    前端开发_浏览器扩展_Vite框架_Vue3_模板_适配_M_1744167663.zip

    【计算机专业】求职面试全流程解析:技术题型、系统设计与行为面试技巧及资源推荐

    内容概要:本文详细介绍了计算机专业求职面试的内容与技巧,旨在帮助求职者高效准备。面经内容涵盖技术面试、系统设计面试、行为面试和其他类型面试。技术面试包括算法与数据结构、计算机基础、编程语言与框架等高频考点;系统设计面试强调高并发、高可用等设计目标,涉及短链系统、分布式缓存等典型题目;行为面试关注项目中的挑战解决、团队协作等问题,提倡使用STAR法则作答。技巧分享方面,技术面试准备建议刷题、复习基础知识;系统设计采用分层设计法,推荐相关书籍和资源;行为面试注重项目包装,强调量化成果和技术术语的使用;面试实战技巧包括良好沟通、拆解难题等。此外,文章还提供了资源与工具推荐、避坑指南以及不同公司面试侧重点分析,并指出短期冲刺和长期积累对提升面试通过率的重要性。; 适合人群:计算机专业学生和从业者,尤其是有求职需求的人员。; 使用场景及目标:①帮助求职者了解面试常见题型与考察点,进行有针对性的准备;②提供有效的面试技巧,提高求职成功率;③根据不同公司特点调整准备方向,增强竞争力。; 其他说明:通过系统化准备和反复练习,求职者能显著提升面试通过率。技术能力决定下限,而沟通表达与思维逻辑决定上限。

    西门子博图时间加密程序块解析:1212C PLC & KTP700触摸屏应用

    内容概要:本文详细介绍了西门子博图时间加密程序块的应用,特别是在1212C DC/DC/DC PLC和KTP700 Basic PN触摸屏中的实现。文章分为加密算法块和解密算法块两大部分,通过具体的代码示例展示了加密和解密的具体过程。加密算法采用了循环右移和异或运算,确保了加密的高效性和安全性。解密则通过逆向操作恢复原始时间数据。此外,文中还讨论了密钥更新策略、时间戳精度、硬件时钟同步等问题,并提供了实际应用中的注意事项和优化建议。 适合人群:从事工业自动化控制系统的工程师和技术人员,尤其是熟悉西门子PLC和触摸屏编程的人员。 使用场景及目标:① 提供一种可靠的时间加密方法,保护关键时间数据和逻辑不被轻易破解;② 增强项目的保密性和安全性;③ 提供实际项目中的应用案例和优化建议,便于快速移植到其他项目中。 其他说明:文章强调了加密和解密过程的透明度,使得维护人员能够直观理解加密逻辑,有助于快速定位和解决问题。同时,文中提到的一些技巧如动态密钥生成、时间戳精度调整等,也为实际应用提供了宝贵的实践经验。

    三相步进电机开环矢量控制与SVPWM实现的技术解析及应用场景

    内容概要:本文详细介绍了三相步进电机的开环矢量控制方案及其源码实现,尤其是坐标变换(Clarke变换和Park变换)和空间矢量脉宽调制(SVPWM)的具体实现方法。文中不仅解释了理论背景,还提供了具体的代码片段,展示了如何通过坐标变换将三相电流映射到旋转坐标系,并通过SVPWM生成合适的PWM信号来控制电机。此外,文章还讨论了一些实际应用中的技巧和注意事项,如角度生成策略、扇区判断优化以及启动时的斜坡函数设置。 适合人群:从事电机控制领域的工程师和技术爱好者,尤其是对步进电机矢量控制感兴趣的初学者和有一定基础的研发人员。 使用场景及目标:适用于需要提高步进电机控制精度和响应速度的场合,如工业自动化设备、搬运机械手等。目标是通过理解和应用开环矢量控制技术,使步进电机表现出接近伺服电机的性能,同时降低成本和复杂度。 其他说明:文章强调了在资源有限的嵌入式系统中进行优化的重要性,如使用查表法替代实时计算、利用位运算提高效率等。此外,还提到了一些调试技巧,如通过示波器观察波形、调整角度积分环节等,有助于解决实际应用中的常见问题。

    基于STM32F031的FOC有感电机控制代码解析与应用

    内容概要:本文详细介绍了基于STM32F031的FOC有感电机控制代码的功能特点及其应用场景。代码不仅涵盖了原理图、PCB设计,还包括详细的程序代码和注释。主要功能包括转把控制、刹车、助力、欠压检测、巡航、铁塔王通讯、一键通、隐形限速、霍尔修复和故障显示等。文中还展示了多个关键代码片段,如ADC采样、PWM生成、霍尔信号处理、故障检测和通讯协议处理等,强调了代码的稳定性和实用性。 适合人群:从事电机控制领域的工程师和技术爱好者,尤其是对FOC算法感兴趣的开发者。 使用场景及目标:适用于电动自行车、滑板车等需要高效电机控制的应用场景。目标是帮助开发者理解和应用成熟的FOC控制代码,提升产品的稳定性和功能性。 其他说明:代码经过量产验证,具有较高的可靠性和灵活性,能够适配多种国产芯片平台。文中还提供了丰富的实战经验和优化技巧,有助于解决实际开发中的常见问题。

    浅析电子商务环境下物流的特点.docx

    浅析电子商务环境下物流的特点.docx

    曾臻-Al+Vision+Shape+the+Future.pdf

    Con北京站聚焦技术落地与前沿趋势,核心方向包括: ​​AI工程化​​:端侧推理、RAG增强、多模态生成成为主流; ​​云原生深水区​​:混合云治理、湖仓一体架构、可观测性技术持续迭代; ​​安全与效能​​:大模型安全防御、研发流程标准化、平台工程价值凸显; ​​行业融合​​:物流、金融、社交等领域的技术跨界创新案例丰富。 大会为开发者提供了从理论到实践的全景视角,推动技术向生产力转化。

    欧姆龙FH系列机器视觉系统的高效开发与应用:加速工业自动化检测项目落地

    内容概要:本文详细介绍了欧姆龙FH系列机器视觉系统的独特优势及其应用场景。FH系列通过提供强大的仿真软件、优化的PLC通信接口以及先进的深度学习模块,显著提高了工业视觉项目的开发效率和准确性。具体而言,FH系列的仿真环境允许开发者在虚拟环境中调试算法,减少了现场调试的时间;其PLC通信接口支持多种工业协议并实现了自动寄存器映射,降低了设备工程师的沟通成本;深度学习模块则提供了预训练模型和自动ROI聚焦等功能,大幅提升了缺陷检测的精度和速度。此外,FH系列还集成了智能标定向导和动态标定功能,使得尺寸测量更加精确和便捷。 适用人群:从事工业自动化、机器视觉、智能制造等领域的一线工程师和技术管理人员。 使用场景及目标:适用于需要快速开发和部署视觉检测系统的工业生产线,尤其是汽车制造、电子产品、制药等行业。主要目标是缩短项目周期、提高检测精度、降低开发难度。 其他说明:相比于传统的视觉检测工具如Halcon,FH系列以其易用性和高效性脱颖而出,成为现代工业视觉项目的首选解决方案。文中提到的具体案例展示了FH系列在实际生产中的卓越表现,证明了其在提升工作效率方面的巨大潜力。

    高效机房控制系统:基于先进算法的多维节能优化方案

    内容概要:本文详细介绍了高效机房控制系统的先进控制算法及其多维节能优化方案。系统通过predictive_optimizer模块进行智能决策,优化冷水机组的组合和负荷分配,采用预测负荷、设备损耗和切换成本等多因素评估,实现最优能耗管理。此外,系统还利用三维建模和可视化工具,如PyQt和Three.js,提供直观的设备管理和故障排查。系统不仅能在常规情况下节省大量能源,还能在异常工况下迅速响应,确保稳定运行。文中提到的具体应用案例展示了该系统在多个项目的显著节能效果,如深圳项目中实现8%的能耗降低,以及某数据中心年能耗减少23%。 适合人群:从事机房管理、暖通空调系统设计与维护的技术人员,对工业自动化和节能优化感兴趣的工程师。 使用场景及目标:适用于新建或改造的大型数据中心、医院、工厂等场所,旨在提高能源利用效率,降低运营成本,增强系统的可靠性和灵活性。 其他说明:系统的核心优势在于其强大的自适应能力和丰富的实战经验,能够根据不同应用场景灵活调整控制策略,实现持续节能。

    基于Matlab的分位数长短期记忆网络(QRLSTM)用于时序数据预测与不确定性评估

    内容概要:本文详细介绍了如何利用Matlab实现分位数长短期记忆网络(QRLSTM)进行时序数据分析与预测。相较于传统LSTM仅提供单点预测,QRLSTM能够同时输出多个分位数的预测结果,从而提供预测不确定性的量化评估。文中首先展示了如何生成带有噪声的正弦波数据作为示例,并进行了数据预处理步骤,包括标准化和滑窗处理。接着,文章深入探讨了QRLSTM的网络架构设计,特别是自定义分位数损失层的实现细节。训练过程中采用了Adam优化器,并设置了学习率衰减机制以提高收敛速度。为了确保预测的有效性和稳定性,作者还分享了一些实用技巧,如GPU加速、梯度裁剪以及早停策略的应用。最终,通过对比实验验证了QRLSTM在处理具有异方差性的时序数据(如风速预测)方面的优越性能。 适合人群:对机器学习尤其是深度学习感兴趣的科研工作者和技术开发者,熟悉Matlab编程环境,希望深入了解时序数据预测及其不确定性估计的人群。 使用场景及目标:适用于需要对时序数据进行精准预测并且关心预测结果可靠性的应用场景,例如金融市场的价格走势预测、气象预报、能源消耗量预测等领域。主要目标是帮助用户掌握QRLSTM的工作原理及其优势,能够在实际项目中应用这一先进技术。 其他说明:文章提供了完整的代码片段供读者参考实践,同时也指出了在实现过程中可能会遇到的问题及相应的解决方案。此外,还提到了一些潜在的研究方向,如将QRLSTM与其他模型组合使用以进一步提升预测精度。

    【智能车竞赛】智能车竞赛技术综述与创新项目设想:关键技术及应用领域探索

    内容概要:本文全面介绍了智能车竞赛的背景、意义、发展历程、竞赛规则与组别设置。通过多个竞赛案例,展示了智能车竞赛的技术水平,深入探讨了智能车开发的关键技术,包括传感器技术、控制算法、路径规划、电机驱动等,并分析了这些技术在智能车竞赛中的应用。最后,提出了基于智能车开发技术的几个创新项目设想,旨在推动智能车技术的进一步发展与应用。; 适合人群:对智能车竞赛感兴趣的学生、教师、科研人员及智能车技术爱好者。; 使用场景及目标:①了解智能车竞赛的历史、规则和发展趋势;②掌握智能车开发的关键技术和应用实例;③探索智能车技术在未来物流配送、环境监测、农业作业等领域的创新应用。; 其他说明:本文不仅详细介绍了智能车竞赛的相关知识,还通过具体案例和技术探讨,为读者提供了深入了解智能车技术的机会。对于希望参与智能车竞赛或从事相关技术研发的人员来说,本文是一份宝贵的参考资料。阅读时应重点关注各个技术环节的具体实现方法及其在实际竞赛中的应用效果。

Global site tag (gtag.js) - Google Analytics