Dorado7.x 基础教程


1. 01. Dorado7.x 基础教程(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1 01. First Contact(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1.1 01. web.xml(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.1.2 02. doradohome(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.1.3 03. 运行模式(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.1.4 04. Spring上下文(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.1.5 05. 资源定位表达式(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.1.6 06. context.xml几项基本配置的简介(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.2 02. 界面开发技巧(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.2.1 01. View配置文件基本结构(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.2.2 02. 实做HelloWorld(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.2.2.1 URI与视图配置文件之间的映射关系 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.2.3 03. EL表达式(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.2.4 04. 控件的基础知识(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.2.5 05. 布局管理器(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 1.2.5.1 01. DockLayout(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 1.2.5.2 02. AnchorLayout(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 1.2.5.3 03. FormLayout(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 1.2.5.4 04. HBoxLayout和VBoxLayout(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 1.2.6 06. 实做AJAX(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 1.2.7 07. 服务定位表达式(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 1.2.8 08. 智能方法适配(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 1.2.9 09. HTML模板(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 1.2.10 10. 对象监听器(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 1.2.10.1 01. 全局监听器范例(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 1.3 03. JavaScript开发基础(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 1.3.1 01. JavaScript基础(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 1.3.2 02. 虚拟面向对象(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 1.3.3 03. 创建Dorado7对象(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 1.3.4 04. 常用技巧和API(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 1.4 04. 基于数据模型的界面开发(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 1.4.1 01. 立体数据模型(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 1.4.2 02. 实做CRUD(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 1.4.3 03. DataProvider和DataResolver(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 1.4.4 04. DataType(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 1.4.5 05. 实做主从维护界面(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 1.4.6 06. DataPath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 1.4.7 07. 数据常用操作技巧(SEFC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 01. Dorado7.x 基础教程(SEFC) 本教程适合初次接触Dorado7的人学习,通过本教程可以初步了解Dorado7的设计诉求以及实现原理,并借此掌握Dorado7中的基本概念和基本术语,例如立体数据模型,DataSet, DataPath, DataType, DataProvider, DataResolver等。另外本教程也提供了一定的范例,通过这些范例可以快速掌握Dorado中基本的页面开发技术和IDE操作技巧,包括AJAX技术交互机制,立体数据模型的应用和智能方法适配等。对于初次接触BS技术的程序员,通过这些范例的学习也能增加对JavaScript技术的了解和加深对BS系统的理解。 First Contact 界面开发技巧 JavaScript开发基础 基于数据模型的界面开发 01. First Contact(SEFC) 简介 产品定位 首先我们将Dorado7定位为展现中间件,它致力与解决展现层的中间件的开发,其核心价值有两个方面: 更好用的前端界面 更高的开发效率 从适用范围来讲我们认为,它适合基于Browser/Server架构的管理类应用,但是不太适合面向互联网的开放式站点。分析其原因主要在两个方面: 界面元素的风格-信息管理类的维护界面与面向互联网的界面元素风格存在较大的差异性 对搜索引擎的友好度-对于这种注重AJAX操作的前端开发技术本身就与搜索引擎存在不适应的情况另外Dorado7最适合采用ORM技术实现数据持久层的开发模式,它在设计之初就是为ORM考虑的,但是考虑到之前Dorado5那种JDBC类型的快速开发方式依然能满足不同类型客户的需求,在Dorado7中依然提供了基于JDBC的开发模式。 下面我们再细说Dorado的价值取向: 更好用的前端界面 丰富的界面控件 支持各种主流浏览器(IE、Chrome、Firefox、Safari、Opera等) 相比Dorado5更加Ajax化,更多的采用异步处理而不是同步处理机制,可以更好的支持异步服务端通讯,从而进一步提高界面操作的友好性。 JS、CSS的按需装载和Server端自动合并 更高的开发效率 全新的基于Eclipse的IDE。 Dorado产品一贯的特色——以XML配置简化前端界面的定义,并彻底以XML替代传统JSP 以数据模型为核心的开发模式。如:数据敏感控件,立体数据模型 遵循"约定优于配置"的设计思想,例如自动方法适配 以XML替代传统JSP的原因 原因一 基于管理类应用界面的特点,采用控件+布局管理器的界面定义模式最为高效。如Swing、SWT等,如下图的界面风格: 这种类型的界面风格有以下几个特征: 信息量大,对控件利用率的要求较高。 需很好的适应各种分辨率。 界面元素相对程式化。 原因二 有利于简化界面开发过程和降低后期维护成本。 基于HTML的开发模式页面代码冗长且不易维护。 基于HTML的开发模式对开发者的要求较高,需时刻考虑HTML代码对各种浏览器的兼容性。 特别说明 如有需要,开发者仍有多种方式回到基于HTML的开发模式下。 以数据模型为核心的开发模式 UI控件发展的两个阶段: 离散控件集型控件集——Dojo、Ext3 数据模型驱动型控件集——Dorado、Ext4 Ext的发展历程映证了数据模型驱动型控件集是更加高效的。 Dorado一贯主张将数据与表现形式分离,实现这种分离,需要几个概念 数据载体——DataSet 数据感知控件——DataGrid、TextEditor、…. 数据模型驱动型控件集的优点: 开发者日常接触的API的数量大大减少。 数据模型中提供了很多附加的功能,例如:状态管理、翻页、校验、提交等等。可以在很大程度上简化开发。 培养开发人员以更加贴近业务逻辑的角度思考问题。始终把精力放在核心的业务逻辑的实现上,而不必因为各种零散的界面特效而致思维发散。 页面代码更加集中,所以更加容易阅读和维护。大部分的页面代码会围绕数据模型展开。 当界面设计改变时,重构变得更加简单。因为数据模型几乎不需要改变,开发者需要的只是改用一些其他的数据感知控件。 项目基本结构和配置 项目基本结构如图: 下面我们详细说明相关的配置文件: web.xml doradohome 运行模式 Spring上下文 资源定位表达式 context.xml文件基本配置简介 准备工作 下载资源: http://www.bsdn.org/projects/dorado7/download 下载其中最新版本的Standard Edition 并利用 完成IDE的安装和sample-center工程的创建安装手册 学习并了解IDE操作的文档:IDE用户手册 01. web.xml(SEFC) 以下是一个标准dorado工程中web.xml的内容: com.bstek.dorado.web.servlet.SpringContextLoaderListener doradoServlet com.bstek.dorado.web.servlet.DoradoServlet 1 doradoServlet *.d doradoServlet *.dpkg doradoServlet /dorado/* http://www.bstek.com/dorado/taglib-7.0 /WEB-INF/dorado-7.0.tld SpringContextLoaderListener Dorado7将Spring作为自己比较底层的依赖包,因此在web.xml中我们可以看到由dorado提供但却以Spring命名的listener:SpringContextLoaderListener,其实SpringContextLoaderListener是继承Spring中标准的ContextLoaderListener的一个类,用于装载dorado的一些基础配置。 当用户没有自行扩展ContextLoaderListener,则我们在web.xml中使用dorado默认提供的SpringContextLoaderListener,但是如果我们的系统中已经扩展了ContextLoaderListener,那么怎么办呢? doradoServlet doradoServlet用于提供dorado引擎服务的Servlet,也可以用于Spring的MVC服务。 拦截字符串 说明 *.d dorado服务,项目中程序员接触最多的请求 *.dpkg dorado的package资源,根据dorado资源打包方式,可包含的资源有js,css等,dorado中资源的按需装载和自动合并功能都是通过这个后缀实现的 /dorado/* dorado自身的服务:控制台服务,对外界提供的服务:如为IDE提供的服务 dorado-7.0.tld 同时也对标签库进行了声明,需要将WEB-INF下的dorado-7.0.tld文件定义在此处。 02. doradohome(SEFC) dorado工程在WEB-INF目录下会包含一个doradohome的文件夹,用于定义dorado的一些系统全局配置和关键的spring配置。 doradohome文件夹的位置,我们可以通过如下方式指定: 默认位于WEB-INF根目录下的doradohome 通过web.xml的context-param定义,参数名为doradohome: doradohome xxxxx 通过系统环境变量DORADO_HOME(如果一台服务器有多个dorado项目,则这种方式就不适用了) 通常情况下,doradohome下包含的文件有: 文件名 说明 context.xml config.properties dorado属性配置文件 packages-config.xml JS文件和相关客户端资源文件的打包规则设定文件 servlet-context.xml 用于存放SpringMVC相关的配置文件 w3c-html4-template.html dorado视图的默认模板 03. 运行模式(SEFC) 设计说明 在项目开发中我们经常会为了配合系统的调试做很多临时性的设定,当我们向正式环境中部署时,系统部署人员往往不是很了解这些设定,没有将这些属性设定调整为生产环境所需,从而导致很多问题,包括安全性方面的。根据这种情况dorado提供了运行模式处理机制,它允许你根据不同的运行环境定义名称不同的配置文件,而在最终发布时,我们只要调整一个系统全局变量就可以进行切换。这样我们从一种运行环境切换到另一种环境时,系统发布人员只要修改一个变量的值。很显然这很受系统部署人员的欢迎。 dorado7通过config.properties文件中runMode的值做运行模式的切换,如图: 系统运行时,会自动检测运行模式,并会给出运行模式的警告: dorado中默认提供了三种运行机制:Production(生产环境),Debug(开发和调试),Test(测试).另外运行模式也可以自定义。 在性能和压力测试环境下需要将运行模式切换为Test模式. 配置装载规则 configure.properties是首先被装载的属性文件,如果发现core.runMode做了设定,则系统会自动查找configure-xxx.properties文件,并加载,如本例为debug,则系统自动查找configure-debug.properties文件。configure-debug.properties中对model.root和view.root进行了覆盖定义。并利用view.mergeJavaScript对javascript和view.mergeStyleSheet对style文件的格式进行了设定,便于系统的调试,如果我们在正式发布的时候将core.runMode的值清空,也就是采用dorado默认的Production运行模式,这个时候configure-debug.properties中的属性配置就不会起作用. 如何定义新的运行模式?我们只要将core.runMode的值给一个新的值(如aaa),并定义一个configure-aaa.properties,这样我们就创建了一个新的运行模式 另外doradohome下的context.xml文件也支持运行模式,例如我们设定core.runMode为debug时,我们就可以定义一个context-debug.xml文件。 dorado默认提供的常用配置属性 属性名 默认值 说明 core.runMode production 生产环境 view.debugEnabled false 是否允许启用Dorado提供的Debugger工具 view.useMinifiedJavaScript true 是否使用压缩后的JavaScript view.useMinifiedStyleSheet true 是否使用压缩后的Style view.outputPrettyJson false 是否格式化输出JSON数据 view.skin default 默认的皮肤 view.mergeJavaScript true 是否合并JavaScript view.mergeStyleSheet true 是否合并CSS文件 view.useRandomStringAlias true 为LoadRunner这类压力测试工具专门设计的参数 是否启用随机别名机制,例如作为服务的view的名字 04. Spring上下文(SEFC) configure.properties只能用于配置dorado7的一些最基本的参数,更多的dorado7配置信息还是位于像context.xml这种类型的spring文件中,由于dorado7将spring作为底层最基础的依赖,dorado7自身的服务也是通过spring搭建起来的,当我们需要扩展dorado7的时候,大多数情况下我们都需要修改这些spring配置文件. .properties与context.xml的关系 举例说明,我们观察context.xml中的如下代码: 注意这个bean-dorado.dataConfigLoader的属性设定中"${model.root}/*.model.xml",其中的"${model.root}",这个格式大家都比较熟悉,这是一种Spring本身就支持的EL表达式的语法.通常情况下它都是用于从.properties配置文件中读取一些参数并在运行时进行替换.如这儿的参数是定义在之前的configure.properties和configure-debug.properties文件中 core.runMode=debug model.root=classpath*:models view.root=classpath: model.root=file:C:/Users/Administrator/workspace/sample/src/models view.root=file:C:/Users/Administrator/workspace/sample/src data.config.autoReloadEnabled=true data.config.autoRecalculatePaths=true view.debugEnabled=true view.mergeJavaScript=false view.mergeStyleSheet=false view.useMinifiedJavaScript=false view.useMinifiedStyleSheet=false view.outputPrettyJson=true 根据之前运行模式的了解我们知道在context.xml在最终运行时${model.root}会被替换为"file:C:/Users/Administrator/workspace/sample/src/models",这样我们知道.properties与Spring配置文件之间的关系,.properties作为Spring配置文件中EL表达式的属性来源,另外.properties文件也做为dorado自身属性配置的存放处。对于专门为Spring配置文件提供服务的属性,例如刚才的"model.root",它的变量名我们也是可以修改的,只要在修改时保证.properties文件的属性名与Spring配置文件的EL表达式保持一致就可以。 运行时spring的上下文 根据Spring的运行机制,一旦你配置了一个Spring的MVC,系统产生的上下文对象除了默认的Context之外还会产生一个Servlet-Context,其中Servlet-Context会包含上面的Context对象,并作为parent关系存在,如图: 如果定义了多个Spring的MVC,就会有多个Servlet-Context,但是Context只有一个.根据运行机制我们知道,Servlet-Context可以访问Context中的bean,但是反过来却不行,这也是之前我们要求的在doradohome文件夹中,如果用户定义Spring的MVC最好将它定义在servlet-context.xml中的主要原因。关于Context与Servlet-Context的详细资料请查阅Spring中的相关文档。 05. 资源定位表达式(SEFC) 在刚才的.properties中我们看到几个变量的定义: model.root=classpath*:models view.root=classpath: ... model.root=file:C:/Users/Administrator/workspace/sample/src/models view.root=file:C:/Users/Administrator/workspace/sample/src 我们看到同样是model.root的值,有以classpath*作为前缀的,也有一file作为前缀的,因此下面要简单介绍一下dorado中的资源定位表达式. 定义:资源定位表达式通常用来描述一个或一组文件的位置, 它的基本格式为:[协议:]路径 就是协议后面加冒号再加路径,中括号表示其中的内容可省略。 目前支持的协议有: file:表示操作系统的文件系统路径; home:表示doradoHome所在位置的起始路径; classpath:Java资源路径 classpath*:Java资源路径,是特别为了从多个jar包中根据通配符批量的提取资源而提供的; 协议是可以省略的,当不指定具体的协议时Dorado7会自行判断应如何理解用户给出的路径。 如果路径以"/"开头,Dorado会认为该路径描述是项目web根下的文件。 如果路径不以"/"开头,Dorado按照classpath协议来处理路径。 如有需要开发人员可以自行扩展协议。 示例说明 file:d:/workspace/test/foo.txt-\- (file:d:/workspace/test/foo.txt--)就是访问d:/workspace/test目录下的foo.txt文件 classpath:org/myproject/configure.xml 与 org/myproject/configure.xml 是等效的。 /WEB-INF/template.jsp--由于以"/"作为前缀,默认就认为是web根目录下的WEB-INF下查找template.jsp文件file:d:/workspace/test/**/*.xml所有d:/workspace/test目录(包括子文件夹)下的xml文件都会被该表达式命中。 classpath:models/*.xml 或 models/ .xml 所有classpath中models下的xml文件都会被该表达式命中。* classpath*:models/*.xml 所有jar包和classpath中models下的xml文件都会被该表达式命中。 06. context.xml几项基本配置的简介(SEFC) xml内容: dorado.dataConfigLoader dorado.dataConfigLoader是用于设定dorado数据模型文件的存放位置,默认该位置为src下的models这个package下,所有的数据模型文件都以.model.xml结尾.当我们将数据模型文件放在models这个package下,dorado7就会自动装载这些模型文件。 dorado.viewConfigFactoryRegister dorado.viewConfigFactoryRegister是用于设定dorado视图文件与请求URL的匹配规则的配置文件,默认的视图文件都以.view.xml文件最为后缀。 dorado.packagesConfigLoader 用于设定dorado中js和css资源打包规则的配置文件的存放位置 以上几个属性的详细使用方式和技巧将在后续的文章中进一步说明 02. 界面开发技巧(SEFC) View配置文件基本结构 实做HelloWorld EL表达式 控件的基础知识 布局管理器 实做AJAX 服务定位表达式 智能方法适配 HTML模板 对象监听器 01. View配置文件基本结构(SEFC) 参看下图,一个空白的视图配置文件共有四个节点: 这是其XML: Arguments 用来定义参数,可在View的其他地方来引用这个参数,在特定情况下可以简化配置,如提取公用信息配置在arguments中。另外arguments的值也允许从外部传入. 这种参数可在当前的View配置文件中通过EL表达式引用。引用方法:通过${argument.foo}的形式引用 Context 对应为DoradoContext的VIEW范围的上下文对象,它在View的整个生命周期中无论在Browser还是在Server端,我们都可以很方便的访问和存储常用的是数据。代码编写方式与map类似,使用时我们可以在网页中通过js将一个字符串存入Context,之后我们再发送一个ajax请求,服务器端就可以根据其key值取到刚才存入的字符串。同时我们也可以在这次ajax请求的服务器端java代码中将一个字符串存入Context,则这次ajax请求结束后,我们可以在Browser端对应这次ajax请求的回调函数或对应执行成功的事件中通过java端设定的key获取到返回的值。基本使用方法: Server端通过context.getAttribute(DoradoContext.VIEW, "foo")读取。 Client端通过view.get("context.foo")读取。 Model Model是View的私有模型对象,View可以在此处定义自己私有的模型对象供当前页面使用,或通过这个私有的模型对象覆盖models目录下对应的某个全局的模型对象,进行个性化设定。关于模型对象的概念后面会有专门的文档进行说明。 View View节点我们最经常使用的一个节点了,dorado7中的控件都是添加到这个节点下的。 02. 实做HelloWorld(SEFC) 首先请完成 。准备工作 页面效果预览: 页面功能非常简单:页面上显示一个按钮,单击这个按钮出现一个"HelloWorld!"的信息提示框 下面我们来实做这个页面,为了减低难度,我们直接在dorado上面准备工作中完成的sample-center中完成这个HelloWorld的开发。 首先我们在src中新建一个package:com.bstek.dorado.sample.training,如下图: 之后单击training的右键,创建一个新的View文件: 将文件名命名为HelloWorld.view.xml: 得到如下视图: 选择View节点,并在Dorado7 ToolBox中输入Button(或直接在General中找到Button控件): 双击Button控件添加Button到View中: 单击Button控件,在右侧的Properties面板中设置其caption属性为:"Greeting from Dorado7 ..." 将当前标签切换到events,并找到Button的onClick事件: 双击打开事件编辑器,并添加如下的代码: dorado.MessageBox.alert("Hello World!"); 以上是用了Dorado提供的MessageBox做alert提示,当然了,你也可以用原生的alert,如: alert("Hello World!"); 它们的运行效果是一样的。 保存当前视图,并先启动当前的tomcat(如果未启动的话): 服务启动成功后,通过如下的URL访问新建的HelloWorld页面. http://localhost:8080/sample-center/com.bstek.dorado.sample.training.HelloWorld.d 得到如下视图: 并单击按钮查看提示信息的效果。 这样我们就完成了HelloWorld的开发。 Argument用法 在此基础上,我们试用一下View中的argument。首先在arguments下添加一个新的argument节点: 并设置value为"HelloWorld!" 同时设置按钮的caption为: ${argument.text} 这是EL表达式的用法,后面的文档将会详细说明.配置好之后如图: 现在你可以再回到原来的测试浏览器中,重新刷新页面查看效果。 URI与视图配置文件之间的映射关系 在实做HelloWorld的过程中应该注意到其URL路径与View文件的资源文件的对应关系。事实上该范例我们也可以通过如下的URL进行访问: http://localhost:8080/sample-center/com/bstek/dorado/sample/training/HelloWorld.d 另外在很多场景下,如果所有的View都处于相对集中的位置,例如本例所有的View都在com.bstek.dorado.sample目录下,则我们还可以通过调整dorado-home下context.xml中的dorado.viewConfigFactoryRegister的配置简化上面URL的访问,例如我们将配置调整为: 按照上面的配置规则调整后我们就可以通过如下的方式访问HelloWorld: http://localhost:8080/sample-center/training.HelloWorld.d 03. EL表达式(SEFC) Dorado7提供了两种EL表达式,静态EL表达式和动态EL表达式,在实做HelloWorld的范例中我们已经初步接触了静态EL表达式. 表达式类型 表达式格式 静态EL表达式 ${expression} 动态EL表达式 $${expression} 差别 静态EL表达式:在创建目标对象的过程中一次性的求值. 动态EL表达式:以动态代理的方式创建目标对象,并在外界每一次读取相应属性时都进行求值。 举例说明: 如我们设置button的caption为${util.getDate()}. 则我们用java访问这个属性的时候: System.out.println(button.getCaption()); System.out.println(button.getCaption()); System.out.println(button.getCaption()); 上面的输出是一样的。 而如果改为动态表达式$${util.getDate()}: System.out.println(button.getCaption()); System.out.println(button.getCaption()); System.out.println(button.getCaption()); 这个时候上面的每一个输出都不一样,在每一次读取的时候都会运算求值。 动态EL表达式通过动态代理实现,使用的时候需要注意隐式对象的选择,例如我们不能在JS端使用Java端的对象做动态EL表达式 隐式对象 Dorado共提供了14个隐式对象,我们不需要预先定义就可以直接使用这些隐式对象。 与线程无关 标识符 描述 null 表示null env 表示获取系统环境变量。${env.JAVA_HOME}或${env["JAVA_HOME"]} system Java的系统属性,即System.getProperties()对象。${system.property1}或${system["property1"]} configure 用于获取Dorado7的配置信息。${configure["runMode"]} 与线程有关 标识符 描述 argument 用于获取当前配置文件中的参数值,仅可用于View.xml context 当前线程中的DoradoContext。 ctx 用于简化对DoradoContext的getAttribute方法的访问。${ctx["foo"]}相当于${context.getAttribute("foo")} util 基本工具类,见com.bstek.dorado.core.el.ExpressionUtilsObject的javadoc request 当前的HttpServletRequest对象,与请求作用域属性的名称和值相关联的 Map 类 req 用于简化对request的getAttribute方法的访问。 ${req["foo"]}相当于${request.getAttribute("foo")} param 用于简化对request的getParameter方法的访问。 ${param["foo"]}相当于${request.getParameter("foo")} session 当前的HttpSession对象,与会话作用域属性的名称和值相关联的 Map 类 servletContext 当前的SerlvetContext对象 web 基本工具类,见com.bstek.dorado.web.WebExpressionUtilsObject的javadoc 可扩展 如有需要,开发人员可以自行扩展出更多的隐式变量. 说明 因为 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 } 返回 urls 标识符所引用的数组或集合的第四个元素(和 Java 语言以及 JavaScript 中一样,EL 中的下标是从零开始的)。对于实现3 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 表达式所访问数据的运算符。 类别 运算符 算术运算符 +、-、*、/(或 div)和 %(或 mod) 关系运算符 ==(或 eq)、!=(或 ne)、<(或 lt)、>(或 gt)、<=(或 le)和 >=(或 ge) 逻辑运算符 &&(或 and)、||(或 or)和 !(或 not) 验证运算符 empty 最后一种 EL 运算符是 empty,它对于验证数据特别有用。empty 运算符采用单个表达式作为其变量(也即,${empty input}),并返回一个布尔值,该布尔值表示对表达式求值 的结果是不是"空"值。求值结果为 null 的表达式被认为是空,即无元素的集合或数组。如果参数是对长度为零的 String 求值所得的结果,则 empty 运算符也将返回 true。 EL 运算符优先级(自顶到底,从左到右) 优先级 [], . () unary -、not、!、empty *、/、div、%、mod +、binary - () <、>、<=、>=、lt、gt、le、ge ==、!=、eq、ne &&、and ||、or 范例 ${4+2} = 6 ${4-2} = 2 ${4*2} = 8 ${4/2} = 2 ${3>2} = true ${3<2} = false ${2!=3} = false ${true&&false} = false ${!(2==3)} = true ${(x >= min) && (x <= max)} ${empty(foo)}${foo>0? "enabled":"disabled"} ${foo["bar"]}或${foo.bar} 读取map中的bar键值。 文字 在 EL 表达式中,数字、字符串、布尔值和 null 都可以被指定为文字值。字符串可以用单引号或双引号定界。布尔值被指定为 true 和 false。 特殊EL隐式变量 在使用Dorado EL表达式的时候,我们还需要掌握几个特殊的EL隐式变量,如:$${this}或$${this.foo}.虽然写法上像动态EL表达式,但其实际运行的机制与一般EL表达式并不一样,注意要点: 此种隐式变量通常只用在DataType的Reference属性中。this表示当前正在处理的数据实体对象,即系统正在尝试获取该数据实体对象的Reference属性的值。 此种EL表达式的实际求值范围是在Client端的JavaScript环境中。 Reference使用图例: 关于这几个EL表达式的实际用法我们将会在后面Reference的使用中用实例阐述 04. 控件的基础知识(SEFC) dorado提供了一套完整的控件库,以Dorado7.0.9版本计算已经提供了74个顶级控件,配合上容器控件和一些复合控件的相互组合,可以作出各种特征的页面。并且随着Dorado版本的升级控件数量将会越来越多。在开始学习这些控件之前,我们有必要先了解一些控件的基础知识。 控件的基本类别 在dorado中我们一般将控件区分为不可见控件和可见控件. 不可见控件: 如DataSet(数据的容器),Action(代表了一个动作),FormProfile(用于设定表单的格式和风格),这种控件不参与页面布局,不会在页面上显示出来,但是一般来说可以在页面上使用它,例如通过js代码存取它的属性,或调用它的方法。其中最终要的是DataSet,这是我们前面所说的Dorado将数据模型和展现形式分开后,DataSet就是用来描述其中的数据模型的。 可见控件: 如在HelloWorld中接触的Button,它会直接显示在浏览器中,参与页面的布局,可见控件可以将它分为: 独立控件:如Button,TextEditor(表单中常用),Grid 容器控件:是指控件内部可以包含其他各种类型控件,包括容器控件,如Container,Panel,GroupBox 复合控件:TabControl, SplitPanel, ToolBar,控件截图: 粗看容器控件与复合控件非常接近,它们都可以包含子控件,我们在来了解容器控件与复合控件的区别: 最大的外在区别在于是否支持布局管理器。 容器控件中总是有一块空白的矩型区域用于显示隶属于容器的子控件,且子控件的显示方式受容器控件当前选用的布局管理器控制。如Panel控件,Panel控件中可以包含多个子控件,并可以根据自己的需要决定布局 复合控件虽然也可以包含一到多个的子控件,但这些子控件如何被显示是由复合控件自身的逻辑决定的。如TabControl控件,TabControl控件也可以包含多个控件,但是一次只能显示一个控件,它无法同时展现多个控件,它内部控件的显示方式是根据控件本身的特性决定的,无法随意更改。 控件的其它分类方式 浮动控件 默认不接受布局管理器的管理,且显示时浮动于所有非浮动控件之上。例如:Dialog、Menu、FloatContainer。如下图: 如果将浮动控件的floating属性设置为false,则浮动控件将失去浮动特性且将接受布局管理器的控制。 数据感知控件 可以与DataSet进行绑定用于显示、修改或控制DataSet中的数据的控件。例如:DataGrid、TextEditor、AutoForm。 属性设置图示: 05. 布局管理器(SEFC) 在First Conatct中我们介绍过,一般的Dorado页面都不需要JSP完成布局,那么我们就需要灵活的掌握运用容器型控件和各种布局管理器来完成对界面的布局。 所谓布局就是指容器组件中子元素的分布、排列组合方式。Dorado的所有容器组件都支持布局操作,每一个容器都会有一个对应的布局,布局负责管理容器组件中子元素的排列、组合及渲染方式等 Dorado7目前提供的布局管理器: 布局名称 说明 DockLayout 停靠式布局 AnchorLayout 锚定式布局 FormLayout 表单式布局 HBoxLayout 水平箱式布局 VBoxLayout 垂直箱式布局 NativeLayout (其实什么都不做的布局) DockLayout(停靠式布局) AnchorLayout(锚定式布局) FormLayout(表单式布局) HBoxLayout和VBoxLayout 01. DockLayout(SEFC) DockLayout是Dorado中最常用的布局方式(经常作为页面的总体布局).DockLayout的基本说明: 停靠式布局将控件分成5中区域:left、top、right、bottom和center。 每个控件选择一种区域由布局管理器按照顺序进行排列。 选择center区域的控件总是到最后才被放置,他总是占尽所有剩余的空间。 除center区域之外,其他4中区域都可以出现0到n个, center区域最多只能出现一次。 如果某控件没有显式的声明选择哪种区域,那么布局管理器会尝试按照center区域对其进行布局。 如果我们这么定义View的布局: 我们设置布局的layout为Dock,不同的HtmlContainer的layoutConstraint属性分别设置为:left、top、right、bottom和center中的一种,则得到的布局效果图如下: 实际使用时并不一定要包含所有的区域,我们将其中的HtmlContainer更换为控件: 查看页面执行效果: 02. AnchorLayout(SEFC) AnchorLayout的基本思路是设定某控件的四周边框与容器边界或其他控件之间的锚定关系,以此来确定该控件实际所处的位置和尺寸。 场景1(简单的边界锚定) 如图: Control1设定与容器的left与top为一个具体值,因此在页面渲染的时候Control1会处在容器中一个固定的位置,而Control2与Control1有所差别,其top锚定到容器的一个具体值,使得它始终距离容器的上边界有一个固定值,但是其left没有直接锚定容器,而是相对的锚定到Control1,其left的值表示相对Control1的一个相对距离。这样一但我们调整Control1距离容器的left值的时候,会看到Control2跟着Control1走的效果。它会始终保持与Control1的一个相对距离。同理Control3与Control4控件,当我们缩放容器的大小时它们会始终都贴在容器的右下角。 测试场景: 选择场景1)http://bsdn.org/projects/dorado7/deploy/sample-center/com.bstek.dorado.sample.basic.AnchorLayout.d( 效果图: 我们可以尝试着将Dialog的大小做调整,发现Control3和Control4始终都贴在Dialog的右下角。 场景2(通过锚定关系来控制控件的尺寸) 如图: 其中Control1设定容器中left和right的锚定值为一个具体值,这样当容器大小发生变化的时候,控件必须保证其left和right的值不变,这样势必要求控件本身的宽度要适应容器宽度的变化。而Control2四个边界都做了锚定,当容器大小发生变化的时候Control2必须同时调整自身的高度和宽度才能满足四个锚定关系。 测试场景: 选择场景2)http://bsdn.org/projects/dorado7/deploy/sample-center/com.bstek.dorado.sample.basic.AnchorLayout.d( 效果图: 我们可以尝试着将Dialog的大小做调整,发现Control1的宽度会自适应调整,而Control2始终保持四个方向锚定距离不变。其实这个场景我们也可以注意到它非常像DockLayout布局中Control1为top布局,而Control2为Center布局。因此DockLayout其实是AnchorLayout的一种特例,事实上Dorado的DockLayout就是从AnchorLayout继承下来的。 场景3(利用百分比锚定实现居中等效果) 如图: 在前面的锚定布局中对四个方向的锚定位置都采用了固定值,其实AnchorLayout也支持百分比的锚定,例如本例的Control1我们设定了left的锚定值为50%,这样AnchorLayout最终运行的时候会使Control1产生一个居中的效果(与场景2居中效果不同的是,该处的控件的高度和宽度始终保持一个固定值),产生这种居中效果的实现需要特别加以说明,50%并不是让Control1距离左边的锚定距离为50%,而是将容器宽度减去自身宽度后剩余宽度的50%,这样就恰好能实现控件居中的效果。这样当我们定义图中Control3的左边锚定距离为100%的话,其实际产生的效果恰好是贴在整个容器的最右边。同样Control2如果我们设容器top的锚定距离为50%,其实际产生的效果就是Control2上下居中。即使我们动态调整整个容器的大小,Control1,Control2,Control3的显示效果都不会有变化。 测试场景: 选择场景3)http://bsdn.org/projects/dorado7/deploy/sample-center/com.bstek.dorado.sample.basic.AnchorLayout.d( 效果图: 我们可以尝试着将Dialog的大小做调整,发现Control1始终左右居中,Control2始终上下居中,Control3始终贴在容器的最右边。并且这个过程中这些控件的高度和宽度始终都没有变化。 实战 前面我们说过DockLayout是AnchorLayout的子类,那么我们通过一个实战体验一下。我们通过之前DockLayout中的范例,做一个调整,改为AnchorLayout,并相应的调整各个控件的锚定属性: AnchorLayout 最终效果图: 从图中我们可以看出与之前 布局中的效果是一模一样的。这也从一个侧面验证了DockLayout是AnchorLayout的子类。DockLayout 03. FormLayout(SEFC) 如图: 表单式布局首先把空间分成1到n列,然后由上往下依次排列各个子控件。 每个子控件可以选择自己要占用几行或几列。 当Control4需要占用两行的时候,我们就可以看到Control3,Control4,Control5的展现效果,其中Control5在Control4的左边。而Control6需要占用两列,就会把容器的整行都占用了,然后Control7占用了第一列,当容器要放置Control8的时候发现Control7这一行的空间不够,它需要占用两列的控件,这样容器会把Control7控件后面的空间空出来,并将Control8放置在下一行中。这就是表单布局的基本特点。这个只要对HTML中Table元素熟悉一点就很容易理解。如果不太清楚仔细阅读HTML中Table元素的文档. 04. HBoxLayout和VBoxLayout(SEFC) HBoxLayout和VBoxLayout布局都比较简单,也叫箱式布局,它按照先后顺序进行横向布局或垂直布局。 另外这两种布局也提供了pack属性支持,设置内部元素的位置:start,center,end. 使HBoxLayout内部的元素靠左,居中还是靠右 使VBoxLayout内部的元素顶天,居中还是立地 这两中布局都相对简单,实际试用一下就能掌握。 HBoxLayout VBoxLayout 06. 实做AJAX(SEFC) 下面我们通过实做AJAX对Dorado7中的AJAX操作做一定的了解。 页面功能描述: 首先我们设计一个Spring的JavaBean: package com.bstek.dorado.sample.basic; import java.util.Properties; import org.springframework.stereotype.Component; import com.bstek.dorado.annotation.Expose; import com.bstek.dorado.core.DoradoAbout; @Component public class Ajax { @Expose public String toUpperCase(String str) { return "input:\n" + str + "\n\n" + "output:\n" + str.toUpperCase(); } @Expose public int multiply(int num1, int num2) { return num1 * num2; } @Expose public Properties getSystemInfo() { Properties info = new Properties(); info.setProperty("product", DoradoAbout.getProductTitle()); info.setProperty("vendor", DoradoAbout.getVendor()); info.setProperty("version", DoradoAbout.getVersion()); return info; } } 页面上放置三个按钮:button1, button2, button3 单击button1的时候,调用spring中的一个bean的方法toUpperCase,并将我们传入的字符串转换为大写,并返回到前台浏览器中; 单击button2的时候,调用spring中的一个bean的方法multiply,并将我们传入Map对象(含多个key)中的两个数字相乘,并将计算结果返回到前台浏览器中; 单击button1的时候,调用spring中的一个bean的方法getSystemInfo,并将Java中的一个Map对象返回到前台浏览器中; 如果完成了以上的三个功能,我们就很容易解决这些AJAX技术问题: 如何调用Spring中bean中指定的业务方法; 如何传入一个单值给后台,并将调用结果为单值的值如何返回到前台; 如何传入一个map到后台,并将运算结果返回到前台; 如何调用后台的业务方法,并将计算结果为map的值返回到前台; 掌握了以上基本技术之后,再将它们综合应用一下,如JS中指定map参数,ajax调用结束之后返回map对象,并在前端使用。这样我们就可以解决大部分的ajax调用问题了。 toUpperCase 下面我们还是在HelloWorld中实做这个范例,由于HelloWorld中已经定义过Ajax这个Bean了,我们不再重复定义,我们在com.bstek.dorado.sample.training目录中新建一个名称为Ajax的View,并在其中添加一个AjaxAction控件和Button控件,其中AjaxAction是Action的一种,我们在控件的基础知识中简单介绍过它代表了页面上的一种动作,是不可见的对象。但是它可以被其他可见控件使用,例如单击按钮时触发Action。 我们设置AjaxAction控件的相关属性: 属性 值 id toUpperCaseAction caption To UpperCase parameter Hello World! service ajax#toUpperCase 其中我们特别关注其service属性,"ajax#toUpperCase"是一个服务名称,根据Dorado中的服务定位表达式,它最终代表的含义是调用Ajax这个类的toUpperCase方法,至于服务表达式的概念我们后面再讲,这儿我们只要记住这个字符串最终会调用到Ajax这个类的toUpperCase方法就可以。而parameter的值就代表了调用toUpperCase方法传入的参数值。 再设置Button控件的相关属性: 属性 值 action toUpperCaseAction 定义action属性的效果是,单击按钮的时候自动触发toUpperCaseAction。我们可以注意到Button上的显示内容我们都没有定义,该处根据Action的绑定规则它会自动显示action对应的caption,而toUpperCaseAction中我们已经定义了caption了。 另外,当Ajax这个类的toUpperCase方法执行结束之后,我们希望在浏览器中看到最终的返回值,那么我们定义toUpperCaseAction的onSuccess事件: 双击onSuccess打开事件编辑器,输入如下代码: dorado.MessageBox.alert(self.get("returnValue")); 在action的onSuccess事件中,self代表了action本身,returnValue表示Ajax调用结束后Java层返回的结果。该处关于JS代码的写法后面我们会有专门的章节进行说明,此处我们记住self.get("returnValue")的含义就是获得ajax调用返回的结果就可以。 这样我们就完成了第一个按钮的开发,在浏览器中打开这个页面( )查看效果:http://localhost:8080/sample-center/com.bstek.dorado.sample.training.Ajax.d multiply 下面我们接着做multiply的ajax调用,同样我们再添加一个AjaxAction和一个Button。 我们设置AjaxAction控件的相关属性: 属性 值 id multiplyAction executingMessage Computing... service ajax#multiply 通过toUpperCase实例的制作,我们知道了"ajax#multiply",它最终代表的含义是调用Ajax这个类的multiply方法。executingMessage是用于在Ajax调用时给客户一个提示信息,在Ajax调用结束之后会自动消失,这样对于某些耗时的ajax调用来说这种显示效果更为人性化。 再设置Button控件的相关属性: 属性 值 action multiplyAction caption Ajax Multiply 定义action属性的效果是,单击按钮的时候自动触发toUpperCaseAction。另外与toUpperCase范例不同,这次我们直接在Button上定义caption,其实这几种定义caption的方式都可行,根据实际场景灵活运用就是了。例如我们希望动态改变按钮绑定的action时,我们就可以考虑将caption定义在action中。 另外,当Ajax这个类的multiply方法被调用时需要两个参数,我们希望给用户一个自定义输入参数的机会,而不是toUpperCase用例中直接定义在parameter属性中,如下图: 则我们在button的onClick代码中添加如下的JS: var action = this.id("multiplyAction"); dorado.MessageBox.prompt("Please input two numbers here", { defaultText: "3,5", callback: function(text) { var nums = text.split(","); var parameter = { num1: nums[0], num2: nums[1] }; action.set("parameter", parameter).execute(function(result) { dorado.MessageBox.alert(nums[0] + " * " + nums[1] + " = " + result); }); } }); 其中我们通过Dorado提供的MessageBox做用户输入界面,MessageBox的具体用法参考: .http://www.bsdn.org/projects/dorado7/deploy/jsdoc/class.html?symbol=dorado.MessageBox 我们将用户输入的值利用js的split拆分为两个数字,num1和num2封装到parameter中(可以想象成一个Map),并将这个parameter设置给action去调用服务器端的multiply方法。 我们回过头在看看multiply方法: @Expose public int multiply(int num1, int num2) { return num1 * num2; } 当map对象传到Ajax类的时候,发现没有匹配的方法,这个时候Dorado的自动方法适配机制会自动的将map拆为num1和num2,从而调用到multiply方法。有关自动方法适配我们后面还会再讲。multiply做的工作就是将num1和num2相乘,并将结果返回。我们在Button的onClick代码中利用了一个回调函数将计算结果显示出来(回调函数用法会在后面的JavaScript基础中进一步说明)。 这样我们就完成了第二个按钮的开发,在浏览器中打开这个页面( )查看效果:http://localhost:8080/sample-center/com.bstek.dorado.sample.training.Ajax.d getSystemInfo 下面我们做getSystemInfo的ajax调用,同样我们再添加一个AjaxAction和一个Button。 我们设置AjaxAction控件的相关属性: 属性 值 id getSystemInfoAction caption Retrieve Dorado7 System Information service ajax#getSystemInfo 通过toUpperCase实例的制作,我们知道了"ajax#getSystemInfo",它最终代表的含义是调用Ajax这个类的getSystemInfo方法。 再设置Button控件的相关属性: 属性 值 action getSystemInfoAction 定义action属性的效果是,单击按钮的时候自动触发getSystemInfo。 另外,当Ajax这个类的getSystemInfo方法调用成功后返回的是一个Properties对象,这也是一个Map对象,我们希望在浏览器中看到最终的返回值,那么我们定义getSystemInfoAction的onSuccess事件: var info = self.get("returnValue"); dorado.MessageBox.alert("product : " + info.product + "\n" + "vendor : " + info.vendor + "\n" + "version : " + info.version); 在action的onSuccess事件中,self代表了action本身,returnValue表示Ajax调用结束后Java层返回的结果。由于返回的是一个Map对象,在浏览器中接受的时候会自动转为JSON对象,这样我们就可以直接通过info.product,info.veneor,info.version范围map中的内容。 这样我们就完成了第三个按钮的开发,在浏览器中打开这个页面( )查看效果:http://localhost:8080/sample-center/com.bstek.dorado.sample.training.Ajax.d 07. 服务定位表达式(SEFC) 在实做AJAX中我们提到服务定位表达式的概念,接下来我们详细对服务定位表达式做一个说明。 在Dorado7中服务定位表达式是用来描述服务的查找方式,即Dorado7通过服务定位表达式来查找到具体服务,以便于对服务进行调用。 它的基本格式: 协议:服务名[#方法名] 这里的服务名通常是代表一个JavaBean。 目前支持的协议(协议也可以扩展): spring: 表示其后的服务名是某个Spring上下文中的Bean的id。例如:spring:ajax#toUpperCase classpath: 表示其后的服务名一个类的完全限定名,当Dorado7需要调用此服务时会自动按照单例模式来实例化该类。(此种方式不推荐使用,因为Spring是Dorado7的标配,将服务注册在Spring上下文中可以获得很多额外的好处)。例如:classpath:com.bstek.dorado.sample.basic.Ajax#toUpperCase 以刚才实做的AJAX范例说明,首先我们了解一下什么是可暴露服务,在Dorado中所有的Ajax调用只能调用到那些明确声明为可暴露服务的Java方法,否则是无法调用成功的。可暴露服务包括两个部分: 服务名称 服务定位表达式 在Ajax.java中我们利用annotation机制实现了spring的bean声明: @Component public class Ajax { } 另外我们在WEB-INF的doradohome的app-context.xml中添加了如下的代码: 这样系统默认就会自动扫描到Ajax类,并注册到Spring的BeanFactory中。 而对于toUpperCase方法,我们在此处采用了@Expose标记: @Expose public String toUpperCase(String str) { return "input:\n" + str + "\n\n" + "output:\n" + str.toUpperCase(); } @Expose标记是Dorado7专门提供的标注,用于定义可暴露服务,根据这个规则Dorado7会将这个方法自动注册在ExposedServiceManager中,其中服务名为:ajax.toUpperCase,服务表达式为:spring:ajax.toUpperCase。由于本例采用的是spring协议,因此服务定位表达式以"spring:"作为前缀,而服务名就是Ajax.java在BeanFactory中注册的bean的id,annotation机制会自动将Ajax的A自动转换为小写字母。 另外对于一些其他不采用annotation的系统我们也可以手动的注册可暴露服务,其方法是在Spring的配置文件中添加如下的代码: 如果有多个服务,就在map中添加就是了。 08. 智能方法适配(SEFC) 在实做Ajax的范例中,我们注意到Ajax.java中的代码中没有任何dorado的开发约定,它的样子和我们 没业务层的代码没有什么差别: @Expose public String toUpperCase(String str) { return "input:\n" + str + "\n\n" + "output:\n" + str.toUpperCase(); } @Expose public int multiply(int num1, int num2) { return num1 * num2; } 这是如何做到的呢?另外在multiply方法中dorado是怎么将我们的一个map对象分拆为num1和num2的 呢?要解释这几个问题就有必要先了解一下Dorado7提供的职能方法适配功能。 所谓职能方法适配是基于"约定优于配置"的设计思路而提供。这样在很多情况下我们不需要方法具 有Dorado特性,也不需要引入Dorado的开发规范。由Dorado7自动判断这个方法中的各个参数以及返 回值的用途。这是一种职能化的处理逻辑。这带给我们的好处: 几乎不需要引入任何Dorado7的API。 按照业务的需要而不是Dorado7的需要来为表现层编写代码。 可以令Dorado7与后台业务逻辑之间的粘合层代码更加简洁、易读。 如Ajax范例中的toUpperCase,Browser向服务器端传递的参数是我们在action的parameter属性中定 义的,因为传过来的是一个字符串,智能方法在适配的时候会发现toUpperCase方法的参数就是一个 字符串类型的,这样它就自动认为你想调用的方法就是toUpperCase,并将parameter中的值作为str 中的值传入。这个方法调用结束之后返回了一个字符串给外界,而ajax调用就自动的将这个返回值作 为ajax调用的返回值,如toUpperCaseAction的onSuccess方法: dorado.MessageBox.alert(self.get("returnValue")); 在multiply范例中前台传入的是一个JSON对象,可以就认为是一个Map对象: var parameter = { num1: nums[0], num2: nums[1] }; action.set("parameter", parameter).execute(function(result) { dorado.MessageBox.alert(nums[0] + " * " + nums[1] + " = " + result); }); 这样后台就拿到一个Map参数,让后对ajax这个bean进行方法匹配,会发现其中没有完全匹配的,这 个时候职能方法适配会将parameters中的参数拆开为num1,num2,这样就可以发现存在对应的 multiply方法,并进行调用。并将结果作为ajax调用的结果返回到前台: action.set("parameter", parameter).execute(function(result) { dorado.MessageBox.alert(nums[0] + " * " + nums[1] + " = " + result); }); 我们直接将这个result显示出来。 multiply范例体现的是智能方法适配过程中map自动拆解的功能。 适配算法 上面我们通过Ajax范例对智能方法的适配规则有了一些基本的了解,下面总结一下适配算法。 首先智能方法适配按照参数名进行适配: 即Dorado根据参数名来确定每个参数的作用。 相对严谨的适配规则,但有时使不够业务化。例如对于AjaxAction的后端方法,其参数名必须为 parameter。 如果按照上面的规则,toUpperCaseAction对应的Ajax方法就必须为如下的形式: @Expose public String toUpperCase(String parameter) { return "input:\n" + parameter + "\n\n" + "output:\n" + parameter.toUpperCase(); } 这种方式有时候可能并不满足我们对业务方法的命名习惯,不利于Java代码的阅读。 按照参数类型进行适配 另外我们还可以根据参数的类型进行方法适配。即Dorado根据参数类型来确定每个参数的作用。 它存在的问题是:当参数较为复杂时Dorado可能无法准确的判断个参数的作用。 混合式的适配规则(尚未提供) 即现根据名称规则进行一次适配,对于那些无法匹配的参数继续尝试通过类型规则进行适配。 自动方法适配不会强行调用目标方法 当其认为适配可能存在歧义时会报错而不会继续执行方法调用。 Map 对于Map类的参数自动方法适配会尝试将其拆解,用其中的键值对与方法参数进行适配。 09. HTML模板(SEFC) 前面我们提到过大部分的Dorado页面都不需要JSP,我们可以通过布局管理器和容器完成系统中绝大部分的页面设计,但是也不能排除系统中还是会存在某几个特殊的页面,开发人 员希望能够引入JSP或Velocity作为页面的布局管理器。比如说原有的布局管理器无法满足特殊的页面布局管理,或者说开发人员希望让美工更好的参与到页面的设计中。 下面我们介绍一下Dorado7中的HTML模板功能。 Velocity页面模板 我们查看sample-center中提供的Velocity页面模板示例: 从页面的风格我们看出这是一种开放式布局页面,其页面上嵌入了一些Dorado的控件,如: 场景1中的按钮; 场景2中的一个在Dorado中叫ListBox的控件; 场景3中的一个面板控件 现在我们先看看其中的Velocity页面模板,找到src目录下com.bstek.dorado.sample.basic目录中的VelocityTemplate.html,并打开查看其中代码: #outputPageHeader()

Velocity

1 - renderTo:

2 - renderOn:

3 - renderOn:

HTML

可以看到这是一个普通的html,唯一不同之处是"#outputPageHeader()"这行代码,这样这个html就比较容易的被美工人员在DremWeaver或FrongPage中进行编辑。与使用标签库开发不同,这种页面美工更容易读懂,也更容易被一般的网页编辑器读取和编辑。 我们再来看看同样目录下的VelocityTemplate.view.xml: 由于采用的是Velocity布局,因此在这个View中我们可以看到其中的控件是一个个罗列在View节点下的。View不再进行布局的管理。 现在我们再看看Velocity页面模板与View是怎么配合工作的,我们先了解View的一个特性: Dorado默认的资源文件加载的约定:与View同名同目录的html、js、css文件可以被自动装载。 如刚才的VelocityTemplate.html和VelocityTemplate.view.xml文件我们注意到他的名字是一样的,这样Dorado就默认认为VelocityTemplate.html是VelocityTemplate.view.xml 的HTML模板页面,并自动装载。同理相关的js和css文件也是这样,如果我们希望加载不同文件名或不同资源路径的文件,则我们也可以通过View的几个属性进行设定: 属性名 说明 pageTemplate HTML页面模板 javascriptFile js资源文件,多个js资源逗号隔开 styleSheetFile css文件按,多个css文件逗号隔开 以上三个属性的值都支持协议的写法,如:classpath:xxx或file:xxx 这样我们就知道了View与HTML模板建立关系的方式。 另外关于控件渲染到HTML模板的模式,Dorado设计了三种: renderTo模式 renderOn模式 renderOn容器模式 dorado中的所有可见控件都提供了renderTo和renderOn的两个属性。我们通过一个实例了解三种模式的差别。 页面测试URL:http://www.bsdn.org/projects/dorado7/deploy/sample-center/com.bstek.dorado.sample.basic.VelocityTemplate.d renderTo 其中的Button1和Button2被渲染到了页面中带红边框的一个DIV中,在XML定义的时候我们设置了其renderTo属性:
还剩105页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享pdf获得金币 ] 13 人已下载

下载pdf

pdf贡献者

cherry_wb

贡献于2012-07-21

下载需要 8 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf