在Flex和LiveCycle中使用文档对象

来源:互联网 发布:淘宝怎么上传切片 编辑:程序博客网 时间:2024/06/02 18:43

本文来自RIAMeeting:http://riameeting.com/node/411

这是一篇来自Adobe开发者中心的文章,原文地址:

http://www.adobe.com/devnet/livecycle/articles/document_objects.html

Flex被用来来发诱人用户界面,而 Adobe LiveCycle ES则是用来自动化处理复杂的进程 结合这两种技术可以创建出功能强大并很有趣的应用程序。 让这两种产品一起工作并非难事,但这确实需要一些关于这两种技术工作方式的预备知识。

文本对象是LiveCycle ES产品的基本组成部分;它被用来承装PDF,XML以及二进制信息。 不幸的是,Flex这边并没有同样的对象。 Flex有一个FileReference对象,允许开发者指向二进制数据,但是它并不允许直接访问这些数据。 使用DocumentReference对象(该类包含在LiveCycle API中的adobe-remoting-provider.swc文件中)以及LiveCycle的远程上传 servlet(lcfileupload),开发者可以很容易的在两种有很大差别的开发环境中开发的程序之间传递文档数据。

在这篇文章中,我将涵盖使用Flex和LiveCycle ES创建一个简单的处理过程需要的各个步骤,包括,上传,处理,和返回一个文档对象。

要求

为了实现文章中提到的实例,你需要以下软件和文件:

Flex Builder 3

  • 试用
  • 购买

LiveCycle ES

  • 试用
  • 购买

示例文件:

  • document_objects_sample.zip(zip,459k)

预备知识

需要Flex,Flex Builder和LiveCycle ES的基本知识。

从Flex上传文件到 LiveCycle ES

由于一个处理过程往往是由用户请求发起的,所以我将会从编写Flex程序开始这个系统。 我将会编写一个简单的接口,让操作者可以使用它来上传文件到(任何文件)到LiveCycle进程。

这里是基本的步骤:

  1. 添加一个可以触发文件浏览弹出框的按钮。
  2. 使用FileReference对象来指向文件的位置。
  3. 使用LiveCycle的远程上传服务( LiveCycle ES的一个组成部分)来上传文件到服务端。
  4. 使用DocumentReference对象来将上传的文件的URL处理为一个LiveCycle进程。

使用Flex Builder或者FlexBuilder3的Eclipse插件创建一个新的Flex项目。添加一个按钮到项目界面,并为它注册一个点击事件,调用一个本地函数。

 

  1. <mx:Button id="selectBtn" label="Select
  2. Files" width="105" click="uploadFile()"/>

 

下面你将需要写一些脚本来时这些东西工作起来。 添加一个脚本标签到你的Flex程序,并实例化一个FileReference以及一个FileReferenceList对象。 当你做完了这些,你可以创建一个函数,为刚刚那个按钮所调用。

 

  1. <mx:Script>
  2. <![CDATA[
  3.  
  4. private var fileRef:FileReference = new FileReference();
  5. private var fileRefList:FileReferenceList = new FileReferenceList();
  6.  
  7. private function uploadFile():void {
  8. }
  9. ]]>
  10. </mx:Script>

 

我可以使用FileReferenceList的browse函数来打开一个文件浏览弹出式窗口。 同样,我也需要处理结果返回的事件,这个事件是在用户在浏览窗口中做了任何一种决定性的操作之后,由Flex派发的。

 

  1. private function uploadFile():void {
  2.  
  3. fileRefList.addEventListener(Event.SELECT, selectHandler);
  4. var docFilter:FileFilter = new FileFilter("PDF Documents","*.pdf");
  5. fileRefList.browse([docFilter]);
  6. }
  7.  
  8. private function selectHandler(event:Event):void {}

 

下一步是很好玩的一个部分。 我将FileReferenceList对象中被选定的每一个文件取出,上传到LiveCycle ES的服务中。 这个服务会返回一个已经被上传了的文件的URL,可以用来向LiveCycle ES进程发送请求。
我需要为程序添加一些新的全局变量:

 

  1. private var fileName:String;
  2. private var pendingFiles:Array;
  3. private var urlRequest:URLRequest = new URLRequest("http://myserver:8080/remoting/lcfileupload");
  4. private var uploadedDocURL:String;

 

然后添加实现文件上传的函数:

 

  1. private function selectHandler(event:Event):void {
  2. pendingFiles = new Array();
  3. for (var i:uint = 0; i < fileRefList.fileList.length; i++) {
  4. fileRef = FileReference(fileRefList.fileList[i]);
  5. addPendingFile(fileRef);
  6. }
  7. selectBtn.enabled = false;
  8. createBtn.enabled = true;
  9. }
  10.  
  11. private function addPendingFile(fileRef:FileReference):void {
  12. pendingFiles.push(fileRef);
  13. fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,completeHandler);
  14. fileRef.upload(urlRequest);
  15. }
  16.  
  17. private function completeHandler(event:DataEvent):void {
  18. //in this case I am only storing one value
  19. //if I wanted multiple files then I could use an array to
  20. //store the returned URLs. In this case only the LAST one will be kept.
  21. uploadedDocURL = event.data;
  22. }

 

使用远程调用对象来调用LiveCycle ES进程。

现在,我要调用LiveCycle ES并使用 DocumentReference对象处理返回的文档对象。 我需要创建一个远程调用对象关联到 LiveCycle ES的服务,便于我在稍后调用。 目标属性中的“ GenericProcess”是用来指定被调用的 LiveCycle ES服务的名字的。 在这个例子中,GenericProcess要做的仅仅是返回输入的文档对象。

 

  1. <mx:RemoteObject id="ro" destination="GenericProcess"
  2. result="resultHandler(event)" fault="faultHandler(event)"/>

 

由于远程调用对象需要与服务端做通信,我需要使用一个ChannelSet对象。 这同时也允许我设置LiveCycle ES需要的用户名和密码。 在这个例子中,我在程序初始化时设置了channel set的相关信息。 不要忘记将“myserver”替换成你自己的 LiveCycle ES服务的真实地址名。

 

  1. private function initApp():void{
  2. var cs:ChannelSet= new ChannelSet();
  3. cs.addChannel(new AMFChannel("my-amf", "http://myserver:8080/remoting/messagebroker/amf"));
  4. ro.setCredentials("administrator", "password");
  5. ro.channelSet = cs;
  6. }

 

为了处理传递到LiveCycle服务的文件,我创建了一个DocumentReference对象 然后将服务返回的URL植入到这个对象中。 InputDocument这个字符串是LiveCycle进程的输入参数的名字。 在这个例子中GenericProcess只能处理一个(且只有一个)文档对象。 如果你的进程具有更多的文档参数,或者要处理一组文件,那么在这里你需要指明这些变量。

 

  1. private function callLC():void{
  2. CursorManager.setBusyCursor();
  3. createBtn.enabled = false;
  4. var inDoc:DocumentReference = new DocumentReference();
  5. inDoc.url = uploadedDocURL;
  6. inDoc.referenceType = DocumentReference.REF_TYPE_URL;
  7.  
  8. var params:Object = new Object();
  9. params["InputDocument"] = inDoc;
  10.  
  11. ro.invoke(params);
  12.  
  13. }

 

处理返回值

这个LiveCycle ES进程同样会返回一个文档对象。 Flex程序需要能都对这个包含了结果文档地址的返回对象做点什么。 在这个例子中,我将返回的URL直接使用标签显示到界面上,用户可以点击它。

从返回的事件对象中,我使用 LiveCycle输出进程的变量名来获得文档对象。 例如,在本例中这个变量是pdfOutput:

 

  1. private function resultHandler(event:ResultEvent):void {
  2. var docRef:DocumentReference = event.result.pdfOutput; //last part of this must be the same as the LC output variable
  3. pdfUrl.htmlText = "<u><a href='" + docRef.url + "'target='_blank'>Generated PDF</a></u>";
  4. pdfUrl.selectable = true;
  5. CursorManager.removeBusyCursor();
  6. }

 

我们还可以知道些什么呢?

搞定了! 你现在已经可以使用Flex前端上传,处理,并接收到一个返回的文档对象了。

我建议你看一下下列文件:

  • LiveCycle ES Remoting(LiveCycle ES远程连接)
  • LiveCycle Quick Start―Invoking a Long Lived Process using Remoting(LiveCycle快速入门:使用远程连接请求一个长生命周期的进程)

关于作者

Michael Hodgson是一个Adobe企业技术团队中的eSystem专家。他已经在Adobe工作了5年,专注于用户概念证实的开发。 Mike工作和生活在加拿大渥太华。

RIAMeeting翻译小组 王贺 翻译

原创粉丝点击