您的位置:首页 > 编程语言 > Java开发

构建富Internet应用程序 :使用OpenLaszlo、Eclipse Laszlo IDE和Web Tools

2011-11-15 22:56 766 查看
构建富Internet应用程序:使用OpenLaszlo、EclipseLaszloIDE和WebTools
转载自:http://www.bianceng.cn/Programming/Java/201104/25443.htm

开始之前

本教程演示如何使用OpenLaszlo平台和Web服务来开发、打包和部署一个已编写好的富Internet客户机。富客户端利用了后端的服务(这些后端服务是通过使用SOAPWeb服务的通用SOA方法提供)。还将了解如何有效地使用EclipseLaszloIDE和EclipseWebTools来使得开发更加容易且富有生产效率。

关于本教程

由于大多数Web应用程序都构建于HTML和HTTP之上,所以Web对于用户经常使用的应用程序(比如拍卖和书店站点)来说是一个很好的平台。但是,该例不适合需要丰富用户界面的业务应用程序,因为缺少状态、组件数量有限且浏览器不一致。

如果不是HTML和HTTP,那会是什么呢?富Internet客户机(RichInternetClients,RIC)也称为富Internet应用程序(RichInternetApplications,RIA),是下一代Web应用程序。RIC提供客户机/服务器应用程序的可用性、响应性和重用,以及传统Web应用程序的部署、可管理性和可用性。

本教程探索创建富Internet应用程序、FluidMotion和使用OpenLaszlo平台。

前提条件

您应该具备一些基本的Java™、Web开发和XML技能。对Web服务、XPath和持久存储的基本了解是有帮助的,但不是必需的。

系统需求

需要安装了以下软件:

JavaDevelopmentKit(JDK)™V1.4或更高版本

ApacheTomcatV5.0.28

还需要下载以下软件(本教程解释了如何安装和配置它):

OpenLaszloV3.0.2

EclipseWebToolsall-in-one0.7.1

IDEforLaszloV2.1

OpenLaszlo

本节详细介绍OpenLaszlo,包括它如何适合Java2Platform,EnterpriseEdition(J2EE™)空间,以及可用的开发工具。

概述

OpenLaszlo是一个开放源码的富客户机平台,用于开发动态数据驱动的应用程序。为了运行在MacromediaFlash中的、面向对象的、事件驱动的用户界面(UI),它结合了XML、JavaScript™和XPath。它包括一组丰富的组件和服务(称为运行时框架)和一个用于集成的可选Javaservlet。

OpenLaszlo在公开的CommonPublicLicense下可用。这是一种流行的许可,因为除了常见的授予使用和修改源代码的权限以外,它还提供商业发行版。这意味着商业产品可以派生自OpenLaszlo平台。

其他富客户机

AsynchronousJavaandXML(Ajax)对于结合诸如异步JavaScript、XML、XHTML和CSS之类的标准Web技术的旧技术来讲是一个新术语。有了这一新技术,随之出现了许多有竞争力的框架/工具箱。至于哪种框架/工具箱将成为标准仍然未可知。但是这一技术无疑正在不断流行,Google的威力在一定程度起到了推波助澜的作用。

MacromediaFlex是一款商业产品,用于开发运行在Flash播放器中的业务应用程序。许多Web游戏和电影也利用了Flash播放器。Flex应用程序是用MaximumExperienceMarkupLanguage(MXML)编写的,并且也使用ActionScript进行事件和流控制。MXML是一种基于XML的语言,用于定义UI。

OpenLaszlo是本教程的焦点,它是Flex开放源码的替代物。与Flex一样,它运行在Flash播放器中,使用XML来定义UI,并使用脚本语言进行事件和流控制,以及用服务器端代码进行数据集成。

OpenLaszlo用于布局用户界面的XML格式叫做LaszloXML(LZX)。OpenLaszlo包含一个编译器,用于将LZX和JavaScript编译成二进制ShockwaveFlash(SWF)文件,Flash播放器将呈现该文件。

运行在Flash播放器中是理想的,因为它是一个到处存在的平台。Macromedia宣称它存在于96%连接到Internet的计算机上。没有哪个单个的浏览器可以这样宣称。不断地,它也成为在许多其他设备(比如手提计算机)上可用。Flash播放器也使得安装比较容易,因为它自动地取得应用程序的最新版本,并自动地更新它自己。甚至,Flash可以用于产生吸引眼球的应用程序,因为它还是用于开发基于Web的游戏和电影的平台。那么为什么不直接使用Flash工具呢?Flash使用一种具有时间线和帧的电影手法(metaphor),这使得它难以构建业务应
用程序。但是,OpenLaszlo使用一种具有表、树和组件的常见应用程序框架手法,这是业务应用程序开发人员所熟悉的方法。

OpenLaszlo如何进入J2EE

OpenLaszlo作为客户机层的另一个表示方案,完美地进入J2EE堆栈,如图1所示。

图1.OpenLaszlo作为J2EE堆栈的一部分



使用以下三种协议之一,OpenLaszlo可以通过HTTP与后端服务通信。这三种协议是:JavaRPC、eXtensibleMarkupLanguage--RemoteProcedureCall(XML-RPC)和SOAP。JavaRPC允许调用服务器端Java方法。XML-RPC和SOAP是基于标准的Web服务协议,支持以独立于语言的方式通过HTTP调用远程过程。

