Java101账号_数据绑定101

Web application (1.4 MB)中获得。

参与者

绑定UI到数据的过程需要三个参与者--业务对象/数据、NetUI JSP标签库、表达式语言。业务对象中含有需要绑定到JSP页面的数据。JSP标签以特定视图(只读或可更新)的方式在Web浏览器中绘制数据,而表达式语言则将两者粘合在一起,从而可以通过JSP标签引用业务对象的属性。借助三个参与者的实例,Workshop开发人员可以用灵活且优雅的方式创建用于显示、更新、及创建数据的用户界面。

整篇文章我们都会用到一个定义了字段和属性的JavaBean,属性更适合说明数据是如何绑定到不同类型之上的。该表单的一部分如下;其中定义了一个公共属性name 和一个公共字段eMail。可以把该类看作一个针对简单Web页面的业务对象,该Web页面演示了如何绑定到表单的属性。

public class Customer

{

public String eMail = "";

private String name;

public String getName()

{

return this.name;

}

. . .

}

[binding/Controller.jpf]

URL 也是该bean的一个属性。除此之外,同一页面流中还定义了一个LocationInfo 类,它暴露了可以进行数据绑定的复杂类型。

为了更快将读者引进门,我们假定代表用户"Dave Smith"的Customer对象已经存在,并且可以通过String类型的关键字"customer"在request的属性映射中进行访问。这个Customer的姓名可以借助JSP的NetUI标签显示在Web页中。

Customer Name:

[binding/simple.jsp]

它在Workshop JSP 设计器中显示如下:

Customer Name: {request.customer.name}

并生成如下的HTML输出:

Customer Name: John Smith

下面我们将从整体上更进一步分析这个例子和表达式。

表达式语言

表达式语言使得Workshop开发人员能够使用一种简单的语法在JSP页面中引用业务对象的数据。通常,一个表达式引用业务对象上的一个或一系列属性,从而可以唯一标识JSP标签所绑定的数据。在以上例子中,表达式{request.customer.name}引用Customer JavaBean中的name 属性,保存在request中的该JavaBean被称作"customer"。

在JSP标签属性中,表达式分别以'{' 和'}'作为开始和结束标记。标签探测一个属性是否是表达式、或者其中是否包含表达式,从而对属性进行求值。

一个表达式含有两个独立的部分--数据绑定上下文:在其中进行表达式求值;属性:它是表达式求值返回的结果。在表达式{request.customer.name}中, request是绑定上下文,它引用JSP页面request的属性映射。表达式剩下的部分用来引用唯一的对象属性。"customer"标识符用来在request的属性映射中查找相关对象,name标识符用来获取Customer 对象上的JavaBean 属性name。从功能上讲,该表达式等同于以下语句:

String name = ((Customer)request.getAttribute("customer")).getName();

同样是引用相同的数据,表达式语法更为简单。

除了request 上下文,还可以在其它数据绑定上下文中求值表达式,这些上下文用来访问Web应用和页面流环境的不同部分。绑定上下文还可以引用其它资源,比如通过url 或 bundle 上下文,它可以分别引用URL参数或资源包中的国际化字符串。完整的上下文及其引用对象/资源的列表如下:

上下文名称

上下文引用的对象

actionForm

和当前NetUI 表单标签相关的动作表单

pageFlow

某个用户的当前页面流

globalApp

webapp中某个用户的Global.app

bundle

用于引用声明或隐含的资源包属性

pageContext

JSP 页面的PageContext属性映射

request

request的属性映射

session

session的属性映射

application

servlet上下文的属性映射

url

用于当前请求的URL 查询参数

container

当使用重复标签绘制某个数据集时,复杂数据绑定标签用它来访问当前条目

现在进一步讨论上表中提到的一些上下文。

同样是使用表达式,仍然存在多种不同方法来引用同一对象的同一属性。例如,在我们的例子中,以下几个表达式都是等价的:

- request["customer"]["name"]

- request.customer.name

- request["customer"].name

- request.customer["name"]

[binding/index.jsp]

而且,表达式既可以访问字段,也可以访问属性,这些属性返回任意基本类型或Java Object类型,也可以返回它们的数组、列表和映射类型。一般说来,属性命名遵循JavaBean属性的setter和getter方法命名规范。关于暴露、命名、引用数据绑定对象属性的特殊规则将在下面进行讨论。

注意:对象的值既可以是只读的也可以是可读/写的;对象对应的值的暴露方式决定了它对于表达式仅是只读的,还是当Web浏览器向服务器提交数据时该值是可更新的。

访问属性

为了识别类暴露的可绑定数据属性,表达式语言采用了JavaBean命名规范。符合以下条件的方法可以暴露一个只读属性:

- public 访问权限

- 返回非void类型

- 无参数

- 以"get"作为名称的开头

可以使用表达式来引用数据绑定上下文中符合以上条件的任意方法。JavaBean属性的名称被包含在表达式中。例如,类中定义了一个属性:

public String getName();

[binding/index.jsp]

[binding/Controller.jpf]

在表达式中它被引用为:

{request.customer.name}

[binding/index.jsp]

[binding/index.jsp]

前提是一个Customer 对象被指定为“customer”并可以从request中得到。

在本例中,方法 getName 对应名为name的JavaBean属性;这是通过去掉“get”并将第一个字符变成小写之后得到的。一个例外是如果“get”之后的头两个字符都是大写的,JavaBean属性的名称将在表达式中保持不变。例如,属性:

public String getURL();

[binding/index.jsp]

[binding/Controller.jpf]

在表达式中被引用为:

{request.customer.URL}

[binding/index.jsp]

[binding/index.jsp]

迄今为止,以上的name 和URL 属性都是只读的,因为我们没有为它们定义setter方法,该方法可以用来更新对象的属性值。一个JavaBean的setter方法需要符合以下条件:

- 以"set"作为名称开头

- 返回void类型

- 只有一个参数,它的类型与对应getter方法的返回类型相同

前面两个属性的JavaBean setter如下:

public void setName(String name);

public void setURL(String url);

[binding/index.jsp]

[binding/Controller.jpf]

如果对象中同时存在正确定义的getter 和setter,属性就是可读/写的。这种类型的属性十分重要,因为可以从Web页面更新它们的值。

访问字段

可以通过表达式访问公共字段。上面Customer类中定义的“eMail”字段就是一个例子。公共字段总是可读/写的。Customer的email地址在Web页中可以显示为:

[binding/index.jsp]

[binding/Controller.jpf]

访问数组或列表中的元素

使用常用的[index] 语法可以引用数组或列表中的条目。如果一个属性被暴露为:

public String[] getZipArray();

[binding/Controller.jpf]

[binding/index.jsp]

那么可以通过以下表达式访问数组的第四个条目:

{request.locationInfo.zipArray[3]}

[binding/index.jsp]

[binding/index.jsp]

假定LocationInfo对象可以在request中通过关键字“locationInfo”进行访问,

如果一个属性被暴露为:

public List getZipList();

[binding/index.jsp]

[binding/Controller.jpf]

那么以下表达式将会访问列表中的第四个条目:

{request.locationInfo.zipList[3]}

[binding/index.jsp]

[binding/index.jsp]

此类表达式求值还是略有不同。如果该表达式在一个长度仅为2的String[]上被求值,因为数组的长度小于表达式的引用长度,所以将会发生错误。如果属性是列表类型,表达式将被简单地求值为null。

使用NetUI Repeater标签集可以方便地绘制数组和列表。稍候一篇dev2dev文章将会涉及该标签集以及“container”绑定上下文。

访问映射中的元素

表达式还可以采用与访问属性相同的语法来引用映射中特定键值对应的条目。例如,如果LocationInfo 类暴露了一个含有州名缩写和州名的Map,并将其定义为带有JavaBean getter方法的可绑定数据属性:

public Map getAbbrevMap();

[binding/index.jsp]

[binding/Controller.jpf]

那么,以下两个表达式都可以使用键值“CO”在映射中进行查找:

{request.locationInfo.abbrevMap.CO}

{request.locationInfo.abbrevMap["CO"]}

[binding/index.jsp]

[binding/index.jsp]

访问基本类型

采用以上任何机制暴露的数据类型可以是Java对象或基本类型。如果某个属性或字段的类型是基本类型,比如int 或 boolean ,表达式的求值结果将是基本类型的Java对象包装器。在本例中,将分别是Integer 和 Boolean。

表达式和NetUI JSP标签

在NetUI JSP标签上使用表达式、属性可以引用业务对象属性,并将数据显示在Web页面上。同一属性的显示方式取决于标签的选择。比如,绑定到NetUI label的字符串属性是只读的,而绑定到NetUI form内NetUI text box的字符串属性却是可读/写的。