如果您不需要J2EE应用服务器的所有强大功能,OpenLaszlo应用程序可以运行在包含的LaszloPresentationServer(LPS)上,这是ApacheTomcat的定制版本,或者运行在诸如ApacheorMicrosoftInternetInformationServer(IIS)的基本Web服务器上,这称为StandaloneOpenLaszloOutput(SOLO)。

开发工具

要开始构建Laszlo应用程序,需要用到OpenLaszloDevelopmentKit(OLDK)。OLDK包含构建OpenLaszlo应用程序所需用到的任何东西,包括LPS、运行时组件和编译器,以及很多很好的文档、演示和示例代码。

除了OLDK之外,我们还推荐使用IDEforLaszlo。它是一个Eclipse插件,其中包括很多好的特性,比如Laszlo项目和文件向导、一个LaszloPerspective以及一个可视化设计器和调试器。当前,IDEforLaszlo是一个IBMalphaWorks项目。但是,IBM和EclipseFoundation最近宣布,IBM将捐出EclipseTechnologyProjects的代码基。

IDEforLaszlo构建在EclipseWebToolsPlatform(WTP)之上。这是理想的情况,因为WTP旨在构建标准(HTML、XML、CSS)和基于J2EE的Web应用程序。建立在WTP基础之上,IDEforLaszlo具有开发多层应用程序所需的所有工具。后面就会看到,WTP也支持开发Web服务。

FluidMotion架构

本教程中给出的FluidMotion应用程序是一个简单的WorkOrderManagement(WOM)应用程序,允许雇员向数据库提交新的工作单。WOM应用程序允许组织收集及管理工具和设备维护请求,通过确保请求不被忘记并及时完成,而为组织带来价值。本教程中的FluidMotionWOM允许维护人员查看列表中的工作单,并在完成后更新和关闭它们。

图2中所示的FluidMotion应用程序架构包括客户机和服务器组件。客户机是用OpenLaszlo富Internet客户机框架编写的,该框架由MacromediaFlashPlayer呈现,而后者宿主在Web浏览器中。客户机通过SOAP与通过ApacheAxis公开的Web服务进行通信,ApacheAxis是一个开放源码的Web服务框架。Web服务然后使用Hibernate(一个开放源码的对象关系映射框架)将工作单持久存储到Derby,Derby
是一个轻量级的Java数据库。服务器组件宿主在OpenLaszlo服务器上,该服务器是ApacheTomcat的一个扩展,而ApacheTomcat是一个开放源码的Web容器。

图2.FluidMotion应用程序架构



设置开发工具

从前一节已经看到,设置成功的OpenLaszlo开发环境需要用到几个软件。本节解释如何安装和配置这些软件。

OpenLaszloDevelopmentKit

OpenLaszloDevelopmentKit带有特定于平台的安装程序,如果您的操作系统不是显式受支持的,则可以使用DevKit。要在Microsoft®Windows®中安装开发工具箱,请执行以下步骤:

下载openlaszlo-3.0.2-windows-dev-install.exe,如果还没有下载的话。

双击openlaszlo-3.0.2-windows-dev-install.exe。

阅读许可,并通过单击IAgree接受许可。

选择一个目录用于安装OpenLaszlo服务器,并单击Install。

单击Finish。

一完成安装,LPS就会立即启动,您的默认浏览器也会启动(如果还没有打开的话)。浏览器被定向到OpenLaszlo文档、演示和示例代码的本地版本。阅读完本教程之后,请花点时间仔细阅读该文档,它很值得一读。

EclipseWebTools

EclipseWebTools依赖于EclipseV3.1以及几个其他Eclipse项目:EMF、GEF和JavaEMFModel。由于所有这些依赖项,所以有三种安装WTP的方案。如果已经安装了EclipseV3.1,第一个选项就是独立地下载所有其他Eclipse项目并分别安装它们。另一种方案是使用UpdateManager中预配置的Eclipse.org更新站点。

第三种方案是all-in-one软件包,其中包括EclipseV3.1、WTPV0.7.1和所有其他依赖项。如果还没有安装EclipseV3.1的话,这是一个首选方案。

提示:如果需要将Eclipse的多个版本安装在同一台计算机上,那么将Eclipse解压在eclipse-3.1目录中是有帮助的。

要安装all-in-one软件包,请执行以下步骤:

下载wtp-all-in-one-0.7-win32.zip,如果还没有下载的话。

将wtp-all-in-one-0.7-win32.zip解压到所希望的目录。

通过在安装WTPall-in-one软件包的目录中双击eclipse.exe而启动Eclipse。

当提示工作空间时,保持默认选项,然后单击OK。

提示:对于LaszloIDE,只需要0.7版本的WTP。但是0.7.1版本在Web服务工具方面有了一些改进,并且在本教程的以后各节中将用到这些增强。

IDEforLaszlo

安装WTP之后,就来安装LaszloIDE插件。它们被打包成一个.zip软件包,可以使用EclipseUpdateManager来安装。

警告:要完成这些步骤,必须连接到Internet。

要安装LaszloIDE,请执行以下步骤:

下载laszloIDE.zip,如果还没有下载的话。

如果Eclipse当前还没在运行,则通过在安装WTPall-in-one软件包的目录中双击eclipse.exe而启动它。

选择Help>SoftwareUpdates>FindandInstall。

在FeatureUpdates页面上,选择Searchfornewfeaturestoinstall,然后单击Next。

在如图3所示的Updatesitestovisit页面上,单击NewArchivedSite。

图3.UpdateManager向导中的Updatesitestovisit页面



浏览并找到laszloIDE.zip文件,然后单击OK。

在EditLocalSite对话框中,通过单击OK确认.zip位置。

返回Updatesitestovisit页面,选中laszloIDE.zip,单击Finish。

在SearchResults页面上,选中laszloIDE.zip,然后单击Next。

在FeatureLicense页面上,阅读许可,并通过选中Iacceptthetermsinthelicenseagreement接受许可,然后单击Next。

在Installation页面上,单击Finished。

在FeatureVerification页面上,单击InstallAll。

当提示重新启动时,单击Yes。

在Eclipse重新启动后,WTP和LaszloIDE就已安装好了,您就可以开始开发Web服务和OpenLaszlo客户机了。

开发Web服务

在本节中,使用EclipseWebTools来为OpenLaszlo客户机将会调用的FluidMotion应用程序构建一个基本的Web服务。该Web服务将使用Hibernate来将数据持久存储到ApacheDerby数据库。首先创建一个动态Web项目。然后将服务创建为一个PlainOldJavaObject(POJO),再运行Web服务向导将它公开为一个SOAP服务。最后将它打包为一个Web应用程序。

注意:在开始开发Web服务之前,请确保任何LPS服务器都没在运行。否则,Tomcat服务器会出现WTP错误,因为它试图绑定到端口8080,而这是LPS服务器所使用的端口。要关闭LPS服务器,请激活命令窗口,并按Ctrl+C。

创建动态Web项目

Web服务最终将被打包为Web应用程序,并部署到Web容器。所以首先创建一个动态Web项目,该项目具有可部署的Web应用程序所必需的结构。换句话说,它将包含一个WEB-INF目录、WEB-INF/lib目录和一个web.xml文件。针对FluidMotion服务器将这个项目命名为fms。

要创建动态Web项目,请执行以下步骤:

从Eclipse主菜单选择File>New>Project。

在Selectawizard页面上,选择Web>DynamicWebProject,然后单击Next。

在DynamicWebProject页面上,输入项目名称,然后单击ShowAdvanced。

单击New以添加新的Tomcat服务器。

在NewServerRuntime页面上,选择Apache>ApacheTomcatv5.0,如图4所示,并单击Next。

图4.选择ApacheTomcatv5.0运行时



使用Browse找到Tomcat安装目录。

接下来,从JRE列表选择一个JDK,如图5所示,并单击Finish。注意,Eclipse默认情况下一般使用JavaRuntimeEnvironment(JRE),但是Tomcat必须配置为使用JDK,因为它需要编译工具,以将JavaServerPages™(JSPs)转换为servlet。所以这里确保配置并选择了JDK运行时。

图5.Tomcat服务器配置



回到DynamicWebProject页面,单击Finish。

如果提示一个许可协定,就阅读它,并通过单击IAgree接受它。

如果提示打开J2EE透视图,则单击Yes。

一旦完成DynamicWebProject向导,您就在DynamicWebProjects节点下具有了一个新的动态Web项目,类似于图6所示的项目。

图6.新的动态Web项目的内容



创建服务和数据转移对象

创建POJO服务和数据转移对象(DTO)与创建任何其他Java类是一样的,只是有两个细微差别。首先,Web服务包含被很好地公开为数组的集合。这使得描述服务的WebServicesDescriptionLanguage(WSDL)可以适当地处理复杂类型。另外,并不是所有支持Web服务的语言都具有动态未类型化集合的概念。其次,DTO必须具有无参构造函数,以便XML封送可以创建新的实例用于联合。

清单1是下一节中公开为Web服务的WorkOrderService类。

清单1.WorkOrderService类

package com.ibm.laszlo.services;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.ibm.laszlo.dto.Building;
import com.ibm.laszlo.dto.Floor;
import com.ibm.laszlo.dto.WorkOrder;
import com.ibm.laszlo.util.HibernateUtil;
/**
 * Service for work order management.
 */
public
 