目前存在三个NetUI标签库——HTML、复杂数据绑定、模板,本文不涉及后面两个。HTML标签集尽可能遵循HTML4.01规范并将自己的标签和HTML中定义的元素相互结合。例如,textBox、 checkBox、 和radioButton 标签分别显示HTML输入标签类型“text”、 “checkbox”、 和“radio”。可以在Workshop标签面板中找到这些标签。

image002.jpg

也可以在Workshop 8.1的Insert菜单中找到这些标签。

NetUI HTML 标签进一步可以分为两类——只能显示数据的标签(或称为只读的)、能够在服务器和Web浏览器之间“往返”的标签(或称为可读/写的)。可以使用诸如netui:form 内的textBox这类标签在服务器和客户端之间传递数据。关于此类标签如何绑定数据,彼此之间也存在不同。

只读NetUI标签

只读标签使用表达式绑定属性“value”来指定在页面中绘制的数据。此类标签只是简单地通过表达式从业务对象中读取数值并在Web页面上绘制,可能还会对输出结果进行格式处理。我们已经知道netui:label 标签可以在页面上绘制表达式的值,其实它也可以绘制普通文本:

[binding/index.jsp]

[binding/index.jsp]

因为label标签不是到服务器的可往返标签,所以它的value属性可以是文本和表达式的组合。例如,想要显示用反斜杠分开的客户姓名和年龄,可以这样使用label:

[binding/index.jsp]

[customerEntry/display.jsp]

每个表达式都将被求值,文本“/”将会混合到表达式结果中。

可读/写NetUI标签

第二组标签使用“dataSource”属性,它们比较特殊因为被“dataSource”属性引用的数据可以在Web浏览器和服务器之间往返。尽管dataSource属性可以绑定表达式,但该属性的value必须是一个纯粹的表达式。与label标签的value属性不同,dataSource属性不能混合文本和表达式,因为dataSource属性的value被用在两个地方:

- 绘制JSP页面的时候通过表达式读取值

- 当表单所在页面POST的时候,通过同一个表达式将值写回到业务对象中去。

采取这种方式,诸如textBox这样的标签就可以在服务器和Web浏览器之间来回传输数据。

如果在dataSource 属性中混合使用文本,属性就不是一个纯粹的表达式并将报错。因为dataSource 属性通常被用于同数据库交换数据,所以这里使用的表达式必须引用那些可以更新的数据绑定上下文,它们是actionForm、pageFlow、和 globalApp。 除此以外,所有其它绑定上下文在数据被POST到服务器时都是只读的。

一个简单例子

让我们对前面的Customer例子稍作修改并利用NetUI编写一个“Hello World”,从而形成一个实用的例子。本例中含有一个页面流simpleForm 和一个JSP。JSP定义了一个绑定到页面流中某个action的NetUI表单。当表单从浏览器中POST的时候,动作表单将被创建,提交的数据将被添加到动作表单中。接着,输入页面被刷新,刚刚在只读label中显示的信息将会显示到可编辑的文本框中。这里所说的页面流是指本文示例应用中的simpleForm。

首先我们来看看动作表单,它们负责封装那些在页面中被显示并更新的数据。该类定义了通过NetUI HTML在JSP表单标签内可编辑的属性;它暴露了唯一一个属性——message。

public static class MessageForm extends FormData

{

private String message;

public void setMessage(String message)

{

this.message = message;

}

public String getMessage()

{

return this.message;

}

}

[binding/index.jsp]

[simpleForm/Controller.jpf]

接着我们来看看JSP页面。这里的netui:form 标签用于引用在表单POST时将会执行的页面流动作。如果您对页面流不熟悉,请参阅参考材料部分的页面流参考手册。一般来说,从可读/写NetUI标签POST到服务器的更新必须在NetUI form 标签中进行。

Current message:

[binding/index.jsp]

[simpleForm/index.jsp]

JSP中有两个附加NetUI标签;其中netui:textBox 利用表达式{actionForm.message}在当前动作表单中显示message的值。最初该值以及textBox都是空的。还有一个button标签用来把表单提交到服务器。运行例子的时候,请在文本框中输入“Hello World”并按下“Submit”。

看!当表单提交到服务器时,页面流生命周期创建了接收POST数据(即本例中的message)的动作表单。因为textBox的dataSource 属性对应的表达式被映射为HTML输入标签——{actionForm.message},所以message的值被路由到该属性上。

一旦表单填充完毕,postback 动作就会执行并在页面中重新绘制相同的表单。运行结果是:表达式{actionForm.message} 现在同时指向label和textBox 中显示的“Hello World”。在文本框中输入文本并重新提交表单可以修改该值。