class
 WorkOrderService {
 
/**
  * Finds a specific work order by id.
  * @param id unique id of work order.
  * @return work order.
  */
 
public
 WorkOrder findWorkOrderById(
int
 id) {
  Session session = HibernateUtil.currentSession();
  Transaction tx = session.beginTransaction();
  WorkOrder workOrder = (WorkOrder) session.
get
(
    WorkOrder.
class
, 
new
 Integer(id));
  tx.commit();
  HibernateUtil.closeSession();
  
return
 workOrder;
 }
 
/**
  * Returns all work orders.
  * @return all work orders.
  */
 
public
 WorkOrder[] findAllWorkOrders() {
  Session session = HibernateUtil.currentSession();
  Transaction tx = session.beginTransaction();
  List workOrders = session.createQuery(
"from WorkOrder"
).list();
  tx.commit();
  HibernateUtil.closeSession();
  
return
 (WorkOrder[])workOrders.toArray(
     
new
 WorkOrder[workOrders.size()]);
 }
 
/**
  * Create a new work order.
  * @param contact contact person's name.
  * @param phone contact person's phone number.
  * @param email contact person's email.
  * @param description description of problem.
  * @param building building problem is in.
  * @param floor floor in building with problem.
  * @param severity severity of the problem.
  * @return new work order's id.
  */
 
public
 
int
 createWorkOrder(String contact, String phone,
   String email, String description,
   String building, String floor, 
int
 severity) {
  Session session = HibernateUtil.currentSession();
  Transaction tx = session.beginTransaction();
  WorkOrder workOrder = 
new
 WorkOrder(contact, phone,
    email, building, floor, description, severity);
  Date currentDate = 
new
 Date();
  workOrder.setDateRequested(currentDate);
  workOrder.setLastModified(currentDate);
  workOrder.setStatus(WorkOrder.STATUS_REQUESTED);
  session.saveOrUpdate(workOrder);
  tx.commit();
  HibernateUtil.closeSession();
  
return
 workOrder.getId();
 }
 
/**
  * Collection of buildings and their floors.
  * NOTE: Hard coded for simplicity but could be read from a 
  * database.
  * @return 
  */
 
public
 Building[] getBuildings() {
  List buildings = 
new
 ArrayList();
  Building building = 
new
 Building(1, 
"HQ"
);
  building.addFloor(
new
 Floor(1, 
"Floor 1"
));
  building.addFloor(
new
 Floor(2, 
"Floor 2"
));
  building.addFloor(
new
 Floor(3, 
"Mezzanine"
));
  buildings.add(building);
  building = 
new
 Building(2, 
"Trump Tower"
);
  building.addFloor(
new
 Floor(1, 
"Trump 1"
));
  building.addFloor(
new

 Floor(2, 
"Trump 2"
));
  building.addFloor(
new
 Floor(3, 
"Trump 3"
));
  buildings.add(building);
  
return
 (Building[])buildings.toArray(
    
new
 Building[buildings.size()]);
 }
}
  

注意该类是如何具有五个方法的:findWorkOrderById()、findAllWorkOrders()、createWorkOrder()、updateWorkOrder()和getBuildings()。这五个方法将被公开为SOAP操作。还要注意,getBuildings()和findAllWorkOrders()方法返回类型化数组而不是java.util.List。该服务中引用的WorkOrder、Floor和Building类是带有无参构造函数的简单JavaBeans。

注意,如果您的服务或DTO类使用任何类型的第三方库,比如WorkOrderService类使用Hibernate,那么这些库的JAR需要包含在WebContent/WEB-INF/lib目录中。

将POJO服务公开为Web服务

既然有了一个POJO服务,就将它公开为Web服务。这叫做自底向上的方法,意味着从一个Java类开始,并使用它来生成描述该方法的WSDL。替代方案是自顶向下的方法,即从WSDL开始,并从它生成Java代码。

要将WorkOrderService公开为SOAPWeb服务,请执行以下步骤:

从Eclipse主菜单选择File>New>Other。

在Selectawizard页面上,选择WebServices>WebService,然后单击Next。

在如图7所示的WebServices页面上,选中Generateaproxy、TesttheWebservice和MonitortheWebservice,然后单击Next。

图7.生成Web服务的选项



在ObjectSelection页面上,选择您想要公开为Web服务的bean,比如WorkOrderService,然后单击Next。

在ServiceDeploymentConfiguration页面上,直接单击Next。这些配置就是针对将ApacheAxisJARs添加到哪个项目的。此外,它还会创建一个新项目,以允许您测试自己的Web服务,而不必具有Laszlo客户机。

如图8所示,WebServiceJavaBeanIdentity页面上的所有默认选项都应该保持,所以单击Finish。该页面允许您显式地选择哪些方法将由WSDL公开,以及使用的SOAP风格。

图8.针对公开方法和定义风格的配置



完成Web服务向导之后,就发生了几件事情。首先,用相同名称创建了一个新的动态Web项目,并且客户机被附加到它的末尾。该项目包含您的Web服务的一个消费者以及一个基于JSP的测试工具,如图9所示。这个测试客户机是很方便的,因为测试您的Web服务正确工作不需要完成OpenLaszlo客户机。

图9.Web服务测试客户机



其次,如果Tomcat服务器还没有启动,那么服务器启动并被添加到服务器视图(参见图10),用于管理应用程序的启动、停止和重新部署。

图10.Tomcat服务器在运行



第三,两个动态Web项目都被部署到Tomcat服务器,并且您可以开始通过基于Web的客户机来测试服务。一个内部Eclipse浏览器自动打开到测试页面。

最后,配置了一个TCP/IP监视器,如图11所示,以便您可以监视测试客户机与您的Web服务之间的SOAP流量。

图11.TCP/IP监视器监视客户机与Web服务之间的流量



打包Web服务

在使用测试客户机测试了Web服务之后,就可以将服务打包为标准的Web应用程序或.war文件了,以将它部署到Web容器上。对于开发OpenLaszlo客户机来说,尤其如此。前一节中由Eclipse自动启动的Tomcat服务器和您需要用于开发客户机的OpenLaszlo服务器都运行在端口8080上。您需要打包Web服务,以便它可以被部署到OpenLaszlo服务器。

要打包Web服务,请执行以下步骤:

从Eclipse主菜单选择File>Export。

选择WARfile,并单击Next。

在WARExport页面上,选择包含Web服务和生成的目的.war文件的Web模块,并单击Next。

警告:在启动OpenLaszlo服务器之前停止由Eclipse启动的Tomcat服务器。

要将Web服务部署到OpenLaszlo服务器,请执行以下步骤:

将.war文件fms.war复制到<OpenLaszloServer>/Server/tomcat-5.0.24/webapps目录。

启动OpenLaszlo服务器。

注意:将Web服务部署到OpenLaszlo服务器之后,到WSDL的URL是http://localhost:8080/fms/wsdl/WorkOrderService.wsdl。
开发富客户机

本节演示如何配置LaszloIDE工作空间、创建新的Laszlo项目以及启动Laszlo服务器。关于开发方面,它介绍了利用Laszlo组件、事件脚本编程、数据绑定、调试、在IDE中运行应用程序,以及打包。

配置LaszloIDE——特定于工作空间

配置LaszloIDE是特定于工作空间的。参见图12所示的EclipsePreferences窗口。可以通过从Eclipse主菜单选择Window>Preferences而到达配置面板。LaszloIDE必须被配置为从IDE运行Laszlo应用程序。主要的要求是指定LPSWebRoot、ContextRoot和应用服务器端口(ApacheTomcat)。LPSWebRoot是Laszlo服务器的安装实例所驻留的地方,并需要指向Context
Root。图12中定义的端口是ApacheTomcatservlet容器所监听的默认端口。默认的设计视图和首选设置是LocalDesignView。它使得编辑组件属性更加容易。可选地,LiveDesignView可以被启动为用于编辑的默认视图。一个浏览器选项可以用于从IDE启动应用程序。

图12.LaszloIDE配置面板



创建Laszlo项目

在可以开始开发Laszlo工件之前,需要创建一个项目用于容纳它们。要创建Laszlo项目,请执行以下步骤:

从Eclipse主菜单选择File>New>Project。就会出现新建项目向导,如图13所示。

图13.NewLaszloProject向导



选择向导类型LaszloProject,然后单击Next。

输入项目名称,并单击Next,如图14所示。

图14.命名新的LaszloProject向导



定义定制的LPS选项,如图15所示,并单击Finish。

图15.LaszloProjectLPS设置



一旦完成LaszloProject向导,您就会被提示切换到Laszlo透视图。然后就会创建一个类似于图16所示的新项目。

图16.新的Laszlo项目



注意,在图16中,新的Laszlo项目包含两个组件库。

创建了Laszlo项目之后,您就可以开始添加Laszlo或LZX文件了。要创建新的Laszlo文件,请执行以下步骤:

如果已经在Laszlo透视图中,则从Eclipse主菜单选择File>New>LaszloFile。

如图17所示,输入一个与您的项目相对的容器目录、一个文件名和一个文件类型(对于可视化页面就是Canvas,对于Laszlo类的集合就是Library)、组件和/或工具。

图17.新建Laszlo文件向导



一旦完成新建Laszlo文件向导,您的项目就将包含一个类似于下面的新文件:

<?xmlversion="1.0"encoding="UTF-8"?><canvas>

</canvas>


注意,这是一个.xml文件,其中包含两个canvas标记,它们是可视化组件的容器。在本教程的后面,您将使用这个新文件来创建主页。

启动Laszlo服务器

在可以使用RunasLaszloapplication功能部署和测试Laszlo应用程序之前,您的OpenLaszlo服务器必须在运行。

要在Windows中启动OpenLaszlo服务器,请从Windows任务栏选择Start>Programs>OpenLaszloServer>StartOpenLaszloServer。

执行Laszlo资源管理器的ApacheTomcat的一个捆绑的实例试图启动。也可以通过在运行LPS服务器时导航到http://localhost:8080/lps-3.0.2/laszlo-explorer/index.jsp而启动资源管理器。

要关闭服务器,可从Windows任务栏选择Start>Programs>OpenLaszloServer>StopOpenLaszloServer,或者在服务器控制台窗口为激活的情况下按Ctrl+C。

布局应用程序主页和导航

通过开发主页(索引)和导航,开始Laszlo应用程序。导航是到视图和创建工作的两个链接。导航使用了由XML数据集填充的<tree>组件。通过将代码包含在<library>标记中,菜单代码可作为包含文件可用。

清单2展示了menu.lzx文件的内容。

清单2.menu.lzx文件的内容

<library>
<!-- Menu data -->
<dataset name=
"fm"
>
 <nav nav=
"View Work"
    url=
"viewWork.lzx?lzt=html"
/>
 <nav nav=
"Create Work Order"
    url=
"createWork.lzx?lzt=html"
/>
</dataset>
<!-- START NAVIGATION -->
<view width=
"200"
 height=
"200"
 x=
"20"
 y=
"120"
>
 <tree datapath=
"fm:/"
 autoscroll=
"true"
 showroot=
"false"
>
  <tree datapath=
"*"
     text=
"$path{'@nav'}"
     open=
"true"
     isleaf=
"true"
     selectiontype=
"single"
>
   <method 
event
=
"onactivate"
>
    var url = 
this
.datapath.xpathQuery(
'@url'
);
    

if
 (url != 
null
) {
     LzBrowser.loadURL(url,
'_self'
);
    }
   </method>
  </tree>
 </tree>
</view>
<!-- END NAVIGATION -->
</library>
  

图18所示的索引页面是一个简单的页面,只包含菜单和一个logo。

图18.索引页面



索引的代码执行一个菜单包含,也包含一个空的<splash/>标记,以便在加载应用程序时向用户展示一个进度条。<splash>组件有两种形式,用于控制加载应用程序时的表示。一般的方式是,空标记或<splash/>默认触发一个进度条。另外,<splash/>标记也可以包含视图元素,用于用任何定制的图像、元素或者您希望的加载动画覆盖默认的进度条。