技巧和经验

如何访问页面流的成员属性?

页面流可以像其它类一样暴露JavaBean属性;利用表达式和pageFlow 绑定上下文可以绑定这些属性。例如,如果一个页面流用以下方法暴露属性productName:

public String getProductName()

{

return productName;

}

[binding/index.jsp]

[howdoi/Controller.jpf]

就可以通过以下表达式在JSP中进行数据绑定:

{pageFlow.productName}

[binding/index.jsp]

[howdoi/index.jsp]

你还可以绑定到页面流暴露的公共字段。

应该在页面流上暴露映射吗?

在任何可以接受POST数据的数据绑定上下文中暴露Map类型都是危险的。问题在于映射可以变得很大,这就在服务上开了一个安全漏洞:因为网页可以直接POST数据到Map,这将会导致map无限变大、消耗掉可观的服务器资源。

通过类似request这样的只读数据绑定上下文来暴露Map类型要安全很多。上面的例子中,LocationInfo对象通过abbrevMap 属性实现了这点。

如果在表单上暴露一个int 类型的属性,从页面POST出去的是什么类型?

当JSP页面POST数据到服务器时,所有的数据都以字符串形式到达。应用POST数据到页面流属性或动作表单的过程中,NetUI会设法把已经POST到底层属性或字段的字符串数据转换为原有的类型。

例如,如果动作表单暴露一个类型为int、名称为 age 的属性,并且该字段可以从NetUI表单更新,类型转换工作即是把String 类型的“42”的转换成int 类型的42。如果转换失败,失败信息将会显示在运行WebLogic的命令提示窗口中。

如何显示一个数据列表或数组?

利用NetUI复杂数据绑定标签可以绘制诸如列表、数组、映射、和行集这类的数据集。这些将在接下来的dev2dev文章中讨论。

表达式求值失败会怎样?

当JSP准备绘制时,如果一个表达式求值失败了,JSP页面上将会显示一个失败信息。假定有属性绑定的例子:

Customer Name:

[binding/index.jsp]

[binding/index.jsp]

如果request的属性映射中不包含名为“customer”的对象,那么绑定将会失败,因为name属性无法访问null对象。请尝试将例子改为:

Customer Name:

[binding/index.jsp]

[binding/index.jsp]

这样就可以知道表达式求值是如何失败的了。

Workshop 8.1 IDE如何帮我进行数据绑定?

Workshop可以用多种方式帮助JSP作者进行数据绑定,其中最重要的一种是通过数据面板。使用数据面板可以在JSP页面中创建能够显示或更新数据的NetUI标签。

例如,在Workshop中打开JSP页面howdoi/index.jsp;在页面上,数据面板显示如下:

image004.jpg

您可以看见productName属性在面板中是可用的。如果拖动它到JSP页面中,以下代码将被生成并将在页面中显示产品名称:

试着添加其它属性到页面流中并拖动它们到JSP页面中,从而生成可以显示数据的NetUI标签。

如果页面上有动作表单,它上面的属性也可以被拖动到JSP上。

结论

本文覆盖的范围很广。现在重新回顾一下,表达式语言使得NetUI JSP能够引用业务对象暴露的数据、页面流、以及数据绑定上下文暴露的其它对象和资源。表达式可以引用这些对象的属性和字段,并且NetUI HTML标签既可以用于显示数据,也可以用于从Web浏览器更新数据。

本文附带的应用程序包含多个示例,其中包括基本数据绑定规则的例子、Hello World例子、和一个创建、显示、和编辑Customer对象的复杂例子。

在以后的文章中我们还会介绍更多的内容,希望本文使您对WebLogic Workshop 8.1的从UI到数据的绑定有了初步了解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet.Applet 简单实现!~ 网页表格组件 GWT Advanced Table GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存工具 SimpleCache SimpleCache 是一个简单易用的java缓存工具,用来简化缓存代码的编写,让你摆脱单调乏味的重复工作!1. 完全透明的缓存支持,对业务代码零侵入 2. 支持使用Redis和Memcached作为后端缓存。3. 支持缓存数据分区规则的定义 4. 使用redis作缓存时,支持list类型的高级数据结构,更适合论坛帖子列表这种类型的数据 5. 支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类需求可以通过快速配置来开发。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是一个用来操作Windows注册表的 Java 类库,你可以用来对注册表信息进行读写。 GIF动画制作工具 GiftedMotion GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端 JOpenID JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JSEditor JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值