清单3展示了index.lzx文件的内容。

清单3.index.lzx文件的内容

<canvas> <view resource="/images/fm.gif"/> <menuseparator width="600" x="-1" y="97" height="6"/> <include href="lz/tree.lzx"/> <splash/> <include href="menu.lzx"/></canvas>


布局WorkOrder表单

即使您不了解Laszlo组件,这项工作也并不太难,并且也不妨碍您创建复杂的用户界面。图19所示的WorkOrder包含一个简单的表单。

图19.FluidMotionworkorder表单(Laszlo表单元素)



WorkOrder表单演示了使用一些不同的内置Laszlo组件。一个XML数据集驱动的组合框用于楼宇和楼层选择。包含楼宇和楼层数据的XML表示的位置数据集如清单4所示。

清单4.位置数据集

<dataset name=
"location"
>
 <locations>
  <building id=
"1"
 name=
"HQ"
>
   <floor id=
"1"
>Floor 1</floor>
   <floor id=
"2"
>Floor 2</floor>
   <floor id=
"3"
>Mezzanine</floor>
  </building>
  <building id=
"2"
 name=
"Trump Tower"
>
   <floor id=
"1"
>Trump 1</floor>
   <floor id=
"2"
>Trump 2</floor>
   <floor id=
"3"
>Trump 150</floor>
  </building>
 </locations>
</dataset>
  

清单5包含用于楼宇和楼层组合框的代码。

清单5.楼宇和楼层组合框

<text text=
"Building:"
   fontstyle=
"bold"
 width=
"59"
 height=
"17"
/>
<combobox defaulttext=
"choose one..."
 width=
"130"
     editable=
"false"
 height=
"22"
 id=
"bl"
>
 <textlistitem datapath=
"location:/locations[1]/building"
        text=
"$path{'@name'}"
 id=
"bl_id"
        value=
"$path{'@id'}"
        onselect=
"getFloors(this.getValue());"
/>
</combobox>
<text text=
"Floor:"
 fontstyle=
"bold"
 width=
"59"
   height=
"17"
/>
<combobox defaulttext=
"choose one..."
 width=
"130"
     editable=
"false"
 height=
"22"
 id=
"fl"
>
  <textlistitem id=
"fl_id"
 datapath=
""
     text=
"$path{'text()'}"
 value=
"$path{'@id'}"
/>
</combobox>
  

注意textlistitem上的datapath属性。它将下拉列表中的值绑定到前面描述的位置数据集。冒号前面的文本表示数据集名称。冒号后面的值是组件绑定到的XPath。文本和值分别使用XPath来选择将用作下拉列表中项目的文本和值的数据集属性。

在选择了楼宇之后,事件通过调用getFloors()方法并将它传递给当前楼宇ID,来填充楼层组合框。清单6展示了楼宇组合框的onselect事件所调用的getFloors()方法。

清单6.getFloors()方法

<script>
 <![CDATA[
 
// Highlight urgent requests
 function getFloors(bl) {
 fl=
'location:/locations[1]/building[@id=\''
+bl+
'\']/floor'
;
   
this
.fl_id.setAttribute(
'datapath'
, fl);
   
this
.fl_id.setAttribute(
'value'
,
''
);
  }
 ]>
</script>
  

联系人、e-mail、电话和描述(多行属性设置为true)是<edittext>组件。例如:

<edittextid="contact"x="348"width="130"height="17"/>

下面的严重性<slider>组件允许请求者给工作单分配一个严重性:

<slidermaxvalue=
"4"

minvalue=
"1"
text=
"Severity"
id=
"severity"
keystep=
"1"

bordersize=
"1"
yoffset=
"17"
/>
下面的Submit按钮是一个标准的<button>组件,并允许提交表单。目前,这个表单不会被提交。后面,该表单将被提交给Web服务。

<buttonisdefault="true"text="Submit"x="350"onclick=""/>

布局工作视图

图20所示的工作视图使用<grid>组件以及其他嵌入式组件,来查看当前的工作请求。

图20.FluidMotionviewwork页面(Laszlo网格组件)



该网格是用清单7中的静态数据集构建的,以建模它后面连接到的服务器端调用。

清单7.静态数据集

<dataset name=
"work"
>
 <work>
  <wo id=
"100301"
>
   <date_req>11/15/2005</date_req>
   <date_last_mod>11/18/2005</date_last_mod>
   <bl_name>HQ</bl_name>
   <fl_name>Floor 3</fl_name>
   <contact>Tim Dennison</contact>
   <email>tden@rockstar.rock</email>
   <phone>679.111.1123</phone>
   <description>
    Need emergency service on my equipment!
   </description>
   <comments>I'm on it!</comments>
   <severity>Low</severity>
   <status>Complete</status>
  </wo>
  <wo id=
"100302"
>
   <date_req>11/18/2005</date_req>
   <date_last_mod>11/19/2005</date_last_mod>
   <bl_name>Trump Tower</bl_name>
   <fl_name>Trump 2</fl_name>
   <contact>Donald Trump</contact>
   <email>dtrump@trump.usa</email>
   <phone>603.239.4326</phone>
   <description>
    Need recruiter machine repaired. 
   </description>
   <comments>This 
is
 on hold 
for
 now.</comments>
   <severity>Urgent</severity>
   <status>On Hold</status>
  </wo>
 </work>
</dataset>
这个Laszlo<grid>组件可以包含<gridcolumn>组件,如清单8所示。

清单8.Laszlo<grid>组件可以包含<gridcolumn>组件

<grid datapath=
"work:/work[1]"
 contentdatapath=
"wo"
shownitems=
"7"
 height=
"135"
 width=
"625"
 id=
"wo_grid"
x=
"180"
 y=
"115"
 multiselect=
"false"
>
<gridcolumn resizable=
"false"
>Requested
 <text datapath=
"date_req/text()"
 text=
"$path{'text()'}"
/>
</gridcolumn>
<gridcolumn resizable=
"true"
 width=
"90"
>Contact 
 <text datapath=
"contact/text()"
/>
</gridcolumn>
<gridcolumn resizable=
"false"
>Severity
 <text datapath=
"severity/text()"
/>
</gridcolumn>
<gridcolumn resizable=
"false"
 width=
"90"
>Status
 <combobox defaulttext=
"Requested"
 editable=
"false"
      id=
"status"
 datapath=
"status/text()"
>
  <textlistitem text=
"Assigned"
 id=
"assigned"
     value=
"assigned"
/>
  <textlistitem text=
"Active"
 id=
"active"
 value=
"active"
/>
  <textlistitem text=
"Complete"
 id=
"complete"
     value=
"complete"
/>
  <textlistitem text=
"On Hold"
 id=
"hold"
 value=
"hold"
/>
  <textlistitem text=
"Cancelled"
 id=
"cancel"
     value=
"cancel"
/>
 </combobox>
</gridcolumn>
<gridcolumn resizable=
"false"
 width=
"240"
>Comments
 <inputtext datapath=
"comments/text()"
 id=
"comments"
   text=
"comments/text()"
 multiline=
"true"
 height=
"35"
   selectiontype=
"multi"
/>
 </gridcolumn>
</grid>
  

运行应用程序并调试

LaszloIDE允许开发人员从IDE启动正在开发的当前文件。您可以利用如图21所示的RunAs命令,方法是简单地右击文档并选择RunAs>LaszloApplication。然后,IDE就启动了。

图21.LaszloIDE的RunAs特性



可以通过利用debug.write()方法而构造调试语句。调试语句如下所示:

debug.write("gettingfloorsfor"+bl);debug.write("settingfloordatapathto"+fl);


要查看调试窗口和结果,请将canvas标记上的debug属性设置为true,如图22所示。

<canvaswidth="100%"height="100%"debug="true">

图22.LaszloDebugger窗口



将Laszlo保存为.war文件(捆绑和部署)

LaszloIDE允许开发人员通过执行以下步骤而捆绑标准的J2EEWebarchive(WAR)文件:

从Eclipse主菜单选择File>Export。

选择LaszloWARFile,如图23所示,并单击Next。

图23.Laszlo.war文件导出工具



如图24所示,从Project组合框选择一个Laszlo项目,并从LPS根目录中的OpenLaszlo服务器的适当目录,选择一个具有.war扩展名的适当目的文件。

图24.LaszloWARExport工具



LaszloWARExport工具捆绑运行与LPS服务器无关的应用程序所需的所有必要的依赖项。换句话说,它使得应用程序可以虚拟地部署和运行在任何JavaWeb容器上。依赖项包括但不局限于所有的.jar文件、内置的Laszlo组件和LaszloDTD。它还包括所有基本Laszlo组件、CSS文件、Java类文件、Flash和HTML。这一特性使得将富客户机应用程序打包、部署和集成到J2EE架构中非常容易。

将Web服务和客户机绑定在一起

既然已经完成了Web服务,并布局了富客户机,就必须将它们绑定在一起。本节中有两个例子,展示如何从OpenLaszlo客户机调用Web服务。

简单的Web服务调用

在前一个例子中,楼宇和楼层组合框的内容是从静态位置数据集构建的。尽管这对于布局应用程序来说没有问题,但是它对于长期的维护来说不是一个好主意。您不想在每次添加一个新的楼宇时都必须更新代码。这可以形象化为一个从Web容器加载的.xml文件,但是这也似乎有太多的工作需要维护。相反,该列表和其他选择列表有可能来自Web服务和数据库。因此,Web服务具有一个getBuildings()操作。

清单9是一个调用getBuildings()操作的例子。

清单9.getBuildings()操作

<dataset name=
"location"
 />
<soap name=
"WorkOrderService"
  wsdl=
"http://localhost:8080/fms/wsdl/WorkOrderService.wsdl"
  autoload=
"true"
>
 <remotecall name=
"getBuildings"
       funcname=
"getBuildings"
 dataobject=
"location"
>
  <method 
event
=
"ondata"
 args=
"value"
>
   debug.write(location.serialize());
  </method>
 </remotecall>
 <method 
event
=
"onload"
>
  WorkOrderService.getBuildings.invoke();
 </method>
 <method 
event
=
"onerror"
 args=
"error"
>
  debug.write(
'error:'
, error);
 </method>
</soap>
  

XML已经从位置数据集删除掉了。这现在动态地由来自getBuildings()操作调用的XML所填充。

接下来,使用soap元素定义SOAP服务器。这里,您需要给它一个名称和一个到利用Web服务生成的WSDL的URL。对于本例来说,自动加载Web服务,因为您想要用户一查看页面就填充组合框。

在SOAP定义中,也需要在您将要使用remotecall元素调用的Web服务上声明远程操作。这里,您定义了getBuildings操作。name属性是在执行操作时JavaScript引用的本地名称,而funcname属性必须匹配WSDL中的名称,这与Web服务Java类一样。dataobject属性指出将用结果填充哪个数据集。指定前面使用过的位置数据集。

在remotecall中,您可以指定一个ondata事件。该事件在Web服务返回结果后将被调用。在本例中,您只是将结果写到调试器窗口。这也已经用于填充字段或其他东西。即使写到调试器的这一实现很简单,它仍然很有价值,因为它是一个强大的工具。有时,Web服务产生不像XML的XML,最初用于设计用户界面。也很难确定OpenLaszlo平台如何解释XML。这个例子展示了,您如何可以在数据集上调用serialize方法,以将XML分成良好的XML格式。清单10是来自
Web服务调用的例子,这不同于最初用于设计的XML。

清单10.在数据集上调用serialize方法以将XML分成良好的XML格式

<location>
 <getBuildingsReturn>
  <floors>
   <floors>
    <name>Floor 1</name>
    <id>1</id>
   </floors>
   <floors>
    <name>Floor 2</name>
    <id>2</id>
   </floors>
  </floors>
  <name>HQ</name>
  <id>1</id>
 </getBuildingsReturn>
 <getBuildingsReturn>
  <floors>
   <floors>
    <name>Trump 1</name>
    <id>1</id>
   </floors>
   <floors>
    <name>Trump 2</name>
    <id>2</id>
   </floors>
  </floors>
  <name>Trump Tower</name>
  <id>2</id>
 </getBuildingsReturn>
</location>
  

注意几件事情。首先,Web服务不使用任何属性。每个数据项都是一个元素。其次,location,即数据集的名称,是最外边的XML元素。第三,buildings被getBuildingsReturn所取代,后者是用附加到它的单词Return所调用的方法的名称。

还有两个其余事件应用于SOAP定义而非远程调用。它们是onload和onerror。onload只是一个调用方法的方便方式,以便在最初查看页面时填充复选框。当然,要让这件事在查看时立即发生,您还需要在soap元素上将autoload设置为true。在onload中,在WorkOrderService上显式地调用了getBuildings()操作。在onerror事件中,只将错误消息写到调试器窗口,以便可以看到错误。

参数化Web服务调用

第二个Web服务提交一个新的工作单。这里,调用createWorkOrder操作。清单11是包含在前一节的WorkOrderServicesoap定义中的定义。

清单11.包含在WorkOrderServicesoap定义中的定义

<remotecall name=
"createWorkOrder"
 funcname=
"createWorkOrder"
>
 <param value=
"${contact.text}"
 />
 <param value=
"${phone.text}"
 />
 <param value=
"${email.text}"
 />
 <param value=
"${description.text}"
 />
 <param value=
"${bl.text}"
 />
 <param value=
"${fl.text}"
 />
 <param value=
"${severity.value}"
 />
 <method 
event
=
"ondata"
 args=
"value"
>
  debug.write(
'New Work Order ID = '
 + value);
 </method>
</remotecall>
  

在本例中,您也在Web服务类中用等于WSDL和方法中的操作名的name和funcname声明了一个远程调用。因为该操作接受参数,所以您应该包含param元素。参数的顺序与Web服务类createWorkOrder()方法签名相同。这里,值引用edittext组件和其他组件中的文本。这个remotecall也有一个ondata事件,用于将新工作单ID的返回值绑定到调试窗口。

警告:OpenLaszlo要求Web服务至少返回一个值。它不能只是返回一个void,或者所调用的onerror事件。

要发起对createWorkOrder的调用,请添加一个onclick事件到按钮,并在createWorkOrder远程调用上调用invoke方法:

<buttonisdefault="true"text="Submit"x="350"onclick="WorkOrderService.createWorkOrder.invoke()"/>


部署到ApacheTomcat

在完成Web服务和OpenLaszlo客户机之后,就应该部署应用程序了。

因为Web服务(fms)和OpenLaszlo客户机(fm)的输出都是.war文件,所以您应该能够将它们部署在任何兼容的Web容器或J2EE应用服务器上。因为部署是特定于容器的,所以请参考您的容器文档,了解部署应用程序的指令。ApacheTomcat是一种流行的Web容器,所以本节介绍如何将应用程序部署到这一类型的容器。

要在Windows中部署到ApacheTomcat服务器,请执行以下步骤:

将导出的fm.war和fms.war文件复制到<jakarta-tomcat>/webapps目录。

通过执行<jakarta-tomcat>/bin/startup.bat脚本启动ApacheTomcat。

就是这些内容。要测试应用程序,请使用Web浏览器导航到http://localhost:8080/fm/index.lzx。
结束语

随着富Internet应用程序的流行,OpenLaszlo已经成为Ajax或MacromediaFlex强大的替代物。在本教程中,您看到了使用富组件库和少量XML创建有吸引力和响应快速的OpenLaszlo应用程序是多么容易。还看到了通过将它与公开为SOAPWeb服务的业务层集成,OpenLaszlo是多么适合J2EE应用程序架构。最后,您学习了如何将它打包和部署到ApacheTomcatWeb容器。整个教程中,了解到了如何使用许多EclipseLaszlo
IDE和EclipseWebTools来简化开发过程。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: